alshabib

Merge branch 'master' of ssh://gerrit.onlab.us:29418/onos-next

Showing 61 changed files with 1417 additions and 258 deletions
...@@ -15,18 +15,29 @@ ...@@ -15,18 +15,29 @@
15 */ 15 */
16 package org.onlab.onos.calendar; 16 package org.onlab.onos.calendar;
17 17
18 -import org.onlab.onos.net.ConnectPoint; 18 +import java.net.URI;
19 -import org.onlab.onos.net.DeviceId;
20 -import org.onlab.onos.net.intent.IntentService;
21 -import org.onlab.rest.BaseResource;
22 19
23 import javax.ws.rs.POST; 20 import javax.ws.rs.POST;
24 import javax.ws.rs.Path; 21 import javax.ws.rs.Path;
25 import javax.ws.rs.PathParam; 22 import javax.ws.rs.PathParam;
26 import javax.ws.rs.core.Response; 23 import javax.ws.rs.core.Response;
27 -import java.net.URI; 24 +
25 +import org.onlab.onos.core.ApplicationId;
26 +import org.onlab.onos.core.CoreService;
27 +import org.onlab.onos.net.ConnectPoint;
28 +import org.onlab.onos.net.DeviceId;
29 +import org.onlab.onos.net.flow.DefaultTrafficSelector;
30 +import org.onlab.onos.net.flow.TrafficSelector;
31 +import org.onlab.onos.net.flow.TrafficTreatment;
32 +import org.onlab.onos.net.intent.Intent;
33 +import org.onlab.onos.net.intent.IntentService;
34 +import org.onlab.onos.net.intent.PointToPointIntentWithBandwidthConstraint;
35 +import org.onlab.onos.net.resource.BandwidthResourceRequest;
36 +import org.onlab.packet.Ethernet;
37 +import org.onlab.rest.BaseResource;
28 38
29 import static org.onlab.onos.net.PortNumber.portNumber; 39 import static org.onlab.onos.net.PortNumber.portNumber;
40 +import static org.onlab.onos.net.flow.DefaultTrafficTreatment.builder;
30 41
31 /** 42 /**
32 * Web resource for triggering calendared intents. 43 * Web resource for triggering calendared intents.
...@@ -47,12 +58,33 @@ public class BandwidthCalendarResource extends BaseResource { ...@@ -47,12 +58,33 @@ public class BandwidthCalendarResource extends BaseResource {
47 ConnectPoint srcPoint = new ConnectPoint(deviceId(src), portNumber(srcPort)); 58 ConnectPoint srcPoint = new ConnectPoint(deviceId(src), portNumber(srcPort));
48 ConnectPoint dstPoint = new ConnectPoint(deviceId(dst), portNumber(dstPort)); 59 ConnectPoint dstPoint = new ConnectPoint(deviceId(dst), portNumber(dstPort));
49 60
61 + TrafficSelector selector = buildTrafficSelector();
62 + TrafficTreatment treatment = builder().build();
63 +
64 + Intent intent = new PointToPointIntentWithBandwidthConstraint(
65 + appId(), selector, treatment,
66 + srcPoint, dstPoint, new BandwidthResourceRequest(Double.parseDouble(bandwidth)));
67 + service.submit(intent);
68 +
50 return Response.ok("Yo! We got src=" + srcPoint + "; dst=" + dstPoint + 69 return Response.ok("Yo! We got src=" + srcPoint + "; dst=" + dstPoint +
51 "; bw=" + bandwidth + "; intent service " + service).build(); 70 "; bw=" + bandwidth + "; intent service " + service).build();
52 } 71 }
53 72
73 + private TrafficSelector buildTrafficSelector() {
74 + TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
75 + Short ethType = Ethernet.TYPE_IPV4;
76 +
77 + selectorBuilder.matchEthType(ethType);
78 +
79 + return selectorBuilder.build();
80 + }
81 +
54 private DeviceId deviceId(String dpid) { 82 private DeviceId deviceId(String dpid) {
55 return DeviceId.deviceId(URI.create("of:" + dpid)); 83 return DeviceId.deviceId(URI.create("of:" + dpid));
56 } 84 }
57 85
86 + protected ApplicationId appId() {
87 + return get(CoreService.class).registerApplication("org.onlab.onos.calendar");
88 + }
89 +
58 } 90 }
......
...@@ -76,7 +76,7 @@ ...@@ -76,7 +76,7 @@
76 "nodeName1": "ROUTER1", 76 "nodeName1": "ROUTER1",
77 "nodeName2": "ROADM1", 77 "nodeName2": "ROADM1",
78 "bandWidth": 100000, 78 "bandWidth": 100000,
79 - "port1": 1, 79 + "port1": 2,
80 "port2": 10 80 "port2": 10
81 }, 81 },
82 "type": "pktOptLink" 82 "type": "pktOptLink"
...@@ -90,7 +90,7 @@ ...@@ -90,7 +90,7 @@
90 "nodeName1": "ROUTER2", 90 "nodeName1": "ROUTER2",
91 "nodeName2": "ROADM2", 91 "nodeName2": "ROADM2",
92 "bandWidth": 100000, 92 "bandWidth": 100000,
93 - "port1": 1, 93 + "port1": 2,
94 "port2": 11 94 "port2": 11
95 }, 95 },
96 "type": "pktOptLink" 96 "type": "pktOptLink"
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
19 +package org.onlab.onos.cli.net;
20 +
21 +import org.apache.karaf.shell.commands.Argument;
22 +import org.apache.karaf.shell.commands.Command;
23 +import org.onlab.onos.net.ConnectPoint;
24 +import org.onlab.onos.net.DeviceId;
25 +import org.onlab.onos.net.PortNumber;
26 +import org.onlab.onos.net.flow.TrafficSelector;
27 +import org.onlab.onos.net.flow.TrafficTreatment;
28 +import org.onlab.onos.net.intent.Intent;
29 +import org.onlab.onos.net.intent.IntentService;
30 +import org.onlab.onos.net.intent.PointToPointIntentWithBandwidthConstraint;
31 +import org.onlab.onos.net.resource.BandwidthResourceRequest;
32 +
33 +import static org.onlab.onos.net.DeviceId.deviceId;
34 +import static org.onlab.onos.net.PortNumber.portNumber;
35 +import static org.onlab.onos.net.flow.DefaultTrafficTreatment.builder;
36 +
37 +/**
38 + * Installs point-to-point connectivity intents.
39 + */
40 +@Command(scope = "onos", name = "add-point-intent-bw",
41 + description = "Installs point-to-point connectivity intent with bandwidth constraint")
42 +public class AddPointToPointIntentWithBandwidthConstraintCommand extends ConnectivityIntentCommand {
43 +
44 + @Argument(index = 0, name = "ingressDevice",
45 + description = "Ingress Device/Port Description",
46 + required = true, multiValued = false)
47 + String ingressDeviceString = null;
48 +
49 + @Argument(index = 1, name = "egressDevice",
50 + description = "Egress Device/Port Description",
51 + required = true, multiValued = false)
52 + String egressDeviceString = null;
53 +
54 + @Argument(index = 2, name = "bandwidth",
55 + description = "Bandwidth",
56 + required = true, multiValued = false)
57 + String bandwidthString = null;
58 +
59 + @Override
60 + protected void execute() {
61 + IntentService service = get(IntentService.class);
62 +
63 + DeviceId ingressDeviceId = deviceId(getDeviceId(ingressDeviceString));
64 + PortNumber ingressPortNumber = portNumber(getPortNumber(ingressDeviceString));
65 + ConnectPoint ingress = new ConnectPoint(ingressDeviceId, ingressPortNumber);
66 +
67 + DeviceId egressDeviceId = deviceId(getDeviceId(egressDeviceString));
68 + PortNumber egressPortNumber = portNumber(getPortNumber(egressDeviceString));
69 + ConnectPoint egress = new ConnectPoint(egressDeviceId, egressPortNumber);
70 +
71 + long bandwidth = Long.parseLong(bandwidthString);
72 +
73 + TrafficSelector selector = buildTrafficSelector();
74 + TrafficTreatment treatment = builder().build();
75 +
76 + Intent intent = new PointToPointIntentWithBandwidthConstraint(
77 + appId(), selector, treatment,
78 + ingress, egress, new BandwidthResourceRequest(bandwidth));
79 + service.submit(intent);
80 + }
81 +
82 + /**
83 + * Extracts the port number portion of the ConnectPoint.
84 + *
85 + * @param deviceString string representing the device/port
86 + * @return port number as a string, empty string if the port is not found
87 + */
88 + private String getPortNumber(String deviceString) {
89 + int slash = deviceString.indexOf('/');
90 + if (slash <= 0) {
91 + return "";
92 + }
93 + return deviceString.substring(slash + 1, deviceString.length());
94 + }
95 +
96 + /**
97 + * Extracts the device ID portion of the ConnectPoint.
98 + *
99 + * @param deviceString string representing the device/port
100 + * @return device ID string
101 + */
102 + private String getDeviceId(String deviceString) {
103 + int slash = deviceString.indexOf('/');
104 + if (slash <= 0) {
105 + return "";
106 + }
107 + return deviceString.substring(0, slash);
108 + }
109 +}
...@@ -47,8 +47,8 @@ public abstract class ConnectivityIntentCommand extends AbstractShellCommand { ...@@ -47,8 +47,8 @@ public abstract class ConnectivityIntentCommand extends AbstractShellCommand {
47 */ 47 */
48 protected TrafficSelector buildTrafficSelector() { 48 protected TrafficSelector buildTrafficSelector() {
49 TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder(); 49 TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
50 -
51 Short ethType = Ethernet.TYPE_IPV4; 50 Short ethType = Ethernet.TYPE_IPV4;
51 +
52 if (!Strings.isNullOrEmpty(ethTypeString)) { 52 if (!Strings.isNullOrEmpty(ethTypeString)) {
53 EthType ethTypeParameter = EthType.valueOf(ethTypeString); 53 EthType ethTypeParameter = EthType.valueOf(ethTypeString);
54 ethType = ethTypeParameter.value(); 54 ethType = ethTypeParameter.value();
......
...@@ -40,7 +40,7 @@ import static org.onlab.onos.net.DeviceId.deviceId; ...@@ -40,7 +40,7 @@ import static org.onlab.onos.net.DeviceId.deviceId;
40 description = "Lists all ports or all ports of a device") 40 description = "Lists all ports or all ports of a device")
41 public class DevicePortsListCommand extends DevicesListCommand { 41 public class DevicePortsListCommand extends DevicesListCommand {
42 42
43 - private static final String FMT = " port=%s, state=%s%s"; 43 + private static final String FMT = " port=%s, state=%s, type=%s, speed=%s%s";
44 44
45 @Option(name = "-e", aliases = "--enabled", description = "Show only enabled ports", 45 @Option(name = "-e", aliases = "--enabled", description = "Show only enabled ports",
46 required = false, multiValued = false) 46 required = false, multiValued = false)
...@@ -110,10 +110,14 @@ public class DevicePortsListCommand extends DevicesListCommand { ...@@ -110,10 +110,14 @@ public class DevicePortsListCommand extends DevicesListCommand {
110 ports.add(mapper.createObjectNode() 110 ports.add(mapper.createObjectNode()
111 .put("port", port.number().toString()) 111 .put("port", port.number().toString())
112 .put("isEnabled", port.isEnabled()) 112 .put("isEnabled", port.isEnabled())
113 + .put("type", port.type().toString().toLowerCase())
114 + .put("portSpeed", port.portSpeed())
113 .set("annotations", annotations(mapper, port.annotations()))); 115 .set("annotations", annotations(mapper, port.annotations())));
114 } 116 }
115 } 117 }
116 - return result.put("device", device.id().toString()).set("ports", ports); 118 + result.set("device", json(service, mapper, device));
119 + result.set("ports", ports);
120 + return result;
117 } 121 }
118 122
119 // Determines if a port should be included in output. 123 // Determines if a port should be included in output.
...@@ -130,6 +134,7 @@ public class DevicePortsListCommand extends DevicesListCommand { ...@@ -130,6 +134,7 @@ public class DevicePortsListCommand extends DevicesListCommand {
130 for (Port port : ports) { 134 for (Port port : ports) {
131 if (isIncluded(port)) { 135 if (isIncluded(port)) {
132 print(FMT, port.number(), port.isEnabled() ? "enabled" : "disabled", 136 print(FMT, port.number(), port.isEnabled() ? "enabled" : "disabled",
137 + port.type().toString().toLowerCase(), port.portSpeed(),
133 annotations(port.annotations())); 138 annotations(port.annotations()));
134 } 139 }
135 } 140 }
......
...@@ -116,6 +116,17 @@ ...@@ -116,6 +116,17 @@
116 </optional-completers> 116 </optional-completers>
117 </command> 117 </command>
118 <command> 118 <command>
119 + <action class="org.onlab.onos.cli.net.AddPointToPointIntentWithBandwidthConstraintCommand"/>
120 + <completers>
121 + <ref component-id="connectPointCompleter"/>
122 + <ref component-id="connectPointCompleter"/>
123 + <null/>
124 + </completers>
125 + <optional-completers>
126 + <entry key="-t" value-ref="ethTypeCompleter"/>
127 + </optional-completers>
128 + </command>
129 + <command>
119 <action class="org.onlab.onos.cli.net.AddOpticalIntentCommand"/> 130 <action class="org.onlab.onos.cli.net.AddOpticalIntentCommand"/>
120 <completers> 131 <completers>
121 <ref component-id="connectPointCompleter"/> 132 <ref component-id="connectPointCompleter"/>
......
...@@ -35,6 +35,11 @@ public class RoleInfo { ...@@ -35,6 +35,11 @@ public class RoleInfo {
35 this.backups = ImmutableList.copyOf(backups); 35 this.backups = ImmutableList.copyOf(backups);
36 } 36 }
37 37
38 + public RoleInfo() {
39 + this.master = null;
40 + this.backups = ImmutableList.of();
41 + }
42 +
38 public NodeId master() { 43 public NodeId master() {
39 return master; 44 return master;
40 } 45 }
...@@ -63,7 +68,7 @@ public class RoleInfo { ...@@ -63,7 +68,7 @@ public class RoleInfo {
63 68
64 @Override 69 @Override
65 public int hashCode() { 70 public int hashCode() {
66 - return Objects.hash(master, backups.hashCode()); 71 + return Objects.hash(master, backups);
67 } 72 }
68 73
69 @Override 74 @Override
......
...@@ -24,9 +24,27 @@ import static com.google.common.base.MoreObjects.toStringHelper; ...@@ -24,9 +24,27 @@ import static com.google.common.base.MoreObjects.toStringHelper;
24 */ 24 */
25 public class DefaultPort extends AbstractAnnotated implements Port { 25 public class DefaultPort extends AbstractAnnotated implements Port {
26 26
27 + /** Default port speed in Mbps. */
28 + public static final long DEFAULT_SPEED = 1_000;
29 +
27 private final Element element; 30 private final Element element;
28 private final PortNumber number; 31 private final PortNumber number;
29 private final boolean isEnabled; 32 private final boolean isEnabled;
33 + private final Type type;
34 + private final long portSpeed;
35 +
36 + /**
37 + * Creates a network element attributed to the specified provider.
38 + *
39 + * @param element parent network element
40 + * @param number port number
41 + * @param isEnabled indicator whether the port is up and active
42 + * @param annotations optional key/value annotations
43 + */
44 + public DefaultPort(Element element, PortNumber number, boolean isEnabled,
45 + Annotations... annotations) {
46 + this(element, number, isEnabled, Type.COPPER, DEFAULT_SPEED, annotations);
47 + }
30 48
31 /** 49 /**
32 * Creates a network element attributed to the specified provider. 50 * Creates a network element attributed to the specified provider.
...@@ -34,19 +52,49 @@ public class DefaultPort extends AbstractAnnotated implements Port { ...@@ -34,19 +52,49 @@ public class DefaultPort extends AbstractAnnotated implements Port {
34 * @param element parent network element 52 * @param element parent network element
35 * @param number port number 53 * @param number port number
36 * @param isEnabled indicator whether the port is up and active 54 * @param isEnabled indicator whether the port is up and active
55 + * @param type port type
56 + * @param portSpeed port speed in Mbs
37 * @param annotations optional key/value annotations 57 * @param annotations optional key/value annotations
38 */ 58 */
39 - public DefaultPort(Element element, PortNumber number, 59 + public DefaultPort(Element element, PortNumber number, boolean isEnabled,
40 - boolean isEnabled, Annotations... annotations) { 60 + Type type, long portSpeed, Annotations... annotations) {
41 super(annotations); 61 super(annotations);
42 this.element = element; 62 this.element = element;
43 this.number = number; 63 this.number = number;
44 this.isEnabled = isEnabled; 64 this.isEnabled = isEnabled;
65 + this.type = type;
66 + this.portSpeed = portSpeed;
67 +
68 + }
69 +
70 + @Override
71 + public Element element() {
72 + return element;
73 + }
74 +
75 + @Override
76 + public PortNumber number() {
77 + return number;
78 + }
79 +
80 + @Override
81 + public boolean isEnabled() {
82 + return isEnabled;
83 + }
84 +
85 + @Override
86 + public Type type() {
87 + return type;
88 + }
89 +
90 + @Override
91 + public long portSpeed() {
92 + return portSpeed;
45 } 93 }
46 94
47 @Override 95 @Override
48 public int hashCode() { 96 public int hashCode() {
49 - return Objects.hash(number, isEnabled); 97 + return Objects.hash(number, isEnabled, type, portSpeed);
50 } 98 }
51 99
52 @Override 100 @Override
...@@ -58,7 +106,9 @@ public class DefaultPort extends AbstractAnnotated implements Port { ...@@ -58,7 +106,9 @@ public class DefaultPort extends AbstractAnnotated implements Port {
58 final DefaultPort other = (DefaultPort) obj; 106 final DefaultPort other = (DefaultPort) obj;
59 return Objects.equals(this.element.id(), other.element.id()) && 107 return Objects.equals(this.element.id(), other.element.id()) &&
60 Objects.equals(this.number, other.number) && 108 Objects.equals(this.number, other.number) &&
61 - Objects.equals(this.isEnabled, other.isEnabled); 109 + Objects.equals(this.isEnabled, other.isEnabled) &&
110 + Objects.equals(this.type, other.type) &&
111 + Objects.equals(this.portSpeed, other.portSpeed);
62 } 112 }
63 return false; 113 return false;
64 } 114 }
...@@ -69,22 +119,9 @@ public class DefaultPort extends AbstractAnnotated implements Port { ...@@ -69,22 +119,9 @@ public class DefaultPort extends AbstractAnnotated implements Port {
69 .add("element", element.id()) 119 .add("element", element.id())
70 .add("number", number) 120 .add("number", number)
71 .add("isEnabled", isEnabled) 121 .add("isEnabled", isEnabled)
122 + .add("type", type)
123 + .add("portSpeed", portSpeed)
72 .toString(); 124 .toString();
73 } 125 }
74 126
75 - @Override
76 - public PortNumber number() {
77 - return number;
78 - }
79 -
80 - @Override
81 - public boolean isEnabled() {
82 - return isEnabled;
83 - }
84 -
85 - @Override
86 - public Element element() {
87 - return element;
88 - }
89 -
90 } 127 }
......
...@@ -21,6 +21,26 @@ package org.onlab.onos.net; ...@@ -21,6 +21,26 @@ package org.onlab.onos.net;
21 */ 21 */
22 public interface Port extends Annotated { 22 public interface Port extends Annotated {
23 23
24 + /** Represents coarse port type classification. */
25 + public enum Type {
26 + /**
27 + * Signifies copper-based connectivity.
28 + */
29 + COPPER,
30 +
31 + /**
32 + * Signifies optical fiber-based connectivity.
33 + */
34 + FIBER
35 + }
36 +
37 + /**
38 + * Returns the parent network element to which this port belongs.
39 + *
40 + * @return parent network element
41 + */
42 + Element element();
43 +
24 /** 44 /**
25 * Returns the port number. 45 * Returns the port number.
26 * 46 *
...@@ -36,12 +56,18 @@ public interface Port extends Annotated { ...@@ -36,12 +56,18 @@ public interface Port extends Annotated {
36 boolean isEnabled(); 56 boolean isEnabled();
37 57
38 /** 58 /**
39 - * Returns the parent network element to which this port belongs. 59 + * Returns the port type.
40 * 60 *
41 - * @return parent network element 61 + * @return port type
42 */ 62 */
43 - Element element(); 63 + Type type();
44 64
45 - // set of port attributes 65 + /**
66 + * Returns the current port speed in Mbps.
67 + *
68 + * @return current port speed
69 + */
70 + long portSpeed();
46 71
72 + // TODO: more attributes?
47 } 73 }
......
...@@ -15,11 +15,12 @@ ...@@ -15,11 +15,12 @@
15 */ 15 */
16 package org.onlab.onos.net.device; 16 package org.onlab.onos.net.device;
17 17
18 +import com.google.common.base.MoreObjects;
18 import org.onlab.onos.net.AbstractDescription; 19 import org.onlab.onos.net.AbstractDescription;
19 import org.onlab.onos.net.PortNumber; 20 import org.onlab.onos.net.PortNumber;
20 import org.onlab.onos.net.SparseAnnotations; 21 import org.onlab.onos.net.SparseAnnotations;
21 22
22 -import com.google.common.base.MoreObjects; 23 +import static org.onlab.onos.net.Port.Type;
23 24
24 /** 25 /**
25 * Default implementation of immutable port description. 26 * Default implementation of immutable port description.
...@@ -27,8 +28,12 @@ import com.google.common.base.MoreObjects; ...@@ -27,8 +28,12 @@ import com.google.common.base.MoreObjects;
27 public class DefaultPortDescription extends AbstractDescription 28 public class DefaultPortDescription extends AbstractDescription
28 implements PortDescription { 29 implements PortDescription {
29 30
31 + private static final long DEFAULT_SPEED = 1_000;
32 +
30 private final PortNumber number; 33 private final PortNumber number;
31 private final boolean isEnabled; 34 private final boolean isEnabled;
35 + private final Type type;
36 + private final long portSpeed;
32 37
33 /** 38 /**
34 * Creates a port description using the supplied information. 39 * Creates a port description using the supplied information.
...@@ -39,9 +44,34 @@ public class DefaultPortDescription extends AbstractDescription ...@@ -39,9 +44,34 @@ public class DefaultPortDescription extends AbstractDescription
39 */ 44 */
40 public DefaultPortDescription(PortNumber number, boolean isEnabled, 45 public DefaultPortDescription(PortNumber number, boolean isEnabled,
41 SparseAnnotations... annotations) { 46 SparseAnnotations... annotations) {
47 + this(number, isEnabled, Type.COPPER, DEFAULT_SPEED, annotations);
48 + }
49 +
50 + /**
51 + * Creates a port description using the supplied information.
52 + *
53 + * @param number port number
54 + * @param isEnabled port enabled state
55 + * @param type port type
56 + * @param portSpeed port speed in Mbps
57 + * @param annotations optional key/value annotations map
58 + */
59 + public DefaultPortDescription(PortNumber number, boolean isEnabled,
60 + Type type, long portSpeed,
61 + SparseAnnotations...annotations) {
42 super(annotations); 62 super(annotations);
43 this.number = number; 63 this.number = number;
44 this.isEnabled = isEnabled; 64 this.isEnabled = isEnabled;
65 + this.type = type;
66 + this.portSpeed = portSpeed;
67 + }
68 +
69 + // Default constructor for serialization
70 + private DefaultPortDescription() {
71 + this.number = null;
72 + this.isEnabled = false;
73 + this.portSpeed = DEFAULT_SPEED;
74 + this.type = Type.COPPER;
45 } 75 }
46 76
47 /** 77 /**
...@@ -52,7 +82,8 @@ public class DefaultPortDescription extends AbstractDescription ...@@ -52,7 +82,8 @@ public class DefaultPortDescription extends AbstractDescription
52 */ 82 */
53 public DefaultPortDescription(PortDescription base, 83 public DefaultPortDescription(PortDescription base,
54 SparseAnnotations annotations) { 84 SparseAnnotations annotations) {
55 - this(base.portNumber(), base.isEnabled(), annotations); 85 + this(base.portNumber(), base.isEnabled(), base.type(), base.portSpeed(),
86 + annotations);
56 } 87 }
57 88
58 @Override 89 @Override
...@@ -66,17 +97,24 @@ public class DefaultPortDescription extends AbstractDescription ...@@ -66,17 +97,24 @@ public class DefaultPortDescription extends AbstractDescription
66 } 97 }
67 98
68 @Override 99 @Override
100 + public Type type() {
101 + return type;
102 + }
103 +
104 + @Override
105 + public long portSpeed() {
106 + return portSpeed;
107 + }
108 +
109 + @Override
69 public String toString() { 110 public String toString() {
70 return MoreObjects.toStringHelper(getClass()) 111 return MoreObjects.toStringHelper(getClass())
71 .add("number", number) 112 .add("number", number)
72 .add("isEnabled", isEnabled) 113 .add("isEnabled", isEnabled)
114 + .add("type", type)
115 + .add("portSpeed", portSpeed)
73 .add("annotations", annotations()) 116 .add("annotations", annotations())
74 .toString(); 117 .toString();
75 } 118 }
76 119
77 - // default constructor for serialization
78 - private DefaultPortDescription() {
79 - this.number = null;
80 - this.isEnabled = false;
81 - }
82 } 120 }
......
...@@ -18,13 +18,13 @@ package org.onlab.onos.net.device; ...@@ -18,13 +18,13 @@ package org.onlab.onos.net.device;
18 import org.onlab.onos.net.Description; 18 import org.onlab.onos.net.Description;
19 import org.onlab.onos.net.PortNumber; 19 import org.onlab.onos.net.PortNumber;
20 20
21 +import static org.onlab.onos.net.Port.Type;
22 +
21 /** 23 /**
22 * Information about a port. 24 * Information about a port.
23 */ 25 */
24 public interface PortDescription extends Description { 26 public interface PortDescription extends Description {
25 27
26 - // TODO: possibly relocate this to a common ground so that this can also used by host tracking if required
27 -
28 /** 28 /**
29 * Returns the port number. 29 * Returns the port number.
30 * 30 *
...@@ -39,4 +39,18 @@ public interface PortDescription extends Description { ...@@ -39,4 +39,18 @@ public interface PortDescription extends Description {
39 */ 39 */
40 boolean isEnabled(); 40 boolean isEnabled();
41 41
42 + /**
43 + * Returns the port type.
44 + *
45 + * @return port type
46 + */
47 + Type type();
48 +
49 + /**
50 + * Returns the current port speed in Mbps.
51 + *
52 + * @return current port speed
53 + */
54 + long portSpeed();
55 +
42 } 56 }
......
...@@ -20,6 +20,7 @@ import org.onlab.onos.core.ApplicationId; ...@@ -20,6 +20,7 @@ import org.onlab.onos.core.ApplicationId;
20 import org.onlab.onos.net.Path; 20 import org.onlab.onos.net.Path;
21 import org.onlab.onos.net.flow.TrafficSelector; 21 import org.onlab.onos.net.flow.TrafficSelector;
22 import org.onlab.onos.net.flow.TrafficTreatment; 22 import org.onlab.onos.net.flow.TrafficTreatment;
23 +import org.onlab.onos.net.resource.LinkResourceRequest;
23 24
24 /** 25 /**
25 * Abstraction of explicitly path specified connectivity intent. 26 * Abstraction of explicitly path specified connectivity intent.
...@@ -27,6 +28,7 @@ import org.onlab.onos.net.flow.TrafficTreatment; ...@@ -27,6 +28,7 @@ import org.onlab.onos.net.flow.TrafficTreatment;
27 public class PathIntent extends ConnectivityIntent { 28 public class PathIntent extends ConnectivityIntent {
28 29
29 private final Path path; 30 private final Path path;
31 + private final LinkResourceRequest[] resourceRequests;
30 32
31 /** 33 /**
32 * Creates a new point-to-point intent with the supplied ingress/egress 34 * Creates a new point-to-point intent with the supplied ingress/egress
...@@ -39,10 +41,11 @@ public class PathIntent extends ConnectivityIntent { ...@@ -39,10 +41,11 @@ public class PathIntent extends ConnectivityIntent {
39 * @throws NullPointerException {@code path} is null 41 * @throws NullPointerException {@code path} is null
40 */ 42 */
41 public PathIntent(ApplicationId appId, TrafficSelector selector, 43 public PathIntent(ApplicationId appId, TrafficSelector selector,
42 - TrafficTreatment treatment, Path path) { 44 + TrafficTreatment treatment, Path path, LinkResourceRequest[] resourceRequests) {
43 super(id(PathIntent.class, selector, treatment, path), appId, 45 super(id(PathIntent.class, selector, treatment, path), appId,
44 resources(path.links()), selector, treatment); 46 resources(path.links()), selector, treatment);
45 this.path = path; 47 this.path = path;
48 + this.resourceRequests = resourceRequests;
46 } 49 }
47 50
48 /** 51 /**
...@@ -51,6 +54,7 @@ public class PathIntent extends ConnectivityIntent { ...@@ -51,6 +54,7 @@ public class PathIntent extends ConnectivityIntent {
51 protected PathIntent() { 54 protected PathIntent() {
52 super(); 55 super();
53 this.path = null; 56 this.path = null;
57 + this.resourceRequests = new LinkResourceRequest[0];
54 } 58 }
55 59
56 /** 60 /**
...@@ -67,6 +71,10 @@ public class PathIntent extends ConnectivityIntent { ...@@ -67,6 +71,10 @@ public class PathIntent extends ConnectivityIntent {
67 return true; 71 return true;
68 } 72 }
69 73
74 + public LinkResourceRequest[] resourceRequests() {
75 + return resourceRequests;
76 + }
77 +
70 @Override 78 @Override
71 public String toString() { 79 public String toString() {
72 return MoreObjects.toStringHelper(getClass()) 80 return MoreObjects.toStringHelper(getClass())
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
19 +package org.onlab.onos.net.intent;
20 +
21 +import org.onlab.onos.core.ApplicationId;
22 +import org.onlab.onos.net.ConnectPoint;
23 +import org.onlab.onos.net.flow.TrafficSelector;
24 +import org.onlab.onos.net.flow.TrafficTreatment;
25 +import org.onlab.onos.net.resource.BandwidthResourceRequest;
26 +
27 +import com.google.common.base.MoreObjects;
28 +
29 +import static com.google.common.base.Preconditions.checkNotNull;
30 +
31 +/**
32 + * Abstraction of point-to-point connectivity.
33 + */
34 +public class PointToPointIntentWithBandwidthConstraint extends ConnectivityIntent {
35 +
36 + private final ConnectPoint ingressPoint;
37 + private final ConnectPoint egressPoint;
38 + private final BandwidthResourceRequest bandwidthResourceRequest;
39 +
40 + /**
41 + * Creates a new point-to-point intent with the supplied ingress/egress
42 + * ports.
43 + *
44 + * @param appId application identifier
45 + * @param selector traffic selector
46 + * @param treatment treatment
47 + * @param ingressPoint ingress port
48 + * @param egressPoint egress port
49 + * @throws NullPointerException if {@code ingressPoint} or {@code egressPoints} is null.
50 + */
51 + public PointToPointIntentWithBandwidthConstraint(ApplicationId appId, TrafficSelector selector,
52 + TrafficTreatment treatment,
53 + ConnectPoint ingressPoint,
54 + ConnectPoint egressPoint,
55 + BandwidthResourceRequest bandwidthResourceRequest) {
56 + super(id(PointToPointIntentWithBandwidthConstraint.class, selector,
57 + treatment, ingressPoint, egressPoint, bandwidthResourceRequest.bandwidth()),
58 + appId, null, selector, treatment);
59 + this.ingressPoint = checkNotNull(ingressPoint);
60 + this.egressPoint = checkNotNull(egressPoint);
61 + this.bandwidthResourceRequest = bandwidthResourceRequest;
62 + }
63 +
64 + /**
65 + * Constructor for serializer.
66 + */
67 + protected PointToPointIntentWithBandwidthConstraint() {
68 + super();
69 + this.ingressPoint = null;
70 + this.egressPoint = null;
71 + bandwidthResourceRequest = new BandwidthResourceRequest(0.0);
72 + }
73 +
74 + /**
75 + * Returns the port on which the ingress traffic should be connected to
76 + * the egress.
77 + *
78 + * @return ingress port
79 + */
80 + public ConnectPoint ingressPoint() {
81 + return ingressPoint;
82 + }
83 +
84 + /**
85 + * Returns the port on which the traffic should egress.
86 + *
87 + * @return egress port
88 + */
89 + public ConnectPoint egressPoint() {
90 + return egressPoint;
91 + }
92 +
93 + public BandwidthResourceRequest bandwidthRequest() {
94 + return this.bandwidthResourceRequest;
95 + }
96 +
97 + @Override
98 + public String toString() {
99 + return MoreObjects.toStringHelper(getClass())
100 + .add("id", id())
101 + .add("appId", appId())
102 + .add("selector", selector())
103 + .add("treatment", treatment())
104 + .add("ingress", ingressPoint)
105 + .add("egress", egressPoint)
106 + .add("bandwidth", bandwidthResourceRequest.bandwidth().toString())
107 + .toString();
108 + }
109 +
110 +}
1 +/*
2 + * Copyright 2014 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onlab.onos.net.resource;
17 +
18 +import java.util.Set;
19 +
20 +import org.onlab.onos.net.Link;
21 +import org.onlab.onos.net.intent.IntentId;
22 +
23 +
24 +/**
25 + * Manages link resources.
26 + */
27 +public interface LinkResourceStore {
28 + Set<ResourceAllocation> getFreeResources(Link link);
29 +
30 + void allocateResources(LinkResourceAllocations allocations);
31 +
32 + void releaseResources(LinkResourceAllocations allocations);
33 +
34 + LinkResourceAllocations getAllocations(IntentId intentId);
35 +
36 + Iterable<LinkResourceAllocations> getAllocations(Link link);
37 +
38 + Iterable<LinkResourceAllocations> getAllocations();
39 +}
...@@ -23,6 +23,8 @@ import org.onlab.packet.ChassisId; ...@@ -23,6 +23,8 @@ import org.onlab.packet.ChassisId;
23 import static org.junit.Assert.assertEquals; 23 import static org.junit.Assert.assertEquals;
24 import static org.onlab.onos.net.Device.Type.SWITCH; 24 import static org.onlab.onos.net.Device.Type.SWITCH;
25 import static org.onlab.onos.net.DeviceId.deviceId; 25 import static org.onlab.onos.net.DeviceId.deviceId;
26 +import static org.onlab.onos.net.Port.Type.COPPER;
27 +import static org.onlab.onos.net.Port.Type.FIBER;
26 import static org.onlab.onos.net.PortNumber.portNumber; 28 import static org.onlab.onos.net.PortNumber.portNumber;
27 29
28 /** 30 /**
...@@ -35,15 +37,16 @@ public class DefaultPortTest { ...@@ -35,15 +37,16 @@ public class DefaultPortTest {
35 private static final DeviceId DID2 = deviceId("of:bar"); 37 private static final DeviceId DID2 = deviceId("of:bar");
36 private static final PortNumber P1 = portNumber(1); 38 private static final PortNumber P1 = portNumber(1);
37 private static final PortNumber P2 = portNumber(2); 39 private static final PortNumber P2 = portNumber(2);
40 + private static final long SP1 = 1_000_000;
38 41
39 @Test 42 @Test
40 public void testEquality() { 43 public void testEquality() {
41 Device device = new DefaultDevice(PID, DID1, SWITCH, "m", "h", "s", "n", 44 Device device = new DefaultDevice(PID, DID1, SWITCH, "m", "h", "s", "n",
42 new ChassisId()); 45 new ChassisId());
43 - Port p1 = new DefaultPort(device, portNumber(1), true); 46 + Port p1 = new DefaultPort(device, portNumber(1), true, COPPER, SP1);
44 - Port p2 = new DefaultPort(device, portNumber(1), true); 47 + Port p2 = new DefaultPort(device, portNumber(1), true, COPPER, SP1);
45 - Port p3 = new DefaultPort(device, portNumber(2), true); 48 + Port p3 = new DefaultPort(device, portNumber(2), true, FIBER, SP1);
46 - Port p4 = new DefaultPort(device, portNumber(2), true); 49 + Port p4 = new DefaultPort(device, portNumber(2), true, FIBER, SP1);
47 Port p5 = new DefaultPort(device, portNumber(1), false); 50 Port p5 = new DefaultPort(device, portNumber(1), false);
48 51
49 new EqualsTester().addEqualityGroup(p1, p2) 52 new EqualsTester().addEqualityGroup(p1, p2)
...@@ -56,10 +59,12 @@ public class DefaultPortTest { ...@@ -56,10 +59,12 @@ public class DefaultPortTest {
56 public void basics() { 59 public void basics() {
57 Device device = new DefaultDevice(PID, DID1, SWITCH, "m", "h", "s", "n", 60 Device device = new DefaultDevice(PID, DID1, SWITCH, "m", "h", "s", "n",
58 new ChassisId()); 61 new ChassisId());
59 - Port port = new DefaultPort(device, portNumber(1), true); 62 + Port port = new DefaultPort(device, portNumber(1), true, FIBER, SP1);
60 assertEquals("incorrect element", device, port.element()); 63 assertEquals("incorrect element", device, port.element());
61 assertEquals("incorrect number", portNumber(1), port.number()); 64 assertEquals("incorrect number", portNumber(1), port.number());
62 assertEquals("incorrect state", true, port.isEnabled()); 65 assertEquals("incorrect state", true, port.isEnabled());
66 + assertEquals("incorrect speed", SP1, port.portSpeed());
67 + assertEquals("incorrect type", FIBER, port.type());
63 } 68 }
64 69
65 } 70 }
......
...@@ -15,11 +15,12 @@ ...@@ -15,11 +15,12 @@
15 */ 15 */
16 package org.onlab.onos.net.intent; 16 package org.onlab.onos.net.intent;
17 17
18 -import static org.junit.Assert.assertEquals;
19 -
20 import org.junit.Test; 18 import org.junit.Test;
21 import org.onlab.onos.net.NetTestTools; 19 import org.onlab.onos.net.NetTestTools;
22 import org.onlab.onos.net.Path; 20 import org.onlab.onos.net.Path;
21 +import org.onlab.onos.net.resource.LinkResourceRequest;
22 +
23 +import static org.junit.Assert.assertEquals;
23 24
24 public class PathIntentTest extends ConnectivityIntentTest { 25 public class PathIntentTest extends ConnectivityIntentTest {
25 // 111:11 --> 222:22 26 // 111:11 --> 222:22
...@@ -39,11 +40,11 @@ public class PathIntentTest extends ConnectivityIntentTest { ...@@ -39,11 +40,11 @@ public class PathIntentTest extends ConnectivityIntentTest {
39 40
40 @Override 41 @Override
41 protected PathIntent createOne() { 42 protected PathIntent createOne() {
42 - return new PathIntent(APPID, MATCH, NOP, PATH1); 43 + return new PathIntent(APPID, MATCH, NOP, PATH1, new LinkResourceRequest[0]);
43 } 44 }
44 45
45 @Override 46 @Override
46 protected PathIntent createAnother() { 47 protected PathIntent createAnother() {
47 - return new PathIntent(APPID, MATCH, NOP, PATH2); 48 + return new PathIntent(APPID, MATCH, NOP, PATH2, new LinkResourceRequest[0]);
48 } 49 }
49 } 50 }
......
...@@ -407,9 +407,9 @@ public class DeviceManager ...@@ -407,9 +407,9 @@ public class DeviceManager
407 // TODO duplicate suppression should probably occur in the MastershipManager 407 // TODO duplicate suppression should probably occur in the MastershipManager
408 // itself, so listeners that can't deal with duplicates don't have to 408 // itself, so listeners that can't deal with duplicates don't have to
409 // so this check themselves. 409 // so this check themselves.
410 - if (checkDuplicate(event.roleInfo(), term.termNumber())) { 410 +// if (checkDuplicate(event.roleInfo(), term.termNumber())) {
411 - return; 411 +// return;
412 - } 412 +// }
413 413
414 if (!myNodeId.equals(term.master())) { 414 if (!myNodeId.equals(term.master())) {
415 // something went wrong in consistency, let go 415 // something went wrong in consistency, let go
...@@ -435,7 +435,8 @@ public class DeviceManager ...@@ -435,7 +435,8 @@ public class DeviceManager
435 return; 435 return;
436 } 436 }
437 //flag the device as online. Is there a better way to do this? 437 //flag the device as online. Is there a better way to do this?
438 - DeviceEvent devEvent = store.createOrUpdateDevice(device.providerId(), did, 438 + DeviceEvent devEvent =
439 + store.createOrUpdateDevice(device.providerId(), did,
439 new DefaultDeviceDescription( 440 new DefaultDeviceDescription(
440 did.uri(), device.type(), device.manufacturer(), 441 did.uri(), device.type(), device.manufacturer(),
441 device.hwVersion(), device.swVersion(), 442 device.hwVersion(), device.swVersion(),
......
...@@ -15,6 +15,10 @@ ...@@ -15,6 +15,10 @@
15 */ 15 */
16 package org.onlab.onos.net.intent.impl; 16 package org.onlab.onos.net.intent.impl;
17 17
18 +import java.util.Arrays;
19 +import java.util.List;
20 +import java.util.Set;
21 +
18 import org.apache.felix.scr.annotations.Activate; 22 import org.apache.felix.scr.annotations.Activate;
19 import org.apache.felix.scr.annotations.Component; 23 import org.apache.felix.scr.annotations.Component;
20 import org.apache.felix.scr.annotations.Deactivate; 24 import org.apache.felix.scr.annotations.Deactivate;
...@@ -32,13 +36,10 @@ import org.onlab.onos.net.intent.IntentCompiler; ...@@ -32,13 +36,10 @@ import org.onlab.onos.net.intent.IntentCompiler;
32 import org.onlab.onos.net.intent.IntentExtensionService; 36 import org.onlab.onos.net.intent.IntentExtensionService;
33 import org.onlab.onos.net.intent.PathIntent; 37 import org.onlab.onos.net.intent.PathIntent;
34 import org.onlab.onos.net.topology.LinkWeight; 38 import org.onlab.onos.net.topology.LinkWeight;
39 +import org.onlab.onos.net.resource.LinkResourceRequest;
35 import org.onlab.onos.net.topology.PathService; 40 import org.onlab.onos.net.topology.PathService;
36 import org.onlab.onos.net.topology.TopologyEdge; 41 import org.onlab.onos.net.topology.TopologyEdge;
37 42
38 -import java.util.Arrays;
39 -import java.util.List;
40 -import java.util.Set;
41 -
42 import static org.onlab.onos.net.flow.DefaultTrafficSelector.builder; 43 import static org.onlab.onos.net.flow.DefaultTrafficSelector.builder;
43 44
44 /** 45 /**
...@@ -85,7 +86,7 @@ public class HostToHostIntentCompiler ...@@ -85,7 +86,7 @@ public class HostToHostIntentCompiler
85 TrafficSelector selector = builder(intent.selector()) 86 TrafficSelector selector = builder(intent.selector())
86 .matchEthSrc(src.mac()).matchEthDst(dst.mac()).build(); 87 .matchEthSrc(src.mac()).matchEthDst(dst.mac()).build();
87 return new PathIntent(intent.appId(), selector, intent.treatment(), 88 return new PathIntent(intent.appId(), selector, intent.treatment(),
88 - path); 89 + path, new LinkResourceRequest[0]);
89 } 90 }
90 91
91 private Path getPath(HostId one, HostId two) { 92 private Path getPath(HostId one, HostId two) {
......
...@@ -15,9 +15,6 @@ ...@@ -15,9 +15,6 @@
15 */ 15 */
16 package org.onlab.onos.net.intent.impl; 16 package org.onlab.onos.net.intent.impl;
17 17
18 -import static org.onlab.onos.net.flow.DefaultTrafficTreatment.builder;
19 -import static org.slf4j.LoggerFactory.getLogger;
20 -
21 import java.util.Iterator; 18 import java.util.Iterator;
22 import java.util.List; 19 import java.util.List;
23 20
...@@ -41,10 +38,15 @@ import org.onlab.onos.net.flow.TrafficTreatment; ...@@ -41,10 +38,15 @@ import org.onlab.onos.net.flow.TrafficTreatment;
41 import org.onlab.onos.net.intent.IntentExtensionService; 38 import org.onlab.onos.net.intent.IntentExtensionService;
42 import org.onlab.onos.net.intent.IntentInstaller; 39 import org.onlab.onos.net.intent.IntentInstaller;
43 import org.onlab.onos.net.intent.PathIntent; 40 import org.onlab.onos.net.intent.PathIntent;
41 +import org.onlab.onos.net.resource.LinkResourceAllocations;
42 +import org.onlab.onos.net.resource.LinkResourceService;
44 import org.slf4j.Logger; 43 import org.slf4j.Logger;
45 44
46 import com.google.common.collect.Lists; 45 import com.google.common.collect.Lists;
47 46
47 +import static org.onlab.onos.net.flow.DefaultTrafficTreatment.builder;
48 +import static org.slf4j.LoggerFactory.getLogger;
49 +
48 /** 50 /**
49 * Installer for {@link PathIntent packet path connectivity intents}. 51 * Installer for {@link PathIntent packet path connectivity intents}.
50 */ 52 */
...@@ -59,6 +61,9 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { ...@@ -59,6 +61,9 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> {
59 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 61 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
60 protected CoreService coreService; 62 protected CoreService coreService;
61 63
64 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
65 + protected LinkResourceService resourceService;
66 +
62 private ApplicationId appId; 67 private ApplicationId appId;
63 68
64 @Activate 69 @Activate
...@@ -74,6 +79,14 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { ...@@ -74,6 +79,14 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> {
74 79
75 @Override 80 @Override
76 public List<FlowRuleBatchOperation> install(PathIntent intent) { 81 public List<FlowRuleBatchOperation> install(PathIntent intent) {
82 + if (intent.resourceRequests().length > 0) {
83 + LinkResourceAllocations allocations = allocateBandwidth(intent);
84 + if (allocations == null) {
85 + log.debug("Insufficient bandwidth available to install path intent {}", intent);
86 + return null;
87 + }
88 + }
89 +
77 TrafficSelector.Builder builder = 90 TrafficSelector.Builder builder =
78 DefaultTrafficSelector.builder(intent.selector()); 91 DefaultTrafficSelector.builder(intent.selector());
79 Iterator<Link> links = intent.path().links().iterator(); 92 Iterator<Link> links = intent.path().links().iterator();
...@@ -117,6 +130,10 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { ...@@ -117,6 +130,10 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> {
117 return Lists.newArrayList(new FlowRuleBatchOperation(rules)); 130 return Lists.newArrayList(new FlowRuleBatchOperation(rules));
118 } 131 }
119 132
133 + private LinkResourceAllocations allocateBandwidth(PathIntent intent) {
134 + return resourceService.requestResources(intent.resourceRequests()[0]);
135 + }
136 +
120 // TODO refactor below this line... ---------------------------- 137 // TODO refactor below this line... ----------------------------
121 138
122 /** 139 /**
......
...@@ -15,6 +15,10 @@ ...@@ -15,6 +15,10 @@
15 */ 15 */
16 package org.onlab.onos.net.intent.impl; 16 package org.onlab.onos.net.intent.impl;
17 17
18 +import java.util.ArrayList;
19 +import java.util.List;
20 +import java.util.Set;
21 +
18 import org.apache.felix.scr.annotations.Activate; 22 import org.apache.felix.scr.annotations.Activate;
19 import org.apache.felix.scr.annotations.Component; 23 import org.apache.felix.scr.annotations.Component;
20 import org.apache.felix.scr.annotations.Deactivate; 24 import org.apache.felix.scr.annotations.Deactivate;
...@@ -31,15 +35,12 @@ import org.onlab.onos.net.intent.IntentExtensionService; ...@@ -31,15 +35,12 @@ import org.onlab.onos.net.intent.IntentExtensionService;
31 import org.onlab.onos.net.intent.PathIntent; 35 import org.onlab.onos.net.intent.PathIntent;
32 import org.onlab.onos.net.intent.PointToPointIntent; 36 import org.onlab.onos.net.intent.PointToPointIntent;
33 import org.onlab.onos.net.provider.ProviderId; 37 import org.onlab.onos.net.provider.ProviderId;
38 +import org.onlab.onos.net.resource.LinkResourceRequest;
34 import org.onlab.onos.net.topology.LinkWeight; 39 import org.onlab.onos.net.topology.LinkWeight;
35 import org.onlab.onos.net.topology.Topology; 40 import org.onlab.onos.net.topology.Topology;
36 import org.onlab.onos.net.topology.TopologyEdge; 41 import org.onlab.onos.net.topology.TopologyEdge;
37 import org.onlab.onos.net.topology.TopologyService; 42 import org.onlab.onos.net.topology.TopologyService;
38 43
39 -import java.util.ArrayList;
40 -import java.util.List;
41 -import java.util.Set;
42 -
43 import static java.util.Arrays.asList; 44 import static java.util.Arrays.asList;
44 45
45 /** 46 /**
...@@ -89,7 +90,8 @@ public class PointToPointIntentCompiler ...@@ -89,7 +90,8 @@ public class PointToPointIntentCompiler
89 private Intent createPathIntent(Path path, 90 private Intent createPathIntent(Path path,
90 PointToPointIntent intent) { 91 PointToPointIntent intent) {
91 return new PathIntent(intent.appId(), 92 return new PathIntent(intent.appId(),
92 - intent.selector(), intent.treatment(), path); 93 + intent.selector(), intent.treatment(), path,
94 + new LinkResourceRequest[0]);
93 } 95 }
94 96
95 /** 97 /**
......
1 +package org.onlab.onos.net.intent.impl;
2 +
3 +import java.util.ArrayList;
4 +import java.util.Arrays;
5 +import java.util.List;
6 +import java.util.Set;
7 +
8 +import org.apache.felix.scr.annotations.Activate;
9 +import org.apache.felix.scr.annotations.Component;
10 +import org.apache.felix.scr.annotations.Deactivate;
11 +import org.apache.felix.scr.annotations.Reference;
12 +import org.apache.felix.scr.annotations.ReferenceCardinality;
13 +import org.onlab.onos.net.ConnectPoint;
14 +import org.onlab.onos.net.DefaultEdgeLink;
15 +import org.onlab.onos.net.DefaultPath;
16 +import org.onlab.onos.net.Link;
17 +import org.onlab.onos.net.Path;
18 +import org.onlab.onos.net.intent.Intent;
19 +import org.onlab.onos.net.intent.IntentCompiler;
20 +import org.onlab.onos.net.intent.IntentExtensionService;
21 +import org.onlab.onos.net.intent.PathIntent;
22 +import org.onlab.onos.net.intent.PointToPointIntent;
23 +import org.onlab.onos.net.intent.PointToPointIntentWithBandwidthConstraint;
24 +import org.onlab.onos.net.provider.ProviderId;
25 +import org.onlab.onos.net.resource.BandwidthResourceRequest;
26 +import org.onlab.onos.net.resource.DefaultLinkResourceRequest;
27 +import org.onlab.onos.net.resource.LinkResourceRequest;
28 +import org.onlab.onos.net.resource.LinkResourceService;
29 +import org.onlab.onos.net.resource.ResourceRequest;
30 +import org.onlab.onos.net.resource.ResourceType;
31 +import org.onlab.onos.net.topology.LinkWeight;
32 +import org.onlab.onos.net.topology.Topology;
33 +import org.onlab.onos.net.topology.TopologyEdge;
34 +import org.onlab.onos.net.topology.TopologyService;
35 +
36 +/**
37 + * A intent compiler for {@link org.onlab.onos.net.intent.HostToHostIntent}.
38 + */
39 +@Component(immediate = true)
40 +public class PointToPointIntentWithBandwidthConstraintCompiler
41 + implements IntentCompiler<PointToPointIntentWithBandwidthConstraint> {
42 +
43 + private static final ProviderId PID = new ProviderId("core", "org.onlab.onos.core", true);
44 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
45 + protected IntentExtensionService intentManager;
46 +
47 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
48 + protected TopologyService topologyService;
49 +
50 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
51 + protected LinkResourceService resourceService;
52 +
53 + @Activate
54 + public void activate() {
55 + intentManager.registerCompiler(PointToPointIntentWithBandwidthConstraint.class, this);
56 + }
57 +
58 + @Deactivate
59 + public void deactivate() {
60 + intentManager.unregisterCompiler(PointToPointIntent.class);
61 + }
62 +
63 + @Override
64 + public List<Intent> compile(PointToPointIntentWithBandwidthConstraint intent) {
65 + Path path = getPath(intent.ingressPoint(), intent.egressPoint(), intent.bandwidthRequest());
66 +
67 + List<Link> links = new ArrayList<>();
68 + links.add(DefaultEdgeLink.createEdgeLink(intent.ingressPoint(), true));
69 + links.addAll(path.links());
70 + links.add(DefaultEdgeLink.createEdgeLink(intent.egressPoint(), false));
71 +
72 + return Arrays.asList(createPathIntent(new DefaultPath(PID, links, path.cost() + 2,
73 + path.annotations()),
74 + intent));
75 + }
76 +
77 + /**
78 + * Creates a path intent from the specified path and original
79 + * connectivity intent.
80 + *
81 + * @param path path to create an intent for
82 + * @param intent original intent
83 + */
84 + private Intent createPathIntent(Path path,
85 + PointToPointIntentWithBandwidthConstraint intent) {
86 + LinkResourceRequest.Builder request = DefaultLinkResourceRequest.builder(intent.id(),
87 + path.links())
88 + // TODO - this seems awkward, maybe allow directly attaching a BandwidthRequest
89 + .addBandwidthRequest(intent.bandwidthRequest().bandwidth().toDouble());
90 + LinkResourceRequest bandwidthRequest = request.build();
91 + LinkResourceRequest[] bandwidthRequests = {bandwidthRequest};
92 + return new PathIntent(intent.appId(),
93 + intent.selector(), intent.treatment(), path,
94 + bandwidthRequests);
95 + }
96 +
97 + /**
98 + * Computes a path between two ConnectPoints.
99 + *
100 + * @param one start of the path
101 + * @param two end of the path
102 + * @return Path between the two
103 + * @throws org.onlab.onos.net.intent.impl.PathNotFoundException if a path cannot be found
104 + */
105 + private Path getPath(ConnectPoint one, ConnectPoint two, final BandwidthResourceRequest bandwidthRequest) {
106 + Topology topology = topologyService.currentTopology();
107 + LinkWeight weight = new LinkWeight() {
108 + @Override
109 + public double weight(TopologyEdge edge) {
110 + if (bandwidthRequest != null) {
111 + double allocatedBandwidth = 0.0;
112 + Iterable<ResourceRequest> availableResources = resourceService.getAvailableResources(edge.link());
113 + for (ResourceRequest availableResource : availableResources) {
114 + if (availableResource.type() == ResourceType.BANDWIDTH) {
115 + BandwidthResourceRequest bandwidthRequest = (BandwidthResourceRequest) availableResource;
116 + allocatedBandwidth += bandwidthRequest.bandwidth().toDouble();
117 + }
118 + }
119 +
120 + // TODO this needs to be discovered from switch/ports somehow
121 + double maxBandwidth = 1000;
122 +
123 + double availableBandwidth = maxBandwidth - allocatedBandwidth;
124 + if (availableBandwidth >= bandwidthRequest.bandwidth().toDouble()) {
125 + return 1;
126 + } else {
127 + return -1;
128 + }
129 + } else {
130 + return 1;
131 + }
132 + }
133 + };
134 +
135 + Set<Path> paths = topologyService.getPaths(topology,
136 + one.deviceId(),
137 + two.deviceId(),
138 + weight);
139 +
140 + if (paths.isEmpty()) {
141 + throw new PathNotFoundException("No packet path from " + one + " to " + two);
142 + }
143 + // TODO: let's be more intelligent about this eventually
144 + return paths.iterator().next();
145 + }
146 +}
...@@ -15,9 +15,13 @@ ...@@ -15,9 +15,13 @@
15 */ 15 */
16 package org.onlab.onos.net.resource.impl; 16 package org.onlab.onos.net.resource.impl;
17 17
18 +import static com.google.common.base.Preconditions.checkArgument;
19 +import static com.google.common.base.Preconditions.checkNotNull;
18 import static org.slf4j.LoggerFactory.getLogger; 20 import static org.slf4j.LoggerFactory.getLogger;
19 21
22 +import java.util.Collections;
20 import java.util.HashMap; 23 import java.util.HashMap;
24 +import java.util.HashSet;
21 import java.util.Iterator; 25 import java.util.Iterator;
22 import java.util.Map; 26 import java.util.Map;
23 import java.util.Set; 27 import java.util.Set;
...@@ -25,6 +29,8 @@ import java.util.Set; ...@@ -25,6 +29,8 @@ import java.util.Set;
25 import org.apache.felix.scr.annotations.Activate; 29 import org.apache.felix.scr.annotations.Activate;
26 import org.apache.felix.scr.annotations.Component; 30 import org.apache.felix.scr.annotations.Component;
27 import org.apache.felix.scr.annotations.Deactivate; 31 import org.apache.felix.scr.annotations.Deactivate;
32 +import org.apache.felix.scr.annotations.Reference;
33 +import org.apache.felix.scr.annotations.ReferenceCardinality;
28 import org.apache.felix.scr.annotations.Service; 34 import org.apache.felix.scr.annotations.Service;
29 import org.onlab.onos.net.Link; 35 import org.onlab.onos.net.Link;
30 import org.onlab.onos.net.intent.IntentId; 36 import org.onlab.onos.net.intent.IntentId;
...@@ -32,15 +38,16 @@ import org.onlab.onos.net.resource.BandwidthResourceAllocation; ...@@ -32,15 +38,16 @@ import org.onlab.onos.net.resource.BandwidthResourceAllocation;
32 import org.onlab.onos.net.resource.BandwidthResourceRequest; 38 import org.onlab.onos.net.resource.BandwidthResourceRequest;
33 import org.onlab.onos.net.resource.Lambda; 39 import org.onlab.onos.net.resource.Lambda;
34 import org.onlab.onos.net.resource.LambdaResourceAllocation; 40 import org.onlab.onos.net.resource.LambdaResourceAllocation;
41 +import org.onlab.onos.net.resource.LambdaResourceRequest;
35 import org.onlab.onos.net.resource.LinkResourceAllocations; 42 import org.onlab.onos.net.resource.LinkResourceAllocations;
36 import org.onlab.onos.net.resource.LinkResourceRequest; 43 import org.onlab.onos.net.resource.LinkResourceRequest;
37 import org.onlab.onos.net.resource.LinkResourceService; 44 import org.onlab.onos.net.resource.LinkResourceService;
45 +import org.onlab.onos.net.resource.LinkResourceStore;
38 import org.onlab.onos.net.resource.ResourceAllocation; 46 import org.onlab.onos.net.resource.ResourceAllocation;
39 import org.onlab.onos.net.resource.ResourceRequest; 47 import org.onlab.onos.net.resource.ResourceRequest;
48 +import org.onlab.onos.net.resource.ResourceType;
40 import org.slf4j.Logger; 49 import org.slf4j.Logger;
41 50
42 -import com.google.common.collect.Sets;
43 -
44 /** 51 /**
45 * Provides basic implementation of link resources allocation. 52 * Provides basic implementation of link resources allocation.
46 */ 53 */
...@@ -50,6 +57,9 @@ public class LinkResourceManager implements LinkResourceService { ...@@ -50,6 +57,9 @@ public class LinkResourceManager implements LinkResourceService {
50 57
51 private final Logger log = getLogger(getClass()); 58 private final Logger log = getLogger(getClass());
52 59
60 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
61 + private LinkResourceStore store;
62 +
53 @Activate 63 @Activate
54 public void activate() { 64 public void activate() {
55 log.info("Started"); 65 log.info("Started");
...@@ -60,27 +70,65 @@ public class LinkResourceManager implements LinkResourceService { ...@@ -60,27 +70,65 @@ public class LinkResourceManager implements LinkResourceService {
60 log.info("Stopped"); 70 log.info("Stopped");
61 } 71 }
62 72
73 + /**
74 + * Returns available lambdas on specified link.
75 + *
76 + * @param link the link
77 + * @return available lambdas on specified link
78 + */
79 + private Set<Lambda> getAvailableLambdas(Link link) {
80 + checkNotNull(link);
81 + Set<ResourceAllocation> resAllocs = store.getFreeResources(link);
82 + if (resAllocs == null) {
83 + return Collections.emptySet();
84 + }
85 + Set<Lambda> lambdas = new HashSet<>();
86 + for (ResourceAllocation res : resAllocs) {
87 + if (res.type() == ResourceType.LAMBDA) {
88 + lambdas.add(((LambdaResourceAllocation) res).lambda());
89 + }
90 + }
91 + return lambdas;
92 + }
93 +
94 + /**
95 + * Returns available lambdas on specified links.
96 + *
97 + * @param links the links
98 + * @return available lambdas on specified links
99 + */
63 private Iterable<Lambda> getAvailableLambdas(Iterable<Link> links) { 100 private Iterable<Lambda> getAvailableLambdas(Iterable<Link> links) {
64 - return Sets.newHashSet(Lambda.valueOf(7)); 101 + checkNotNull(links);
102 + Iterator<Link> i = links.iterator();
103 + checkArgument(i.hasNext());
104 + Set<Lambda> lambdas = new HashSet<>(getAvailableLambdas(i.next()));
105 + while (i.hasNext()) {
106 + lambdas.retainAll(getAvailableLambdas(i.next()));
107 + }
108 + return lambdas;
65 } 109 }
66 110
67 @Override 111 @Override
68 public LinkResourceAllocations requestResources(LinkResourceRequest req) { 112 public LinkResourceAllocations requestResources(LinkResourceRequest req) {
69 - // TODO implement it using a resource data store. 113 + // TODO Concatenate multiple bandwidth requests.
114 + // TODO Support multiple lambda resource requests.
115 + // TODO Throw appropriate exception.
70 116
71 - ResourceAllocation alloc = null; 117 + Set<ResourceAllocation> allocs = new HashSet<>();
72 for (ResourceRequest r : req.resources()) { 118 for (ResourceRequest r : req.resources()) {
73 switch (r.type()) { 119 switch (r.type()) {
74 case BANDWIDTH: 120 case BANDWIDTH:
75 - log.info("requestResources() always returns requested bandwidth");
76 BandwidthResourceRequest br = (BandwidthResourceRequest) r; 121 BandwidthResourceRequest br = (BandwidthResourceRequest) r;
77 - alloc = new BandwidthResourceAllocation(br.bandwidth()); 122 + allocs.add(new BandwidthResourceAllocation(br.bandwidth()));
78 break; 123 break;
79 case LAMBDA: 124 case LAMBDA:
80 - log.info("requestResources() always returns lambda 7"); 125 + Iterator<Lambda> lambdaIterator =
81 - Iterator<Lambda> lambdaIterator = getAvailableLambdas(req.links()).iterator(); 126 + getAvailableLambdas(req.links()).iterator();
82 if (lambdaIterator.hasNext()) { 127 if (lambdaIterator.hasNext()) {
83 - alloc = new LambdaResourceAllocation(lambdaIterator.next()); 128 + allocs.add(new LambdaResourceAllocation(lambdaIterator.next()));
129 + } else {
130 + log.info("Failed to allocate lambda resource.");
131 + return null;
84 } 132 }
85 break; 133 break;
86 default: 134 default:
...@@ -90,50 +138,66 @@ public class LinkResourceManager implements LinkResourceService { ...@@ -90,50 +138,66 @@ public class LinkResourceManager implements LinkResourceService {
90 138
91 Map<Link, Set<ResourceAllocation>> allocations = new HashMap<>(); 139 Map<Link, Set<ResourceAllocation>> allocations = new HashMap<>();
92 for (Link link : req.links()) { 140 for (Link link : req.links()) {
93 - allocations.put(link, Sets.newHashSet(alloc)); 141 + allocations.put(link, allocs);
94 } 142 }
95 - return new DefaultLinkResourceAllocations(req, allocations); 143 + LinkResourceAllocations result =
144 + new DefaultLinkResourceAllocations(req, allocations);
145 + store.allocateResources(result);
146 + return result;
147 +
96 } 148 }
97 149
98 @Override 150 @Override
99 public void releaseResources(LinkResourceAllocations allocations) { 151 public void releaseResources(LinkResourceAllocations allocations) {
100 - // TODO Auto-generated method stub 152 + store.releaseResources(allocations);
101 -
102 } 153 }
103 154
104 @Override 155 @Override
105 public LinkResourceAllocations updateResources(LinkResourceRequest req, 156 public LinkResourceAllocations updateResources(LinkResourceRequest req,
106 LinkResourceAllocations oldAllocations) { 157 LinkResourceAllocations oldAllocations) {
158 + // TODO
107 return null; 159 return null;
108 } 160 }
109 161
110 @Override 162 @Override
111 public Iterable<LinkResourceAllocations> getAllocations() { 163 public Iterable<LinkResourceAllocations> getAllocations() {
112 - // TODO Auto-generated method stub 164 + return store.getAllocations();
113 - return null;
114 } 165 }
115 166
116 @Override 167 @Override
117 public Iterable<LinkResourceAllocations> getAllocations(Link link) { 168 public Iterable<LinkResourceAllocations> getAllocations(Link link) {
118 - // TODO Auto-generated method stub 169 + return store.getAllocations(link);
119 - return null;
120 } 170 }
121 171
122 @Override 172 @Override
123 public LinkResourceAllocations getAllocations(IntentId intentId) { 173 public LinkResourceAllocations getAllocations(IntentId intentId) {
124 - // TODO Auto-generated method stub 174 + return store.getAllocations(intentId);
125 - return null;
126 } 175 }
127 176
128 @Override 177 @Override
129 public Iterable<ResourceRequest> getAvailableResources(Link link) { 178 public Iterable<ResourceRequest> getAvailableResources(Link link) {
130 - // TODO Auto-generated method stub 179 + Set<ResourceAllocation> freeRes = store.getFreeResources(link);
131 - return null; 180 + Set<ResourceRequest> result = new HashSet<>();
181 + for (ResourceAllocation alloc : freeRes) {
182 + switch (alloc.type()) {
183 + case BANDWIDTH:
184 + result.add(new BandwidthResourceRequest(
185 + ((BandwidthResourceAllocation) alloc).bandwidth()));
186 + break;
187 + case LAMBDA:
188 + result.add(new LambdaResourceRequest());
189 + break;
190 + default:
191 + break;
192 + }
193 + }
194 + return result;
132 } 195 }
133 196
134 @Override 197 @Override
135 public ResourceRequest getAvailableResources(Link link, 198 public ResourceRequest getAvailableResources(Link link,
136 LinkResourceAllocations allocations) { 199 LinkResourceAllocations allocations) {
200 + // TODO
137 return null; 201 return null;
138 } 202 }
139 203
......
...@@ -543,8 +543,9 @@ public class GossipDeviceStore ...@@ -543,8 +543,9 @@ public class GossipDeviceStore
543 Port newPort, 543 Port newPort,
544 Map<PortNumber, Port> ports) { 544 Map<PortNumber, Port> ports) {
545 if (oldPort.isEnabled() != newPort.isEnabled() || 545 if (oldPort.isEnabled() != newPort.isEnabled() ||
546 + oldPort.type() != newPort.type() ||
547 + oldPort.portSpeed() != newPort.portSpeed() ||
546 !AnnotationsUtil.isEqual(oldPort.annotations(), newPort.annotations())) { 548 !AnnotationsUtil.isEqual(oldPort.annotations(), newPort.annotations())) {
547 -
548 ports.put(oldPort.number(), newPort); 549 ports.put(oldPort.number(), newPort);
549 return new DeviceEvent(PORT_UPDATED, device, newPort); 550 return new DeviceEvent(PORT_UPDATED, device, newPort);
550 } 551 }
...@@ -867,7 +868,10 @@ public class GossipDeviceStore ...@@ -867,7 +868,10 @@ public class GossipDeviceStore
867 } 868 }
868 } 869 }
869 870
870 - return new DefaultPort(device, number, isEnabled, annotations); 871 + return portDesc == null ?
872 + new DefaultPort(device, number, false, annotations) :
873 + new DefaultPort(device, number, isEnabled, portDesc.value().type(),
874 + portDesc.value().portSpeed(), annotations);
871 } 875 }
872 876
873 /** 877 /**
......
...@@ -15,6 +15,10 @@ ...@@ -15,6 +15,10 @@
15 */ 15 */
16 package org.onlab.onos.store.mastership.impl; 16 package org.onlab.onos.store.mastership.impl;
17 17
18 +import static org.onlab.onos.net.MastershipRole.MASTER;
19 +import static org.onlab.onos.net.MastershipRole.NONE;
20 +import static org.onlab.onos.net.MastershipRole.STANDBY;
21 +
18 import java.util.Collections; 22 import java.util.Collections;
19 import java.util.EnumMap; 23 import java.util.EnumMap;
20 import java.util.LinkedList; 24 import java.util.LinkedList;
...@@ -59,18 +63,30 @@ final class RoleValue { ...@@ -59,18 +63,30 @@ final class RoleValue {
59 return value.get(type).contains(nodeId); 63 return value.get(type).contains(nodeId);
60 } 64 }
61 65
66 + public MastershipRole getRole(NodeId nodeId) {
67 + if (contains(MASTER, nodeId)) {
68 + return MASTER;
69 + }
70 + if (contains(STANDBY, nodeId)) {
71 + return STANDBY;
72 + }
73 + return NONE;
74 + }
75 +
62 /** 76 /**
63 * Associates a node to a certain role. 77 * Associates a node to a certain role.
64 * 78 *
65 * @param type the role 79 * @param type the role
66 * @param nodeId the node ID of the node to associate 80 * @param nodeId the node ID of the node to associate
81 + * @return true if modified
67 */ 82 */
68 - public void add(MastershipRole type, NodeId nodeId) { 83 + public boolean add(MastershipRole type, NodeId nodeId) {
69 List<NodeId> nodes = value.get(type); 84 List<NodeId> nodes = value.get(type);
70 85
71 if (!nodes.contains(nodeId)) { 86 if (!nodes.contains(nodeId)) {
72 - nodes.add(nodeId); 87 + return nodes.add(nodeId);
73 } 88 }
89 + return false;
74 } 90 }
75 91
76 /** 92 /**
...@@ -78,7 +94,7 @@ final class RoleValue { ...@@ -78,7 +94,7 @@ final class RoleValue {
78 * 94 *
79 * @param type the role 95 * @param type the role
80 * @param nodeId the ID of the node to remove 96 * @param nodeId the ID of the node to remove
81 - * @return 97 + * @return true if modified
82 */ 98 */
83 public boolean remove(MastershipRole type, NodeId nodeId) { 99 public boolean remove(MastershipRole type, NodeId nodeId) {
84 List<NodeId> nodes = value.get(type); 100 List<NodeId> nodes = value.get(type);
...@@ -96,10 +112,12 @@ final class RoleValue { ...@@ -96,10 +112,12 @@ final class RoleValue {
96 * @param nodeId the Node ID of node changing roles 112 * @param nodeId the Node ID of node changing roles
97 * @param from the old role 113 * @param from the old role
98 * @param to the new role 114 * @param to the new role
115 + * @return true if modified
99 */ 116 */
100 - public void reassign(NodeId nodeId, MastershipRole from, MastershipRole to) { 117 + public boolean reassign(NodeId nodeId, MastershipRole from, MastershipRole to) {
101 - remove(from, nodeId); 118 + boolean modified = remove(from, nodeId);
102 - add(to, nodeId); 119 + modified |= add(to, nodeId);
120 + return modified;
103 } 121 }
104 122
105 /** 123 /**
...@@ -109,10 +127,12 @@ final class RoleValue { ...@@ -109,10 +127,12 @@ final class RoleValue {
109 * @param from the old NodeId to replace 127 * @param from the old NodeId to replace
110 * @param to the new NodeId 128 * @param to the new NodeId
111 * @param type the role associated with the old NodeId 129 * @param type the role associated with the old NodeId
130 + * @return true if modified
112 */ 131 */
113 - public void replace(NodeId from, NodeId to, MastershipRole type) { 132 + public boolean replace(NodeId from, NodeId to, MastershipRole type) {
114 - remove(type, from); 133 + boolean modified = remove(type, from);
115 - add(type, to); 134 + modified |= add(type, to);
135 + return modified;
116 } 136 }
117 137
118 /** 138 /**
......
...@@ -142,7 +142,7 @@ public class DistributedMastershipStoreTest { ...@@ -142,7 +142,7 @@ public class DistributedMastershipStoreTest {
142 testStore.setCurrent(CN1); 142 testStore.setCurrent(CN1);
143 143
144 //if already MASTER, nothing should happen 144 //if already MASTER, nothing should happen
145 - testStore.put(DID2, N1, true, false, false); 145 + testStore.put(DID2, N1, true, false, true);
146 assertEquals("wrong role for MASTER:", MASTER, dms.requestRole(DID2)); 146 assertEquals("wrong role for MASTER:", MASTER, dms.requestRole(DID2));
147 147
148 //populate maps with DID1, N1 thru NONE case 148 //populate maps with DID1, N1 thru NONE case
......
...@@ -22,11 +22,11 @@ import java.util.HashMap; ...@@ -22,11 +22,11 @@ import java.util.HashMap;
22 import java.util.HashSet; 22 import java.util.HashSet;
23 import java.util.LinkedList; 23 import java.util.LinkedList;
24 24
25 -import org.onlab.onos.core.DefaultApplicationId;
26 import org.onlab.onos.cluster.ControllerNode; 25 import org.onlab.onos.cluster.ControllerNode;
27 import org.onlab.onos.cluster.DefaultControllerNode; 26 import org.onlab.onos.cluster.DefaultControllerNode;
28 import org.onlab.onos.cluster.NodeId; 27 import org.onlab.onos.cluster.NodeId;
29 import org.onlab.onos.cluster.RoleInfo; 28 import org.onlab.onos.cluster.RoleInfo;
29 +import org.onlab.onos.core.DefaultApplicationId;
30 import org.onlab.onos.mastership.MastershipTerm; 30 import org.onlab.onos.mastership.MastershipTerm;
31 import org.onlab.onos.net.ConnectPoint; 31 import org.onlab.onos.net.ConnectPoint;
32 import org.onlab.onos.net.DefaultAnnotations; 32 import org.onlab.onos.net.DefaultAnnotations;
...@@ -59,6 +59,9 @@ import org.onlab.onos.net.flow.StoredFlowEntry; ...@@ -59,6 +59,9 @@ import org.onlab.onos.net.flow.StoredFlowEntry;
59 import org.onlab.onos.net.flow.criteria.Criteria; 59 import org.onlab.onos.net.flow.criteria.Criteria;
60 import org.onlab.onos.net.flow.criteria.Criterion; 60 import org.onlab.onos.net.flow.criteria.Criterion;
61 import org.onlab.onos.net.flow.instructions.Instructions; 61 import org.onlab.onos.net.flow.instructions.Instructions;
62 +import org.onlab.onos.net.flow.instructions.L0ModificationInstruction;
63 +import org.onlab.onos.net.flow.instructions.L2ModificationInstruction;
64 +import org.onlab.onos.net.flow.instructions.L3ModificationInstruction;
62 import org.onlab.onos.net.host.DefaultHostDescription; 65 import org.onlab.onos.net.host.DefaultHostDescription;
63 import org.onlab.onos.net.host.HostDescription; 66 import org.onlab.onos.net.host.HostDescription;
64 import org.onlab.onos.net.intent.ConnectivityIntent; 67 import org.onlab.onos.net.intent.ConnectivityIntent;
...@@ -66,6 +69,7 @@ import org.onlab.onos.net.intent.HostToHostIntent; ...@@ -66,6 +69,7 @@ import org.onlab.onos.net.intent.HostToHostIntent;
66 import org.onlab.onos.net.intent.Intent; 69 import org.onlab.onos.net.intent.Intent;
67 import org.onlab.onos.net.intent.IntentId; 70 import org.onlab.onos.net.intent.IntentId;
68 import org.onlab.onos.net.intent.IntentState; 71 import org.onlab.onos.net.intent.IntentState;
72 +import org.onlab.onos.net.intent.LinkCollectionIntent;
69 import org.onlab.onos.net.intent.MultiPointToSinglePointIntent; 73 import org.onlab.onos.net.intent.MultiPointToSinglePointIntent;
70 import org.onlab.onos.net.intent.PathIntent; 74 import org.onlab.onos.net.intent.PathIntent;
71 import org.onlab.onos.net.intent.PointToPointIntent; 75 import org.onlab.onos.net.intent.PointToPointIntent;
...@@ -115,6 +119,7 @@ public final class KryoNamespaces { ...@@ -115,6 +119,7 @@ public final class KryoNamespaces {
115 // 119 //
116 ControllerNode.State.class, 120 ControllerNode.State.class,
117 Device.Type.class, 121 Device.Type.class,
122 + Port.Type.class,
118 ChassisId.class, 123 ChassisId.class,
119 DefaultAnnotations.class, 124 DefaultAnnotations.class,
120 DefaultControllerNode.class, 125 DefaultControllerNode.class,
...@@ -149,6 +154,17 @@ public final class KryoNamespaces { ...@@ -149,6 +154,17 @@ public final class KryoNamespaces {
149 DefaultTrafficTreatment.class, 154 DefaultTrafficTreatment.class,
150 Instructions.DropInstruction.class, 155 Instructions.DropInstruction.class,
151 Instructions.OutputInstruction.class, 156 Instructions.OutputInstruction.class,
157 + L0ModificationInstruction.class,
158 + L0ModificationInstruction.L0SubType.class,
159 + L0ModificationInstruction.ModLambdaInstruction.class,
160 + L2ModificationInstruction.class,
161 + L2ModificationInstruction.L2SubType.class,
162 + L2ModificationInstruction.ModEtherInstruction.class,
163 + L2ModificationInstruction.ModVlanIdInstruction.class,
164 + L2ModificationInstruction.ModVlanPcpInstruction.class,
165 + L3ModificationInstruction.class,
166 + L3ModificationInstruction.L3SubType.class,
167 + L3ModificationInstruction.ModIPInstruction.class,
152 RoleInfo.class, 168 RoleInfo.class,
153 FlowRuleBatchOperation.class, 169 FlowRuleBatchOperation.class,
154 CompletedBatchOperation.class, 170 CompletedBatchOperation.class,
...@@ -163,7 +179,8 @@ public final class KryoNamespaces { ...@@ -163,7 +179,8 @@ public final class KryoNamespaces {
163 DefaultEdgeLink.class, 179 DefaultEdgeLink.class,
164 HostToHostIntent.class, 180 HostToHostIntent.class,
165 PointToPointIntent.class, 181 PointToPointIntent.class,
166 - MultiPointToSinglePointIntent.class 182 + MultiPointToSinglePointIntent.class,
183 + LinkCollectionIntent.class
167 ) 184 )
168 .register(DefaultApplicationId.class, new DefaultApplicationIdSerializer()) 185 .register(DefaultApplicationId.class, new DefaultApplicationIdSerializer())
169 .register(URI.class, new URISerializer()) 186 .register(URI.class, new URISerializer())
......
...@@ -15,13 +15,10 @@ ...@@ -15,13 +15,10 @@
15 */ 15 */
16 package org.onlab.onos.store.serializers; 16 package org.onlab.onos.store.serializers;
17 17
18 -import static org.junit.Assert.assertEquals; 18 +import com.google.common.collect.ImmutableList;
19 -import static org.onlab.onos.net.DeviceId.deviceId; 19 +import com.google.common.collect.ImmutableMap;
20 -import static org.onlab.onos.net.PortNumber.portNumber; 20 +import com.google.common.collect.ImmutableSet;
21 -import static java.util.Arrays.asList; 21 +import com.google.common.testing.EqualsTester;
22 -
23 -import java.nio.ByteBuffer;
24 -
25 import org.junit.After; 22 import org.junit.After;
26 import org.junit.Before; 23 import org.junit.Before;
27 import org.junit.BeforeClass; 24 import org.junit.BeforeClass;
...@@ -50,10 +47,12 @@ import org.onlab.packet.IpPrefix; ...@@ -50,10 +47,12 @@ import org.onlab.packet.IpPrefix;
50 import org.onlab.packet.MacAddress; 47 import org.onlab.packet.MacAddress;
51 import org.onlab.util.KryoNamespace; 48 import org.onlab.util.KryoNamespace;
52 49
53 -import com.google.common.collect.ImmutableList; 50 +import java.nio.ByteBuffer;
54 -import com.google.common.collect.ImmutableMap; 51 +
55 -import com.google.common.collect.ImmutableSet; 52 +import static java.util.Arrays.asList;
56 -import com.google.common.testing.EqualsTester; 53 +import static org.junit.Assert.assertEquals;
54 +import static org.onlab.onos.net.DeviceId.deviceId;
55 +import static org.onlab.onos.net.PortNumber.portNumber;
57 56
58 public class KryoSerializerTest { 57 public class KryoSerializerTest {
59 58
......
...@@ -291,8 +291,9 @@ public class SimpleDeviceStore ...@@ -291,8 +291,9 @@ public class SimpleDeviceStore
291 Port newPort, 291 Port newPort,
292 Map<PortNumber, Port> ports) { 292 Map<PortNumber, Port> ports) {
293 if (oldPort.isEnabled() != newPort.isEnabled() || 293 if (oldPort.isEnabled() != newPort.isEnabled() ||
294 + oldPort.type() != newPort.type() ||
295 + oldPort.portSpeed() != newPort.portSpeed() ||
294 !AnnotationsUtil.isEqual(oldPort.annotations(), newPort.annotations())) { 296 !AnnotationsUtil.isEqual(oldPort.annotations(), newPort.annotations())) {
295 -
296 ports.put(oldPort.number(), newPort); 297 ports.put(oldPort.number(), newPort);
297 return new DeviceEvent(PORT_UPDATED, device, newPort); 298 return new DeviceEvent(PORT_UPDATED, device, newPort);
298 } 299 }
...@@ -510,7 +511,10 @@ public class SimpleDeviceStore ...@@ -510,7 +511,10 @@ public class SimpleDeviceStore
510 } 511 }
511 } 512 }
512 513
513 - return new DefaultPort(device, number, isEnabled, annotations); 514 + return portDesc == null ?
515 + new DefaultPort(device, number, false, annotations) :
516 + new DefaultPort(device, number, isEnabled, portDesc.type(),
517 + portDesc.portSpeed(), annotations);
514 } 518 }
515 519
516 /** 520 /**
......
1 +/*
2 + * Copyright 2014 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onlab.onos.store.trivial.impl;
17 +
18 +import static com.google.common.base.Preconditions.*;
19 +import static org.slf4j.LoggerFactory.getLogger;
20 +
21 +import java.util.Collections;
22 +import java.util.HashMap;
23 +import java.util.HashSet;
24 +import java.util.Map;
25 +import java.util.Set;
26 +
27 +import org.apache.felix.scr.annotations.Activate;
28 +import org.apache.felix.scr.annotations.Component;
29 +import org.apache.felix.scr.annotations.Deactivate;
30 +import org.apache.felix.scr.annotations.Service;
31 +import org.onlab.onos.net.Link;
32 +import org.onlab.onos.net.intent.IntentId;
33 +import org.onlab.onos.net.resource.Bandwidth;
34 +import org.onlab.onos.net.resource.BandwidthResourceAllocation;
35 +import org.onlab.onos.net.resource.Lambda;
36 +import org.onlab.onos.net.resource.LambdaResourceAllocation;
37 +import org.onlab.onos.net.resource.LinkResourceAllocations;
38 +import org.onlab.onos.net.resource.LinkResourceStore;
39 +import org.onlab.onos.net.resource.ResourceAllocation;
40 +import org.onlab.onos.net.resource.ResourceType;
41 +import org.slf4j.Logger;
42 +
43 +/**
44 + * Manages link resources using trivial in-memory structures implementation.
45 + */
46 +@Component(immediate = true)
47 +@Service
48 +public class SimpleLinkResourceStore implements LinkResourceStore {
49 + private final Logger log = getLogger(getClass());
50 + private Map<IntentId, LinkResourceAllocations> linkResourceAllocationsMap;
51 + private Map<Link, Set<LinkResourceAllocations>> allocatedResources;
52 + private Map<Link, Set<ResourceAllocation>> freeResources;
53 +
54 + @Activate
55 + public void activate() {
56 + linkResourceAllocationsMap = new HashMap<>();
57 + allocatedResources = new HashMap<>();
58 + freeResources = new HashMap<>();
59 +
60 + log.info("Started");
61 + }
62 +
63 + @Deactivate
64 + public void deactivate() {
65 + log.info("Stopped");
66 + }
67 +
68 + private Set<ResourceAllocation> readOriginalFreeResources(Link link) {
69 + // TODO read capacity and lambda resources from topology
70 + Set<ResourceAllocation> allocations = new HashSet<>();
71 + for (int i = 1; i <= 100; i++) {
72 + allocations.add(new LambdaResourceAllocation(Lambda.valueOf(i)));
73 + }
74 + allocations.add(new BandwidthResourceAllocation(Bandwidth.valueOf(1000000)));
75 + return allocations;
76 + }
77 +
78 + private BandwidthResourceAllocation getBandwidth(Set<ResourceAllocation> freeRes) {
79 + for (ResourceAllocation res : freeRes) {
80 + if (res.type() == ResourceType.BANDWIDTH) {
81 + return (BandwidthResourceAllocation) res;
82 + }
83 + }
84 + return new BandwidthResourceAllocation(Bandwidth.valueOf(0));
85 + }
86 +
87 + private void subtractFreeResources(Link link, LinkResourceAllocations allocations) {
88 + // TODO Use lock or version for updating freeResources.
89 + checkNotNull(link);
90 + Set<ResourceAllocation> freeRes = freeResources.get(link);
91 + checkNotNull(freeRes);
92 + freeRes = new HashSet<>(freeRes);
93 + Set<ResourceAllocation> subRes = allocations.getResourceAllocation(link);
94 + for (ResourceAllocation res : subRes) {
95 + switch (res.type()) {
96 + case BANDWIDTH:
97 + BandwidthResourceAllocation ba = getBandwidth(freeRes);
98 + double requestedBandwidth =
99 + ((BandwidthResourceAllocation) res).bandwidth().toDouble();
100 + double newBandwidth = ba.bandwidth().toDouble() - requestedBandwidth;
101 + checkState(newBandwidth >= 0.0);
102 + freeRes.remove(ba);
103 + freeRes.add(new BandwidthResourceAllocation(
104 + Bandwidth.valueOf(newBandwidth)));
105 + break;
106 + case LAMBDA:
107 + checkState(freeRes.remove(res));
108 + break;
109 + default:
110 + break;
111 + }
112 + }
113 + freeResources.put(link, freeRes);
114 +
115 + }
116 +
117 + private void addFreeResources(Link link, LinkResourceAllocations allocations) {
118 + // TODO Use lock or version for updating freeResources.
119 + Set<ResourceAllocation> freeRes = freeResources.get(link);
120 + checkNotNull(freeRes);
121 + freeRes = new HashSet<>(freeRes);
122 + Set<ResourceAllocation> addRes = allocations.getResourceAllocation(link);
123 + for (ResourceAllocation res : addRes) {
124 + switch (res.type()) {
125 + case BANDWIDTH:
126 + BandwidthResourceAllocation ba = getBandwidth(freeRes);
127 + double requestedBandwidth =
128 + ((BandwidthResourceAllocation) res).bandwidth().toDouble();
129 + double newBandwidth = ba.bandwidth().toDouble() + requestedBandwidth;
130 + freeRes.remove(ba);
131 + freeRes.add(new BandwidthResourceAllocation(
132 + Bandwidth.valueOf(newBandwidth)));
133 + break;
134 + case LAMBDA:
135 + checkState(freeRes.add(res));
136 + break;
137 + default:
138 + break;
139 + }
140 + }
141 + freeResources.put(link, freeRes);
142 + }
143 +
144 + @Override
145 + public Set<ResourceAllocation> getFreeResources(Link link) {
146 + checkNotNull(link);
147 + Set<ResourceAllocation> freeRes = freeResources.get(link);
148 + if (freeRes == null) {
149 + freeRes = readOriginalFreeResources(link);
150 + }
151 +
152 + return freeRes;
153 + }
154 +
155 + @Override
156 + public void allocateResources(LinkResourceAllocations allocations) {
157 + checkNotNull(allocations);
158 + linkResourceAllocationsMap.put(allocations.intendId(), allocations);
159 + for (Link link : allocations.links()) {
160 + subtractFreeResources(link, allocations);
161 + Set<LinkResourceAllocations> linkAllocs = allocatedResources.get(link);
162 + if (linkAllocs == null) {
163 + linkAllocs = new HashSet<>();
164 + }
165 + linkAllocs.add(allocations);
166 + allocatedResources.put(link, linkAllocs);
167 + }
168 + }
169 +
170 + @Override
171 + public void releaseResources(LinkResourceAllocations allocations) {
172 + checkNotNull(allocations);
173 + linkResourceAllocationsMap.remove(allocations);
174 + for (Link link : allocations.links()) {
175 + addFreeResources(link, allocations);
176 + Set<LinkResourceAllocations> linkAllocs = allocatedResources.get(link);
177 + if (linkAllocs == null) {
178 + log.error("Missing resource allocation.");
179 + } else {
180 + linkAllocs.remove(allocations);
181 + }
182 + allocatedResources.put(link, linkAllocs);
183 + }
184 + }
185 +
186 + @Override
187 + public LinkResourceAllocations getAllocations(IntentId intentId) {
188 + checkNotNull(intentId);
189 + return linkResourceAllocationsMap.get(intentId);
190 + }
191 +
192 + @Override
193 + public Iterable<LinkResourceAllocations> getAllocations(Link link) {
194 + checkNotNull(link);
195 + Set<LinkResourceAllocations> result = allocatedResources.get(link);
196 + if (result == null) {
197 + result = Collections.emptySet();
198 + }
199 + return Collections.unmodifiableSet(result);
200 + }
201 +
202 + @Override
203 + public Iterable<LinkResourceAllocations> getAllocations() {
204 + return Collections.unmodifiableCollection(linkResourceAllocationsMap.values());
205 + }
206 +
207 +}
...@@ -15,6 +15,22 @@ ...@@ -15,6 +15,22 @@
15 */ 15 */
16 package org.onlab.onos.provider.lldp.impl; 16 package org.onlab.onos.provider.lldp.impl;
17 17
18 +import static com.google.common.base.Preconditions.checkNotNull;
19 +import static java.util.concurrent.TimeUnit.MILLISECONDS;
20 +import static org.onlab.onos.net.MastershipRole.MASTER;
21 +import static org.onlab.onos.net.PortNumber.portNumber;
22 +import static org.onlab.onos.net.flow.DefaultTrafficTreatment.builder;
23 +import static org.slf4j.LoggerFactory.getLogger;
24 +
25 +import java.nio.ByteBuffer;
26 +import java.util.Collections;
27 +import java.util.HashMap;
28 +import java.util.HashSet;
29 +import java.util.Iterator;
30 +import java.util.Map;
31 +import java.util.Set;
32 +import java.util.concurrent.atomic.AtomicInteger;
33 +
18 import org.jboss.netty.util.Timeout; 34 import org.jboss.netty.util.Timeout;
19 import org.jboss.netty.util.TimerTask; 35 import org.jboss.netty.util.TimerTask;
20 import org.onlab.onos.mastership.MastershipService; 36 import org.onlab.onos.mastership.MastershipService;
...@@ -36,22 +52,6 @@ import org.onlab.packet.ONOSLLDP; ...@@ -36,22 +52,6 @@ import org.onlab.packet.ONOSLLDP;
36 import org.onlab.util.Timer; 52 import org.onlab.util.Timer;
37 import org.slf4j.Logger; 53 import org.slf4j.Logger;
38 54
39 -import java.nio.ByteBuffer;
40 -import java.util.Collections;
41 -import java.util.HashMap;
42 -import java.util.HashSet;
43 -import java.util.Iterator;
44 -import java.util.Map;
45 -import java.util.Set;
46 -import java.util.concurrent.atomic.AtomicInteger;
47 -
48 -import static com.google.common.base.Preconditions.checkNotNull;
49 -import static java.util.concurrent.TimeUnit.MILLISECONDS;
50 -import static org.onlab.onos.net.MastershipRole.MASTER;
51 -import static org.onlab.onos.net.PortNumber.portNumber;
52 -import static org.onlab.onos.net.flow.DefaultTrafficTreatment.builder;
53 -import static org.slf4j.LoggerFactory.getLogger;
54 -
55 /** 55 /**
56 * Run discovery process from a physical switch. Ports are initially labeled as 56 * Run discovery process from a physical switch. Ports are initially labeled as
57 * slow ports. When an LLDP is successfully received, label the remote port as 57 * slow ports. When an LLDP is successfully received, label the remote port as
...@@ -336,7 +336,7 @@ public class LinkDiscovery implements TimerTask { ...@@ -336,7 +336,7 @@ public class LinkDiscovery implements TimerTask {
336 private void sendProbes(Long portNumber) { 336 private void sendProbes(Long portNumber) {
337 // TODO: should have suppression port configuration, not by type 337 // TODO: should have suppression port configuration, not by type
338 if (device.type() != Device.Type.ROADM) { 338 if (device.type() != Device.Type.ROADM) {
339 - log.debug("Sending probes out to {}@{}", portNumber, device.id()); 339 + log.trace("Sending probes out to {}@{}", portNumber, device.id());
340 OutboundPacket pkt = this.createOutBoundLLDP(portNumber); 340 OutboundPacket pkt = this.createOutBoundLLDP(portNumber);
341 pktService.emit(pkt); 341 pktService.emit(pkt);
342 if (useBDDP) { 342 if (useBDDP) {
......
...@@ -23,6 +23,7 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; ...@@ -23,6 +23,7 @@ import org.apache.felix.scr.annotations.ReferenceCardinality;
23 import org.onlab.onos.net.Device; 23 import org.onlab.onos.net.Device;
24 import org.onlab.onos.net.DeviceId; 24 import org.onlab.onos.net.DeviceId;
25 import org.onlab.onos.net.MastershipRole; 25 import org.onlab.onos.net.MastershipRole;
26 +import org.onlab.onos.net.Port;
26 import org.onlab.onos.net.PortNumber; 27 import org.onlab.onos.net.PortNumber;
27 import org.onlab.onos.net.device.DefaultDeviceDescription; 28 import org.onlab.onos.net.device.DefaultDeviceDescription;
28 import org.onlab.onos.net.device.DefaultPortDescription; 29 import org.onlab.onos.net.device.DefaultPortDescription;
...@@ -43,14 +44,19 @@ import org.onlab.packet.ChassisId; ...@@ -43,14 +44,19 @@ import org.onlab.packet.ChassisId;
43 import org.projectfloodlight.openflow.protocol.OFFactory; 44 import org.projectfloodlight.openflow.protocol.OFFactory;
44 import org.projectfloodlight.openflow.protocol.OFPortConfig; 45 import org.projectfloodlight.openflow.protocol.OFPortConfig;
45 import org.projectfloodlight.openflow.protocol.OFPortDesc; 46 import org.projectfloodlight.openflow.protocol.OFPortDesc;
47 +import org.projectfloodlight.openflow.protocol.OFPortFeatures;
46 import org.projectfloodlight.openflow.protocol.OFPortState; 48 import org.projectfloodlight.openflow.protocol.OFPortState;
47 import org.projectfloodlight.openflow.protocol.OFPortStatus; 49 import org.projectfloodlight.openflow.protocol.OFPortStatus;
50 +import org.projectfloodlight.openflow.protocol.OFVersion;
51 +import org.projectfloodlight.openflow.types.PortSpeed;
48 import org.slf4j.Logger; 52 import org.slf4j.Logger;
49 53
50 import java.util.ArrayList; 54 import java.util.ArrayList;
51 import java.util.List; 55 import java.util.List;
52 56
53 import static org.onlab.onos.net.DeviceId.deviceId; 57 import static org.onlab.onos.net.DeviceId.deviceId;
58 +import static org.onlab.onos.net.Port.Type.COPPER;
59 +import static org.onlab.onos.net.Port.Type.FIBER;
54 import static org.onlab.onos.openflow.controller.Dpid.dpid; 60 import static org.onlab.onos.openflow.controller.Dpid.dpid;
55 import static org.onlab.onos.openflow.controller.Dpid.uri; 61 import static org.onlab.onos.openflow.controller.Dpid.uri;
56 import static org.slf4j.LoggerFactory.getLogger; 62 import static org.slf4j.LoggerFactory.getLogger;
...@@ -63,6 +69,7 @@ import static org.slf4j.LoggerFactory.getLogger; ...@@ -63,6 +69,7 @@ import static org.slf4j.LoggerFactory.getLogger;
63 public class OpenFlowDeviceProvider extends AbstractProvider implements DeviceProvider { 69 public class OpenFlowDeviceProvider extends AbstractProvider implements DeviceProvider {
64 70
65 private static final Logger LOG = getLogger(OpenFlowDeviceProvider.class); 71 private static final Logger LOG = getLogger(OpenFlowDeviceProvider.class);
72 + private static final long MBPS = 1_000 * 1_000;
66 73
67 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 74 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
68 protected DeviceProviderRegistry providerRegistry; 75 protected DeviceProviderRegistry providerRegistry;
...@@ -244,8 +251,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -244,8 +251,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
244 * @param ports the list of ports 251 * @param ports the list of ports
245 * @return list of portdescriptions 252 * @return list of portdescriptions
246 */ 253 */
247 - private List<PortDescription> buildPortDescriptions( 254 + private List<PortDescription> buildPortDescriptions(List<OFPortDesc> ports) {
248 - List<OFPortDesc> ports) {
249 final List<PortDescription> portDescs = new ArrayList<>(ports.size()); 255 final List<PortDescription> portDescs = new ArrayList<>(ports.size());
250 for (OFPortDesc port : ports) { 256 for (OFPortDesc port : ports) {
251 portDescs.add(buildPortDescription(port)); 257 portDescs.add(buildPortDescription(port));
...@@ -260,12 +266,25 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -260,12 +266,25 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
260 * @return portDescription for the port. 266 * @return portDescription for the port.
261 */ 267 */
262 private PortDescription buildPortDescription(OFPortDesc port) { 268 private PortDescription buildPortDescription(OFPortDesc port) {
263 - final PortNumber portNo = PortNumber.portNumber(port.getPortNo().getPortNumber()); 269 + PortNumber portNo = PortNumber.portNumber(port.getPortNo().getPortNumber());
264 - final boolean enabled = !port.getState().contains(OFPortState.LINK_DOWN) && 270 + boolean enabled =
271 + !port.getState().contains(OFPortState.LINK_DOWN) &&
265 !port.getConfig().contains(OFPortConfig.PORT_DOWN); 272 !port.getConfig().contains(OFPortConfig.PORT_DOWN);
266 - return new DefaultPortDescription(portNo, enabled); 273 + Port.Type type = port.getCurr().contains(OFPortFeatures.PF_FIBER) ? FIBER : COPPER;
274 + return new DefaultPortDescription(portNo, enabled, type, portSpeed(port));
267 } 275 }
268 276
277 + private long portSpeed(OFPortDesc port) {
278 + if (port.getVersion() == OFVersion.OF_13) {
279 + return port.getCurrSpeed() / MBPS;
280 + }
281 +
282 + PortSpeed portSpeed = PortSpeed.SPEED_NONE;
283 + for (OFPortFeatures feat : port.getCurr()) {
284 + portSpeed = PortSpeed.max(portSpeed, feat.getPortSpeed());
285 + }
286 + return portSpeed.getSpeedBps() / MBPS;
287 + }
269 } 288 }
270 289
271 } 290 }
......
...@@ -6,4 +6,4 @@ ...@@ -6,4 +6,4 @@
6 [ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 6 [ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
7 . $ONOS_ROOT/tools/build/envDefaults 7 . $ONOS_ROOT/tools/build/envDefaults
8 8
9 -cd $ONOS_ROOT && mvn clean install && cd docs && mvn javadoc:aggregate 9 +cd $ONOS_ROOT && mvn clean install "$@" && cd docs && mvn javadoc:aggregate
......
...@@ -34,6 +34,7 @@ alias mci='mvn clean install' ...@@ -34,6 +34,7 @@ alias mci='mvn clean install'
34 34
35 # Short-hand for ONOS build, package and test. 35 # Short-hand for ONOS build, package and test.
36 alias ob='onos-build' 36 alias ob='onos-build'
37 +alias obi='onos-build -Dmaven.test.failure.ignore=true'
37 alias obs='onos-build-selective' 38 alias obs='onos-build-selective'
38 alias op='onos-package' 39 alias op='onos-package'
39 alias ot='onos-test' 40 alias ot='onos-test'
......
1 # Local VirtualBox-based single ONOS instance & ONOS mininet box 1 # Local VirtualBox-based single ONOS instance & ONOS mininet box
2 2
3 -export ONOS_CELL="cbench"
4 -
5 export ONOS_NIC=192.168.56.* 3 export ONOS_NIC=192.168.56.*
6 export OC1="192.168.56.103" 4 export OC1="192.168.56.103"
7 export OCN="192.168.56.103" 5 export OCN="192.168.56.103"
......
1 # Local VirtualBox-based ONOS instances 1,2 & ONOS mininet box 1 # Local VirtualBox-based ONOS instances 1,2 & ONOS mininet box
2 2
3 -export ONOS_CELL="local"
4 -
5 export ONOS_NIC=192.168.56.* 3 export ONOS_NIC=192.168.56.*
6 export OC1="192.168.56.101" 4 export OC1="192.168.56.101"
7 export OC2="192.168.56.102" 5 export OC2="192.168.56.102"
......
1 # ProxMox-based cell of ONOS instance; no mininet-box 1 # ProxMox-based cell of ONOS instance; no mininet-box
2 2
3 -export ONOS_CELL="office"
4 -
5 export ONOS_NIC="10.1.10.*" 3 export ONOS_NIC="10.1.10.*"
6 export OC1="10.1.10.223" 4 export OC1="10.1.10.223"
7 export OCI="${OC1}" 5 export OCI="${OC1}"
......
1 # ProxMox-based cell of ONOS instances 1,2 & ONOS mininet box 1 # ProxMox-based cell of ONOS instances 1,2 & ONOS mininet box
2 2
3 -export ONOS_CELL="prox"
4 -
5 export ONOS_NIC="10.1.9.*" 3 export ONOS_NIC="10.1.9.*"
6 export OC1="10.1.9.94" 4 export OC1="10.1.9.94"
7 export OC2="10.1.9.82" 5 export OC2="10.1.9.82"
......
1 # Local VirtualBox-based single ONOS instance & ONOS mininet box 1 # Local VirtualBox-based single ONOS instance & ONOS mininet box
2 2
3 -export ONOS_CELL="single"
4 -
5 export ONOS_NIC=192.168.56.* 3 export ONOS_NIC=192.168.56.*
6 export OC1="192.168.56.101" 4 export OC1="192.168.56.101"
7 export OCN="192.168.56.103" 5 export OCN="192.168.56.103"
......
1 # Local VirtualBox-based ONOS instances 1,2,3 & ONOS mininet box 1 # Local VirtualBox-based ONOS instances 1,2,3 & ONOS mininet box
2 2
3 -export ONOS_CELL="triple"
4 -
5 export ONOS_NIC=192.168.56.* 3 export ONOS_NIC=192.168.56.*
6 export OC1="192.168.56.101" 4 export OC1="192.168.56.101"
7 export OC2="192.168.56.102" 5 export OC2="192.168.56.102"
......
...@@ -3,28 +3,33 @@ ...@@ -3,28 +3,33 @@
3 { 3 {
4 "uri": "of:0000ffffffffff01", "mac": "ffffffffffff01", "type": "ROADM", 4 "uri": "of:0000ffffffffff01", "mac": "ffffffffffff01", "type": "ROADM",
5 "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", "name": "ROADM1", 5 "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", "name": "ROADM1",
6 - "annotations": { "latitude": 37.6, "longitude": 122.3, "optical.regens": 0 } 6 + "annotations": { "latitude": 37.6, "longitude": 122.3, "optical.regens": 0 },
7 + "ports": [ { "port": 10, "speed": 100000, "type": "FIBER" }, { "port": 20, "speed": 0, "type": "FIBER" } ]
7 }, 8 },
8 { 9 {
9 "uri": "of:0000ffffffffff02", "mac": "ffffffffffff02", "type": "ROADM", 10 "uri": "of:0000ffffffffff02", "mac": "ffffffffffff02", "type": "ROADM",
10 "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", "name": "ROADM2", 11 "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", "name": "ROADM2",
11 - "annotations": { "latitude": 37.3, "longitude": 121.9, "optical.regens": 0 } 12 + "annotations": { "latitude": 37.3, "longitude": 121.9, "optical.regens": 0 },
13 + "ports": [ { "port": 11, "speed": 100000, "type": "FIBER" }, { "port": 21, "speed": 0, "type": "FIBER" } ]
12 }, 14 },
13 { 15 {
14 "uri": "of:0000ffffffffff03", "mac": "ffffffffffff03", "type": "ROADM", 16 "uri": "of:0000ffffffffff03", "mac": "ffffffffffff03", "type": "ROADM",
15 "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", "name": "ROADM3", 17 "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", "name": "ROADM3",
16 - "annotations": { "latitude": 33.9, "longitude": 118.4, "optical.regens": 2 } 18 + "annotations": { "latitude": 33.9, "longitude": 118.4, "optical.regens": 2 },
19 + "ports": [ { "port": 30, "speed": 0, "type": "FIBER" }, { "port": 31, "speed": 0, "type": "FIBER" } ]
17 }, 20 },
18 21
19 { 22 {
20 - "uri": "of:0000ffffffff0001", "mac": "ffffffffff0003", "type": "SWITCH", 23 + "uri": "of:0000ffffffff0001", "mac": "ffffffffff0001", "type": "SWITCH",
21 "mfr": "Linc", "hw": "PK", "sw": "?", "serial": "?", "name": "ROUTER1", 24 "mfr": "Linc", "hw": "PK", "sw": "?", "serial": "?", "name": "ROUTER1",
22 - "annotations": { "latitude": 37.6, "longitude": 122.3 } 25 + "annotations": { "latitude": 37.6, "longitude": 122.3 },
26 + "ports": [ { "port": 1, "speed": 10000, "type": "COPPER" }, { "port": 2, "speed": 100000, "type": "FIBER" } ]
23 }, 27 },
24 { 28 {
25 "uri": "of:0000ffffffff0002", "mac": "ffffffffff0002", "type": "SWITCH", 29 "uri": "of:0000ffffffff0002", "mac": "ffffffffff0002", "type": "SWITCH",
26 "mfr": "Linc", "hw": "PK", "sw": "?", "serial": "?", "name": "ROUTER2", 30 "mfr": "Linc", "hw": "PK", "sw": "?", "serial": "?", "name": "ROUTER2",
27 - "annotations": { "latitude": 37.3, "longitude": 121.9 } 31 + "annotations": { "latitude": 37.3, "longitude": 121.9 },
32 + "ports": [ { "port": 1, "speed": 10000, "type": "COPPER" }, { "port": 2, "speed": 100000, "type": "FIBER" } ]
28 } 33 }
29 ], 34 ],
30 35
...@@ -36,10 +41,8 @@ ...@@ -36,10 +41,8 @@
36 { "src": "of:0000ffffffff0002/2", "dst": "of:0000ffffffffff02/11", "type": "OPTICAL", "annotations": { "bandwidth": 100000, "optical.type": "cross-connect" } } 41 { "src": "of:0000ffffffff0002/2", "dst": "of:0000ffffffffff02/11", "type": "OPTICAL", "annotations": { "bandwidth": 100000, "optical.type": "cross-connect" } }
37 ], 42 ],
38 43
39 - "Xhosts" : [ 44 + "hosts" : [
40 - { "mac": "a0:00:00:00:00:11", "vlan": -1, "location": "of:0000ffffffff0001/11", "ip": "1.2.3.4" }, 45 + { "mac": "00:00:00:00:00:01", "vlan": -1, "location": "of:0000ffffffff0001/1", "ip": "10.0.0.1" },
41 - { "mac": "a0:00:00:00:00:12", "vlan": -1, "location": "of:0000ffffffff0001/12", "ip": "1.2.3.5" }, 46 + { "mac": "00:00:00:00:00:02", "vlan": -1, "location": "of:0000ffffffff0002/1", "ip": "10.0.0.2" }
42 - { "mac": "a0:00:00:00:00:21", "vlan": -1, "location": "of:0000ffffffff0002/11", "ip": "2.2.3.4" },
43 - { "mac": "a0:00:00:00:00:22", "vlan": -1, "location": "of:0000ffffffff0002/12", "ip": "2.2.3.5" }
44 ] 47 ]
45 } 48 }
...\ No newline at end of file ...\ No newline at end of file
......
This diff is collapsed. Click to expand it.
...@@ -101,20 +101,6 @@ public final class Ip4Prefix { ...@@ -101,20 +101,6 @@ public final class Ip4Prefix {
101 return this.address.toString() + "/" + this.prefixLen; 101 return this.address.toString() + "/" + this.prefixLen;
102 } 102 }
103 103
104 - /**
105 - * Compares the value of two Ip4Prefix objects.
106 - * <p/>
107 - * Note the value of the IPv4 address is compared directly between the
108 - * objects, and must match exactly for the objects to be considered equal.
109 - * This may result in objects which represent the same IP prefix being
110 - * classified as unequal, because the unsignificant bits of the address
111 - * field don't match (the bits to the right of the prefix length).
112 - * <p/>
113 - * TODO Change this behavior so that objects that represent the same prefix
114 - * are classified as equal according to this equals method.
115 - *
116 - * @see Object#equals(Object)
117 - */
118 @Override 104 @Override
119 public boolean equals(Object other) { 105 public boolean equals(Object other) {
120 if (other == this) { 106 if (other == this) {
......
...@@ -101,20 +101,6 @@ public final class Ip6Prefix { ...@@ -101,20 +101,6 @@ public final class Ip6Prefix {
101 return this.address.toString() + "/" + this.prefixLen; 101 return this.address.toString() + "/" + this.prefixLen;
102 } 102 }
103 103
104 - /**
105 - * Compares the value of two Ip6Prefix objects.
106 - * <p/>
107 - * Note the value of the IPv6 address is compared directly between the
108 - * objects, and must match exactly for the objects to be considered equal.
109 - * This may result in objects which represent the same IP prefix being
110 - * classified as unequal, because the unsignificant bits of the address
111 - * field don't match (the bits to the right of the prefix length).
112 - * <p/>
113 - * TODO Change this behavior so that objects that represent the same prefix
114 - * are classified as equal according to this equals method.
115 - *
116 - * @see Object#equals(Object)
117 - */
118 @Override 104 @Override
119 public boolean equals(Object other) { 105 public boolean equals(Object other) {
120 if (other == this) { 106 if (other == this) {
......
...@@ -17,6 +17,8 @@ package org.onlab.packet; ...@@ -17,6 +17,8 @@ package org.onlab.packet;
17 17
18 import java.nio.ByteBuffer; 18 import java.nio.ByteBuffer;
19 import java.util.Arrays; 19 import java.util.Arrays;
20 +import java.util.Objects;
21 +import static com.google.common.base.Preconditions.checkNotNull;
20 22
21 /** 23 /**
22 * A class representing an IPv4 address. 24 * A class representing an IPv4 address.
...@@ -37,35 +39,68 @@ public final class IpAddress implements Comparable<IpAddress> { ...@@ -37,35 +39,68 @@ public final class IpAddress implements Comparable<IpAddress> {
37 /** 39 /**
38 * Constructor for given IP address version and address octets. 40 * Constructor for given IP address version and address octets.
39 * 41 *
40 - * @param ver the IP address version 42 + * @param value the IP address value stored in network byte order
41 - * @param octets the IP address octets 43 + * (i.e., the most significant byte first)
44 + * @param value the IP address value
42 */ 45 */
43 - private IpAddress(Version ver, byte[] octets) { 46 + private IpAddress(Version version, byte[] value) {
44 - this.version = ver; 47 + checkNotNull(value);
45 - this.octets = Arrays.copyOf(octets, INET_BYTE_LENGTH); 48 +
49 + this.version = version;
50 + this.octets = Arrays.copyOf(value, INET_BYTE_LENGTH);
51 + }
52 +
53 + /**
54 + * Converts an integer into an IPv4 address.
55 + *
56 + * @param value an integer representing an IPv4 value
57 + * @return an IP address
58 + */
59 + public static IpAddress valueOf(int value) {
60 + byte[] bytes =
61 + ByteBuffer.allocate(INET_BYTE_LENGTH).putInt(value).array();
62 + return new IpAddress(Version.INET, bytes);
46 } 63 }
47 64
48 /** 65 /**
49 * Converts a byte array into an IP address. 66 * Converts a byte array into an IP address.
50 * 67 *
51 - * @param address the IP address value stored in network byte order 68 + * @param value the IP address value stored in network byte order
52 * (i.e., the most significant byte first) 69 * (i.e., the most significant byte first)
53 * @return an IP address 70 * @return an IP address
54 */ 71 */
55 - public static IpAddress valueOf(byte[] address) { 72 + public static IpAddress valueOf(byte[] value) {
56 - return new IpAddress(Version.INET, address); 73 + return new IpAddress(Version.INET, value);
57 } 74 }
58 75
59 /** 76 /**
60 - * Converts an integer into an IPv4 address. 77 + * Converts a byte array and a given offset from the beginning of the
78 + * array into an IP address.
79 + * <p/>
80 + * The IP address is stored in network byte order (i.e., the most
81 + * significant byte first).
61 * 82 *
62 - * @param address an integer representing an IPv4 value 83 + * @param value the value to use
84 + * @param offset the offset in bytes from the beginning of the byte array
63 * @return an IP address 85 * @return an IP address
64 */ 86 */
65 - public static IpAddress valueOf(int address) { 87 + public static IpAddress valueOf(byte[] value, int offset) {
66 - byte[] bytes = 88 + // Verify the arguments
67 - ByteBuffer.allocate(INET_BYTE_LENGTH).putInt(address).array(); 89 + if ((offset < 0) || (offset + INET_BYTE_LENGTH > value.length)) {
68 - return new IpAddress(Version.INET, bytes); 90 + String msg;
91 + if (value.length < INET_BYTE_LENGTH) {
92 + msg = "Invalid IPv4 address array: array length: " +
93 + value.length + ". Must be at least " + INET_BYTE_LENGTH;
94 + } else {
95 + msg = "Invalid IPv4 address array: array offset: " +
96 + offset + ". Must be in the interval [0, " +
97 + (value.length - INET_BYTE_LENGTH) + "]";
98 + }
99 + throw new IllegalArgumentException(msg);
100 + }
101 +
102 + byte[] bc = Arrays.copyOfRange(value, offset, value.length);
103 + return IpAddress.valueOf(bc);
69 } 104 }
70 105
71 /** 106 /**
...@@ -77,8 +112,9 @@ public final class IpAddress implements Comparable<IpAddress> { ...@@ -77,8 +112,9 @@ public final class IpAddress implements Comparable<IpAddress> {
77 public static IpAddress valueOf(String address) { 112 public static IpAddress valueOf(String address) {
78 final String[] net = address.split("\\."); 113 final String[] net = address.split("\\.");
79 if (net.length != INET_BYTE_LENGTH) { 114 if (net.length != INET_BYTE_LENGTH) {
80 - throw new IllegalArgumentException("Malformed IP address string; " 115 + String msg = "Malformed IPv4 address string; " +
81 - + "Address must have four decimal values separated by dots (.)"); 116 + "Address must have four decimal values separated by dots (.)";
117 + throw new IllegalArgumentException(msg);
82 } 118 }
83 final byte[] bytes = new byte[INET_BYTE_LENGTH]; 119 final byte[] bytes = new byte[INET_BYTE_LENGTH];
84 for (int i = 0; i < INET_BYTE_LENGTH; i++) { 120 for (int i = 0; i < INET_BYTE_LENGTH; i++) {
...@@ -115,6 +151,48 @@ public final class IpAddress implements Comparable<IpAddress> { ...@@ -115,6 +151,48 @@ public final class IpAddress implements Comparable<IpAddress> {
115 return bb.getInt(); 151 return bb.getInt();
116 } 152 }
117 153
154 + /**
155 + * Creates an IP network mask prefix.
156 + *
157 + * @param prefixLen the length of the mask prefix. Must be in the interval
158 + * [0, 32] for IPv4
159 + * @return a new IP address that contains a mask prefix of the
160 + * specified length
161 + */
162 + public static IpAddress makeMaskPrefix(int prefixLen) {
163 + // Verify the prefix length
164 + if ((prefixLen < 0) || (prefixLen > INET_BIT_LENGTH)) {
165 + final String msg = "Invalid IPv4 prefix length: " + prefixLen +
166 + ". Must be in the interval [0, 32].";
167 + throw new IllegalArgumentException(msg);
168 + }
169 +
170 + long v = (0xffffffffL << (INET_BIT_LENGTH - prefixLen)) & 0xffffffffL;
171 + return IpAddress.valueOf((int) v);
172 + }
173 +
174 + /**
175 + * Creates an IP address by masking it with a network mask of given
176 + * mask length.
177 + *
178 + * @param addr the address to mask
179 + * @param prefixLen the length of the mask prefix. Must be in the interval
180 + * [0, 32] for IPv4
181 + * @return a new IP address that is masked with a mask prefix of the
182 + * specified length
183 + */
184 + public static IpAddress makeMaskedAddress(final IpAddress addr,
185 + int prefixLen) {
186 + IpAddress mask = IpAddress.makeMaskPrefix(prefixLen);
187 + byte[] net = new byte[INET_BYTE_LENGTH];
188 +
189 + // Mask each byte
190 + for (int i = 0; i < INET_BYTE_LENGTH; i++) {
191 + net[i] = (byte) (addr.octets[i] & mask.octets[i]);
192 + }
193 + return IpAddress.valueOf(net);
194 + }
195 +
118 @Override 196 @Override
119 public int compareTo(IpAddress o) { 197 public int compareTo(IpAddress o) {
120 Long lv = ((long) this.toInt()) & 0xffffffffL; 198 Long lv = ((long) this.toInt()) & 0xffffffffL;
...@@ -124,32 +202,20 @@ public final class IpAddress implements Comparable<IpAddress> { ...@@ -124,32 +202,20 @@ public final class IpAddress implements Comparable<IpAddress> {
124 202
125 @Override 203 @Override
126 public int hashCode() { 204 public int hashCode() {
127 - final int prime = 31; 205 + return Objects.hash(version, Arrays.hashCode(octets));
128 - int result = 1;
129 - result = prime * result + Arrays.hashCode(octets);
130 - result = prime * result + ((version == null) ? 0 : version.hashCode());
131 - return result;
132 } 206 }
133 207
134 @Override 208 @Override
135 public boolean equals(Object obj) { 209 public boolean equals(Object obj) {
136 - if (this == obj) { 210 + if (obj == this) {
137 return true; 211 return true;
138 } 212 }
139 - if (obj == null) { 213 + if ((obj == null) || (getClass() != obj.getClass())) {
140 - return false;
141 - }
142 - if (getClass() != obj.getClass()) {
143 return false; 214 return false;
144 } 215 }
145 IpAddress other = (IpAddress) obj; 216 IpAddress other = (IpAddress) obj;
146 - if (!Arrays.equals(octets, other.octets)) { 217 + return (version == other.version) &&
147 - return false; 218 + Arrays.equals(octets, other.octets);
148 - }
149 - if (version != other.version) {
150 - return false;
151 - }
152 - return true;
153 } 219 }
154 220
155 @Override 221 @Override
......
...@@ -19,17 +19,21 @@ import com.fasterxml.jackson.databind.JsonNode; ...@@ -19,17 +19,21 @@ import com.fasterxml.jackson.databind.JsonNode;
19 import org.onlab.onos.net.ConnectPoint; 19 import org.onlab.onos.net.ConnectPoint;
20 import org.onlab.onos.net.DefaultAnnotations; 20 import org.onlab.onos.net.DefaultAnnotations;
21 import org.onlab.onos.net.Device; 21 import org.onlab.onos.net.Device;
22 +import org.onlab.onos.net.DeviceId;
22 import org.onlab.onos.net.Host; 23 import org.onlab.onos.net.Host;
23 import org.onlab.onos.net.HostId; 24 import org.onlab.onos.net.HostId;
24 import org.onlab.onos.net.HostLocation; 25 import org.onlab.onos.net.HostLocation;
25 import org.onlab.onos.net.Link; 26 import org.onlab.onos.net.Link;
26 import org.onlab.onos.net.MastershipRole; 27 import org.onlab.onos.net.MastershipRole;
28 +import org.onlab.onos.net.Port;
27 import org.onlab.onos.net.SparseAnnotations; 29 import org.onlab.onos.net.SparseAnnotations;
28 import org.onlab.onos.net.device.DefaultDeviceDescription; 30 import org.onlab.onos.net.device.DefaultDeviceDescription;
31 +import org.onlab.onos.net.device.DefaultPortDescription;
29 import org.onlab.onos.net.device.DeviceDescription; 32 import org.onlab.onos.net.device.DeviceDescription;
30 import org.onlab.onos.net.device.DeviceProvider; 33 import org.onlab.onos.net.device.DeviceProvider;
31 import org.onlab.onos.net.device.DeviceProviderRegistry; 34 import org.onlab.onos.net.device.DeviceProviderRegistry;
32 import org.onlab.onos.net.device.DeviceProviderService; 35 import org.onlab.onos.net.device.DeviceProviderService;
36 +import org.onlab.onos.net.device.PortDescription;
33 import org.onlab.onos.net.host.DefaultHostDescription; 37 import org.onlab.onos.net.host.DefaultHostDescription;
34 import org.onlab.onos.net.host.HostProvider; 38 import org.onlab.onos.net.host.HostProvider;
35 import org.onlab.onos.net.host.HostProviderRegistry; 39 import org.onlab.onos.net.host.HostProviderRegistry;
...@@ -45,7 +49,9 @@ import org.onlab.packet.MacAddress; ...@@ -45,7 +49,9 @@ import org.onlab.packet.MacAddress;
45 import org.onlab.packet.VlanId; 49 import org.onlab.packet.VlanId;
46 50
47 import java.net.URI; 51 import java.net.URI;
52 +import java.util.ArrayList;
48 import java.util.Iterator; 53 import java.util.Iterator;
54 +import java.util.List;
49 55
50 import static com.google.common.base.Preconditions.checkNotNull; 56 import static com.google.common.base.Preconditions.checkNotNull;
51 import static org.onlab.onos.net.DeviceId.deviceId; 57 import static org.onlab.onos.net.DeviceId.deviceId;
...@@ -120,7 +126,30 @@ class ConfigProvider implements DeviceProvider, LinkProvider, HostProvider { ...@@ -120,7 +126,30 @@ class ConfigProvider implements DeviceProvider, LinkProvider, HostProvider {
120 DeviceDescription desc = 126 DeviceDescription desc =
121 new DefaultDeviceDescription(uri, type, mfr, hw, sw, serial, 127 new DefaultDeviceDescription(uri, type, mfr, hw, sw, serial,
122 cid, annotations); 128 cid, annotations);
123 - dps.deviceConnected(deviceId(uri), desc); 129 + DeviceId deviceId = deviceId(uri);
130 + dps.deviceConnected(deviceId, desc);
131 +
132 + JsonNode ports = node.get("ports");
133 + if (ports != null) {
134 + parsePorts(dps, deviceId, ports);
135 + }
136 + }
137 +
138 + // Parses the given node with list of device ports.
139 + private void parsePorts(DeviceProviderService dps, DeviceId deviceId, JsonNode nodes) {
140 + List<PortDescription> ports = new ArrayList<>();
141 + for (JsonNode node : nodes) {
142 + ports.add(parsePort(node));
143 + }
144 + dps.updatePorts(deviceId, ports);
145 + }
146 +
147 + // Parses the given node with port information.
148 + private PortDescription parsePort(JsonNode node) {
149 + Port.Type type = Port.Type.valueOf(node.path("type").asText("COPPER"));
150 + return new DefaultPortDescription(portNumber(node.path("port").asLong(0)),
151 + node.path("enabled").asBoolean(true),
152 + type, node.path("speed").asLong(1_000));
124 } 153 }
125 154
126 // Parses the given JSON and provides links as configured. 155 // Parses the given JSON and provides links as configured.
......
...@@ -18,9 +18,12 @@ package org.onlab.onos.gui; ...@@ -18,9 +18,12 @@ package org.onlab.onos.gui;
18 import com.fasterxml.jackson.databind.ObjectMapper; 18 import com.fasterxml.jackson.databind.ObjectMapper;
19 import com.fasterxml.jackson.databind.node.ArrayNode; 19 import com.fasterxml.jackson.databind.node.ArrayNode;
20 import com.fasterxml.jackson.databind.node.ObjectNode; 20 import com.fasterxml.jackson.databind.node.ObjectNode;
21 +import org.onlab.onos.net.Annotations;
21 import org.onlab.onos.net.ConnectPoint; 22 import org.onlab.onos.net.ConnectPoint;
22 import org.onlab.onos.net.Device; 23 import org.onlab.onos.net.Device;
24 +import org.onlab.onos.net.DeviceId;
23 import org.onlab.onos.net.Host; 25 import org.onlab.onos.net.Host;
26 +import org.onlab.onos.net.HostId;
24 import org.onlab.onos.net.HostLocation; 27 import org.onlab.onos.net.HostLocation;
25 import org.onlab.onos.net.Link; 28 import org.onlab.onos.net.Link;
26 import org.onlab.onos.net.device.DeviceService; 29 import org.onlab.onos.net.device.DeviceService;
...@@ -35,6 +38,7 @@ import org.onlab.packet.MacAddress; ...@@ -35,6 +38,7 @@ import org.onlab.packet.MacAddress;
35 import org.onlab.rest.BaseResource; 38 import org.onlab.rest.BaseResource;
36 39
37 import javax.ws.rs.GET; 40 import javax.ws.rs.GET;
41 +import javax.ws.rs.PathParam;
38 import javax.ws.rs.Produces; 42 import javax.ws.rs.Produces;
39 import javax.ws.rs.core.Response; 43 import javax.ws.rs.core.Response;
40 import java.util.HashMap; 44 import java.util.HashMap;
...@@ -43,12 +47,17 @@ import java.util.Iterator; ...@@ -43,12 +47,17 @@ import java.util.Iterator;
43 import java.util.Map; 47 import java.util.Map;
44 import java.util.Set; 48 import java.util.Set;
45 49
50 +import static org.onlab.onos.net.DeviceId.deviceId;
51 +import static org.onlab.onos.net.HostId.hostId;
52 +
46 /** 53 /**
47 * Topology viewer resource. 54 * Topology viewer resource.
48 */ 55 */
49 @javax.ws.rs.Path("topology") 56 @javax.ws.rs.Path("topology")
50 public class TopologyResource extends BaseResource { 57 public class TopologyResource extends BaseResource {
51 58
59 + private static final String HOST_SEP = "/";
60 +
52 @javax.ws.rs.Path("/graph") 61 @javax.ws.rs.Path("/graph")
53 @GET 62 @GET
54 @Produces("application/json") 63 @Produces("application/json")
...@@ -70,6 +79,66 @@ public class TopologyResource extends BaseResource { ...@@ -70,6 +79,66 @@ public class TopologyResource extends BaseResource {
70 return Response.ok(rootNode.toString()).build(); 79 return Response.ok(rootNode.toString()).build();
71 } 80 }
72 81
82 + @javax.ws.rs.Path("/graph/{id}")
83 + @GET
84 + @Produces("application/json")
85 + public Response details(@PathParam("id") String id) {
86 + if (id.contains(HOST_SEP)) {
87 + return hostDetails(hostId(id));
88 + }
89 + return deviceDetails(deviceId(id));
90 + }
91 +
92 + // Returns device details response.
93 + private Response deviceDetails(DeviceId deviceId) {
94 + DeviceService deviceService = get(DeviceService.class);
95 + Device device = deviceService.getDevice(deviceId);
96 + Annotations annot = device.annotations();
97 + int portCount = deviceService.getPorts(deviceId).size();
98 + ObjectNode r = json(deviceId.toString(),
99 + device.type().toString().toLowerCase(),
100 + new Prop("Name", annot.value("name")),
101 + new Prop("Vendor", device.manufacturer()),
102 + new Prop("H/W Version", device.hwVersion()),
103 + new Prop("S/W Version", device.swVersion()),
104 + new Prop("S/W Version", device.serialNumber()),
105 + new Separator(),
106 + new Prop("Latitude", annot.value("latitude")),
107 + new Prop("Longitude", annot.value("longitude")),
108 + new Prop("Ports", Integer.toString(portCount)));
109 + return Response.ok(r.toString()).build();
110 + }
111 +
112 + // Returns host details response.
113 + private Response hostDetails(HostId hostId) {
114 + HostService hostService = get(HostService.class);
115 + Host host = hostService.getHost(hostId);
116 + Annotations annot = host.annotations();
117 + ObjectNode r = json(hostId.toString(), "host",
118 + new Prop("MAC", host.mac().toString()),
119 + new Prop("IP", host.ipAddresses().toString()),
120 + new Separator(),
121 + new Prop("Latitude", annot.value("latitude")),
122 + new Prop("Longitude", annot.value("longitude")));
123 + return Response.ok(r.toString()).build();
124 + }
125 +
126 + // Produces JSON property details.
127 + private ObjectNode json(String id, String type, Prop... props) {
128 + ObjectMapper mapper = new ObjectMapper();
129 + ObjectNode result = mapper.createObjectNode()
130 + .put("id", id).put("type", type);
131 + ObjectNode pnode = mapper.createObjectNode();
132 + ArrayNode porder = mapper.createArrayNode();
133 + for (Prop p : props) {
134 + porder.add(p.key);
135 + pnode.put(p.key, p.value);
136 + }
137 + result.set("propOrder", porder);
138 + result.set("props", pnode);
139 + return result;
140 + }
141 +
73 // Encodes all infrastructure devices. 142 // Encodes all infrastructure devices.
74 private ArrayNode getDevices(ObjectMapper mapper, DeviceService deviceService, 143 private ArrayNode getDevices(ObjectMapper mapper, DeviceService deviceService,
75 TopologyGraph graph) { 144 TopologyGraph graph) {
...@@ -209,4 +278,20 @@ public class TopologyResource extends BaseResource { ...@@ -209,4 +278,20 @@ public class TopologyResource extends BaseResource {
209 return cp.elementId().toString(); 278 return cp.elementId().toString();
210 } 279 }
211 280
281 + // Auxiliary key/value carrier.
282 + private class Prop {
283 + private final String key;
284 + private final String value;
285 +
286 + protected Prop(String key, String value) {
287 + this.key = key;
288 + this.value = value;
289 + }
290 + }
291 +
292 + private class Separator extends Prop {
293 + protected Separator() {
294 + super("-", "");
295 + }
296 + }
212 } 297 }
......

74.1 KB | W: | H:

37.7 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
39 <body> 39 <body>
40 <div id="frame"> 40 <div id="frame">
41 <div id="mast"> 41 <div id="mast">
42 - <img id="logo" src="img/onos-logo.png" width="60" height="38"> 42 + <img id="logo" src="img/onos-logo.png">
43 <span class="title">Open Network Operating System</span> 43 <span class="title">Open Network Operating System</span>
44 <span id="displayModes" class="right"> 44 <span id="displayModes" class="right">
45 <span id="showAll" class="radio active">All Layers</span> 45 <span id="showAll" class="radio active">All Layers</span>
......
...@@ -59,54 +59,72 @@ ...@@ -59,54 +59,72 @@
59 "src": "of:0000000000000001", 59 "src": "of:0000000000000001",
60 "dst": "of:0000000000000002", 60 "dst": "of:0000000000000002",
61 "type": "optical", 61 "type": "optical",
62 + "srcPort": 1,
63 + "dstPort": 2,
62 "linkWidth": 1.5 64 "linkWidth": 1.5
63 }, 65 },
64 { 66 {
65 "src": "of:0000000000000001", 67 "src": "of:0000000000000001",
66 "dst": "of:0000000000000003", 68 "dst": "of:0000000000000003",
67 "type": "optical", 69 "type": "optical",
70 + "srcPort": 2,
71 + "dstPort": 5,
68 "linkWidth": 1.5 72 "linkWidth": 1.5
69 }, 73 },
70 { 74 {
71 "src": "of:0000000000000001", 75 "src": "of:0000000000000001",
72 "dst": "of:0000000000000004", 76 "dst": "of:0000000000000004",
73 "type": "optical", 77 "type": "optical",
78 + "srcPort": 3,
79 + "dstPort": 2,
74 "linkWidth": 1.5 80 "linkWidth": 1.5
75 }, 81 },
76 { 82 {
77 "src": "of:0000000000000002", 83 "src": "of:0000000000000002",
78 "dst": "of:0000000000000003", 84 "dst": "of:0000000000000003",
79 "type": "optical", 85 "type": "optical",
86 + "srcPort": 3,
87 + "dstPort": 4,
80 "linkWidth": 1.5 88 "linkWidth": 1.5
81 }, 89 },
82 { 90 {
83 "src": "of:0000000000000002", 91 "src": "of:0000000000000002",
84 "dst": "of:0000000000000004", 92 "dst": "of:0000000000000004",
85 "type": "optical", 93 "type": "optical",
94 + "srcPort": 4,
95 + "dstPort": 1,
86 "linkWidth": 1.5 96 "linkWidth": 1.5
87 }, 97 },
88 { 98 {
89 "src": "of:0000000000000003", 99 "src": "of:0000000000000003",
90 "dst": "of:0000000000000004", 100 "dst": "of:0000000000000004",
91 "type": "optical", 101 "type": "optical",
102 + "srcPort": 3,
103 + "dstPort": 3,
92 "linkWidth": 1.5 104 "linkWidth": 1.5
93 }, 105 },
94 { 106 {
95 "src": "of:0000000000000013", 107 "src": "of:0000000000000013",
96 "dst": "of:0000000000000003", 108 "dst": "of:0000000000000003",
97 "type": "direct", 109 "type": "direct",
110 + "srcPort": 1,
111 + "dstPort": 7,
98 "linkWidth": 1.0 112 "linkWidth": 1.0
99 }, 113 },
100 { 114 {
101 "src": "of:0000000000000012", 115 "src": "of:0000000000000012",
102 "dst": "of:0000000000000002", 116 "dst": "of:0000000000000002",
103 "type": "direct", 117 "type": "direct",
118 + "srcPort": 1,
119 + "dstPort": 9,
104 "linkWidth": 1.0 120 "linkWidth": 1.0
105 }, 121 },
106 { 122 {
107 "src": "of:0000000000000011", 123 "src": "of:0000000000000011",
108 "dst": "of:0000000000000001", 124 "dst": "of:0000000000000001",
109 "type": "direct", 125 "type": "direct",
126 + "srcPort": 1,
127 + "dstPort": 6,
110 "linkWidth": 1.0 128 "linkWidth": 1.0
111 } 129 }
112 ], 130 ],
......
1 { 1 {
2 "comment": "sample device properties", 2 "comment": "sample device properties",
3 "id": "of:0000000000000001", 3 "id": "of:0000000000000001",
4 - "propOrder": [ "name", "type", "dpid", "latitude", "longitude", "allowed" ], 4 + "type": "roadm",
5 + "propOrder": [ "name", "type", "-", "dpid", "latitude", "longitude", "allowed" ],
5 "props": { 6 "props": {
6 "allowed": true, 7 "allowed": true,
7 "latitude": 37.6, 8 "latitude": 37.6,
8 "longitude": 122.3, 9 "longitude": 122.3,
9 "name": "SFO-W10", 10 "name": "SFO-W10",
10 - "dpid": "00:00:00:00:00:00:00:01", 11 + "dpid": "00:00:00:00:00:00:00:01"
11 - "type": "Roadm"
12 } 12 }
13 } 13 }
......
1 { 1 {
2 "comment": "sample device properties", 2 "comment": "sample device properties",
3 "id": "of:0000000000000002", 3 "id": "of:0000000000000002",
4 + "type": "switch",
4 "propOrder": [ "name", "type", "dpid", "latitude", "longitude", "allowed" ], 5 "propOrder": [ "name", "type", "dpid", "latitude", "longitude", "allowed" ],
5 "props": { 6 "props": {
6 "allowed": true, 7 "allowed": true,
......
1 { 1 {
2 "comment": "sample device properties", 2 "comment": "sample device properties",
3 "id": "of:0000000000000003", 3 "id": "of:0000000000000003",
4 + "type": "switch",
4 "propOrder": [ "name", "type", "dpid", "latitude", "longitude", "allowed" ], 5 "propOrder": [ "name", "type", "dpid", "latitude", "longitude", "allowed" ],
5 "props": { 6 "props": {
6 "allowed": true, 7 "allowed": true,
......
1 { 1 {
2 "comment": "sample device properties", 2 "comment": "sample device properties",
3 "id": "of:0000000000000004", 3 "id": "of:0000000000000004",
4 + "type": "switch",
4 "propOrder": [ "name", "type", "dpid", "latitude", "longitude", "allowed" ], 5 "propOrder": [ "name", "type", "dpid", "latitude", "longitude", "allowed" ],
5 "props": { 6 "props": {
6 "allowed": true, 7 "allowed": true,
......
1 { 1 {
2 "comment": "sample device properties", 2 "comment": "sample device properties",
3 "id": "of:0000000000000011", 3 "id": "of:0000000000000011",
4 + "type": "switch",
4 "propOrder": [ "name", "type", "dpid", "optLink" ], 5 "propOrder": [ "name", "type", "dpid", "optLink" ],
5 "props": { 6 "props": {
6 "name": "SFO-pkt", 7 "name": "SFO-pkt",
......
1 { 1 {
2 "comment": "sample device properties", 2 "comment": "sample device properties",
3 "id": "of:0000000000000012", 3 "id": "of:0000000000000012",
4 + "type": "switch",
4 "propOrder": [ "name", "type", "dpid", "optLink" ], 5 "propOrder": [ "name", "type", "dpid", "optLink" ],
5 "props": { 6 "props": {
6 "name": "SJC-pkt", 7 "name": "SJC-pkt",
......
1 { 1 {
2 "comment": "sample device properties", 2 "comment": "sample device properties",
3 "id": "of:0000000000000013", 3 "id": "of:0000000000000013",
4 + "type": "switch",
4 "propOrder": [ "name", "type", "dpid", "optLink" ], 5 "propOrder": [ "name", "type", "dpid", "optLink" ],
5 "props": { 6 "props": {
6 "name": "LAX-pkt", 7 "name": "LAX-pkt",
......
...@@ -37,9 +37,10 @@ ...@@ -37,9 +37,10 @@
37 layering: true, 37 layering: true,
38 collisionPrevention: true 38 collisionPrevention: true
39 }, 39 },
40 - XjsonUrl: 'rs/topology/graph', 40 + jsonUrl: 'rs/topology/graph',
41 - jsonUrl: 'json/network.json', 41 + jsonPrefix: '',
42 - jsonPrefix: 'json/', 42 + XjsonUrl: 'json/network.json',
43 + XjsonPrefix: 'json/',
43 iconUrl: { 44 iconUrl: {
44 device: 'img/device.png', 45 device: 'img/device.png',
45 host: 'img/host.png', 46 host: 'img/host.png',
...@@ -238,6 +239,9 @@ ...@@ -238,6 +239,9 @@
238 function processKeyEvent() { 239 function processKeyEvent() {
239 var code = d3.event.keyCode; 240 var code = d3.event.keyCode;
240 switch (code) { 241 switch (code) {
242 + case 71: // G
243 + cycleLayout();
244 + break;
241 case 76: // L 245 case 76: // L
242 cycleLabels(); 246 cycleLabels();
243 break; 247 break;
...@@ -251,6 +255,11 @@ ...@@ -251,6 +255,11 @@
251 255
252 } 256 }
253 257
258 + function cycleLayout() {
259 + config.options.layering = !config.options.layering;
260 + network.force.resume();
261 + }
262 +
254 function cycleLabels() { 263 function cycleLabels() {
255 console.log('Cycle Labels - context = ' + contextLabel()); 264 console.log('Cycle Labels - context = ' + contextLabel());
256 } 265 }
...@@ -688,7 +697,8 @@ ...@@ -688,7 +697,8 @@
688 } 697 }
689 698
690 function iconUrl(d) { 699 function iconUrl(d) {
691 - return config.iconUrl[d.icon]; 700 + return 'img/' + d.type + '.png';
701 +// return config.iconUrl[d.icon];
692 } 702 }
693 703
694 function translate(x, y) { 704 function translate(x, y) {
...@@ -889,9 +899,12 @@ ...@@ -889,9 +899,12 @@
889 } 899 }
890 900
891 function detailUrl(id) { 901 function detailUrl(id) {
902 + if (config.jsonPrefix) {
892 var safeId = id.replace(/[^a-z0-9]/gi, '_'); 903 var safeId = id.replace(/[^a-z0-9]/gi, '_');
893 return config.jsonPrefix + safeId + '.json'; 904 return config.jsonPrefix + safeId + '.json';
894 } 905 }
906 + return config.jsonUrl + '/' + encodeURIComponent(id);
907 + }
895 908
896 function flyinPane(obj) { 909 function flyinPane(obj) {
897 var pane = d3.select('#flyout'), 910 var pane = d3.select('#flyout'),
...@@ -924,17 +937,29 @@ ...@@ -924,17 +937,29 @@
924 function displayDetails(data, pane) { 937 function displayDetails(data, pane) {
925 $('#flyout').empty(); 938 $('#flyout').empty();
926 939
927 - pane.append('h2').text(data.id); 940 + var title = pane.append("h2"),
928 - 941 + table = pane.append("table"),
929 - var table = pane.append("table"),
930 tbody = table.append("tbody"); 942 tbody = table.append("tbody");
931 943
944 + $('<img src="img/' + data.type + '.png">').appendTo(title);
945 + $('<span>').attr('class', 'icon').text(data.id).appendTo(title);
946 +
947 +
932 // TODO: consider using d3 data bind to TR/TD 948 // TODO: consider using d3 data bind to TR/TD
933 949
934 data.propOrder.forEach(function(p) { 950 data.propOrder.forEach(function(p) {
951 + if (p === '-') {
952 + addSep(tbody);
953 + } else {
935 addProp(tbody, p, data.props[p]); 954 addProp(tbody, p, data.props[p]);
955 + }
936 }); 956 });
937 957
958 + function addSep(tbody) {
959 + var tr = tbody.append('tr');
960 + $('<hr>').appendTo(tr.append('td').attr('colspan', 2));
961 + }
962 +
938 function addProp(tbody, label, value) { 963 function addProp(tbody, label, value) {
939 var tr = tbody.append('tr'); 964 var tr = tbody.append('tr');
940 965
......
...@@ -28,11 +28,17 @@ body, html { ...@@ -28,11 +28,17 @@ body, html {
28 * Classes 28 * Classes
29 */ 29 */
30 30
31 +img#logo {
32 + height: 38px;
33 + padding-left: 8px;
34 + padding-right: 8px;
35 +}
36 +
31 span.title { 37 span.title {
32 - color: #37b; 38 + color: #369;
33 font-size: 14pt; 39 font-size: 14pt;
34 font-style: italic; 40 font-style: italic;
35 - vertical-align: 10px; 41 + vertical-align: 12px;
36 } 42 }
37 43
38 span.radio { 44 span.radio {
...@@ -41,6 +47,8 @@ span.radio { ...@@ -41,6 +47,8 @@ span.radio {
41 } 47 }
42 48
43 span.right { 49 span.right {
50 + padding-top: 8px;
51 + padding-right: 16px;
44 float: right; 52 float: right;
45 } 53 }
46 54
...@@ -89,14 +97,13 @@ svg .link { ...@@ -89,14 +97,13 @@ svg .link {
89 } 97 }
90 98
91 svg .link.host { 99 svg .link.host {
92 - stroke: #6a6; 100 + stroke: #666;
93 - stroke-dasharray: 3,3; 101 + stroke-width: 1px;
102 + Xstroke-dasharray: 3,3;
94 } 103 }
95 104
96 svg .node.device rect { 105 svg .node.device rect {
97 - stroke-width: 3.0px; 106 + stroke-width: 1.5px;
98 - stroke: white;
99 - stroke-dasharray: 2,2;
100 107
101 transition: opacity 250ms; 108 transition: opacity 250ms;
102 -webkit-transition: opacity 250ms; 109 -webkit-transition: opacity 250ms;
...@@ -104,19 +111,21 @@ svg .node.device rect { ...@@ -104,19 +111,21 @@ svg .node.device rect {
104 } 111 }
105 112
106 svg .node.device.fixed rect { 113 svg .node.device.fixed rect {
107 - stroke-width: 0; 114 + stroke-width: 1.5;
115 + stroke: #ccc;
116 + Xstroke-dasharray: 4,2;
108 } 117 }
109 118
110 svg .node.device.roadm rect { 119 svg .node.device.roadm rect {
111 - fill: #229; 120 + fill: #03c;
112 } 121 }
113 122
114 svg .node.device.switch rect { 123 svg .node.device.switch rect {
115 - fill: #55f; 124 + fill: #06f;
116 } 125 }
117 126
118 svg .node.host circle { 127 svg .node.host circle {
119 - fill: #898; 128 + fill: #c96;
120 stroke: #000; 129 stroke: #000;
121 } 130 }
122 131
...@@ -148,7 +157,7 @@ svg .node.inactive rect, ...@@ -148,7 +157,7 @@ svg .node.inactive rect,
148 svg .node.inactive circle, 157 svg .node.inactive circle,
149 svg .node.inactive text, 158 svg .node.inactive text,
150 svg .node.inactive image { 159 svg .node.inactive image {
151 - opacity: .05; 160 + opacity: .1;
152 } 161 }
153 162
154 svg .node.inactive.selected rect, 163 svg .node.inactive.selected rect,
...@@ -199,8 +208,9 @@ body { ...@@ -199,8 +208,9 @@ body {
199 #mast { 208 #mast {
200 height: 36px; 209 height: 36px;
201 padding: 4px; 210 padding: 4px;
202 - background-color: #ccc; 211 + background-color: #bbb;
203 vertical-align: baseline; 212 vertical-align: baseline;
213 + box-shadow: 0px 2px 8px #777;
204 } 214 }
205 215
206 #frame { 216 #frame {
...@@ -214,19 +224,27 @@ body { ...@@ -214,19 +224,27 @@ body {
214 z-index: 100; 224 z-index: 100;
215 display: block; 225 display: block;
216 top: 10%; 226 top: 10%;
217 - width: 300px; 227 + width: 280px;
218 - height: 80%; 228 + right: -300px;
219 - right: -320px;
220 opacity: 0; 229 opacity: 0;
221 - background-color: rgba(0,0,0,0.5); 230 + background-color: rgba(255,255,255,0.5);
231 +
222 padding: 10px; 232 padding: 10px;
223 - color: white; 233 + color: black;
224 font-size: 10pt; 234 font-size: 10pt;
235 + box-shadow: 2px 2px 16px #777;
225 } 236 }
226 237
227 #flyout h2 { 238 #flyout h2 {
228 margin: 8px 4px; 239 margin: 8px 4px;
229 - color: yellow; 240 + color: black;
241 + vertical-align: middle;
242 +}
243 +
244 +#flyout h2 img {
245 + height: 32px;
246 + padding-right: 8px;
247 + vertical-align: middle;
230 } 248 }
231 249
232 #flyout p, table { 250 #flyout p, table {
...@@ -235,7 +253,7 @@ body { ...@@ -235,7 +253,7 @@ body {
235 253
236 #flyout td.label { 254 #flyout td.label {
237 font-style: italic; 255 font-style: italic;
238 - color: #ccf; 256 + color: #777;
239 padding-right: 12px; 257 padding-right: 12px;
240 } 258 }
241 259
...@@ -243,3 +261,10 @@ body { ...@@ -243,3 +261,10 @@ body {
243 261
244 } 262 }
245 263
264 +#flyout hr {
265 + height: 1px;
266 + color: #ccc;
267 + background-color: #ccc;
268 + border: 0;
269 +}
270 +
......