Praseed Balakrishnan

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

Conflicts:
	apps/optical/src/main/java/org/onlab/onos/optical/cfg/OpticalConfigProvider.java
Showing 22 changed files with 297 additions and 63 deletions
...@@ -13,7 +13,7 @@ public interface DeviceProvider extends Provider { ...@@ -13,7 +13,7 @@ public interface DeviceProvider extends Provider {
13 13
14 /** 14 /**
15 * Triggers an asynchronous probe of the specified device, intended to 15 * Triggers an asynchronous probe of the specified device, intended to
16 - * determine whether the host is present or not. An indirect result of this 16 + * determine whether the device is present or not. An indirect result of this
17 * should be invocation of 17 * should be invocation of
18 * {@link org.onlab.onos.net.device.DeviceProviderService#deviceConnected} )} or 18 * {@link org.onlab.onos.net.device.DeviceProviderService#deviceConnected} )} or
19 * {@link org.onlab.onos.net.device.DeviceProviderService#deviceDisconnected} 19 * {@link org.onlab.onos.net.device.DeviceProviderService#deviceDisconnected}
......
...@@ -161,6 +161,17 @@ public class DeviceManager ...@@ -161,6 +161,17 @@ public class DeviceManager
161 } 161 }
162 } 162 }
163 163
164 + // Queries a device for port information.
165 + private void queryPortInfo(DeviceId deviceId) {
166 + Device device = store.getDevice(deviceId);
167 + // FIXME: Device might not be there yet. (eventual consistent)
168 + if (device == null) {
169 + return;
170 + }
171 + DeviceProvider provider = getProvider(device.providerId());
172 + provider.triggerProbe(device);
173 + }
174 +
164 @Override 175 @Override
165 public void removeDevice(DeviceId deviceId) { 176 public void removeDevice(DeviceId deviceId) {
166 checkNotNull(deviceId, DEVICE_ID_NULL); 177 checkNotNull(deviceId, DEVICE_ID_NULL);
...@@ -210,8 +221,6 @@ public class DeviceManager ...@@ -210,8 +221,6 @@ public class DeviceManager
210 log.info("Device {} connected", deviceId); 221 log.info("Device {} connected", deviceId);
211 // check my Role 222 // check my Role
212 MastershipRole role = mastershipService.requestRoleFor(deviceId); 223 MastershipRole role = mastershipService.requestRoleFor(deviceId);
213 - log.info("## - our role for {} is {} [master is {}]", deviceId, role,
214 - mastershipService.getMasterFor(deviceId));
215 if (role != MastershipRole.MASTER) { 224 if (role != MastershipRole.MASTER) {
216 // TODO: Do we need to explicitly tell the Provider that 225 // TODO: Do we need to explicitly tell the Provider that
217 // this instance is no longer the MASTER? probably not 226 // this instance is no longer the MASTER? probably not
...@@ -265,7 +274,6 @@ public class DeviceManager ...@@ -265,7 +274,6 @@ public class DeviceManager
265 // but if I was the last STANDBY connection, etc. and no one else 274 // but if I was the last STANDBY connection, etc. and no one else
266 // was there to mark the device offline, this instance may need to 275 // was there to mark the device offline, this instance may need to
267 // temporarily request for Master Role and mark offline. 276 // temporarily request for Master Role and mark offline.
268 - log.info("## for {} role is {}", deviceId, mastershipService.getLocalRole(deviceId));
269 if (!mastershipService.getLocalRole(deviceId).equals(MastershipRole.MASTER)) { 277 if (!mastershipService.getLocalRole(deviceId).equals(MastershipRole.MASTER)) {
270 log.debug("Device {} disconnected, but I am not the master", deviceId); 278 log.debug("Device {} disconnected, but I am not the master", deviceId);
271 //let go of ability to be backup 279 //let go of ability to be backup
...@@ -373,7 +381,6 @@ public class DeviceManager ...@@ -373,7 +381,6 @@ public class DeviceManager
373 final DeviceId did = event.subject(); 381 final DeviceId did = event.subject();
374 final NodeId myNodeId = clusterService.getLocalNode().id(); 382 final NodeId myNodeId = clusterService.getLocalNode().id();
375 383
376 - log.info("## got Mastershipevent for dev {}", did);
377 if (myNodeId.equals(event.roleInfo().master())) { 384 if (myNodeId.equals(event.roleInfo().master())) {
378 MastershipTerm term = termService.getMastershipTerm(did); 385 MastershipTerm term = termService.getMastershipTerm(did);
379 386
...@@ -384,7 +391,6 @@ public class DeviceManager ...@@ -384,7 +391,6 @@ public class DeviceManager
384 return; 391 return;
385 } 392 }
386 393
387 - log.info("## setting term for CPS as new master for {}", did);
388 // only set the new term if I am the master 394 // only set the new term if I am the master
389 deviceClockProviderService.setMastershipTerm(did, term); 395 deviceClockProviderService.setMastershipTerm(did, term);
390 396
...@@ -404,6 +410,7 @@ public class DeviceManager ...@@ -404,6 +410,7 @@ public class DeviceManager
404 device.serialNumber(), device.chassisId())); 410 device.serialNumber(), device.chassisId()));
405 } 411 }
406 //TODO re-collect device information to fix potential staleness 412 //TODO re-collect device information to fix potential staleness
413 + queryPortInfo(did);
407 applyRole(did, MastershipRole.MASTER); 414 applyRole(did, MastershipRole.MASTER);
408 } else if (event.roleInfo().backups().contains(myNodeId)) { 415 } else if (event.roleInfo().backups().contains(myNodeId)) {
409 applyRole(did, MastershipRole.STANDBY); 416 applyRole(did, MastershipRole.STANDBY);
......
...@@ -299,7 +299,8 @@ public class FlowRuleManager ...@@ -299,7 +299,8 @@ public class FlowRuleManager
299 private void extraneousFlow(FlowRule flowRule) { 299 private void extraneousFlow(FlowRule flowRule) {
300 checkNotNull(flowRule, FLOW_RULE_NULL); 300 checkNotNull(flowRule, FLOW_RULE_NULL);
301 checkValidity(); 301 checkValidity();
302 - removeFlowRules(flowRule); 302 + FlowRuleProvider frp = getProvider(flowRule.deviceId());
303 + frp.removeFlowRule(flowRule);
303 log.debug("Flow {} is on switch but not in store.", flowRule); 304 log.debug("Flow {} is on switch but not in store.", flowRule);
304 } 305 }
305 306
......
...@@ -9,6 +9,7 @@ import org.apache.felix.scr.annotations.Service; ...@@ -9,6 +9,7 @@ import org.apache.felix.scr.annotations.Service;
9 import org.onlab.onos.net.ConnectPoint; 9 import org.onlab.onos.net.ConnectPoint;
10 import org.onlab.onos.net.Link; 10 import org.onlab.onos.net.Link;
11 import org.onlab.onos.net.Path; 11 import org.onlab.onos.net.Path;
12 +
12 import org.onlab.onos.net.flow.FlowRule; 13 import org.onlab.onos.net.flow.FlowRule;
13 import org.onlab.onos.net.flow.FlowRuleEvent; 14 import org.onlab.onos.net.flow.FlowRuleEvent;
14 import org.onlab.onos.net.flow.FlowRuleListener; 15 import org.onlab.onos.net.flow.FlowRuleListener;
...@@ -35,12 +36,14 @@ public class StatisticManager implements StatisticService { ...@@ -35,12 +36,14 @@ public class StatisticManager implements StatisticService {
35 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 36 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
36 protected StatisticStore statisticStore; 37 protected StatisticStore statisticStore;
37 38
39 +
38 private final InternalFlowRuleListener listener = new InternalFlowRuleListener(); 40 private final InternalFlowRuleListener listener = new InternalFlowRuleListener();
39 41
40 @Activate 42 @Activate
41 public void activate() { 43 public void activate() {
42 flowRuleService.addListener(listener); 44 flowRuleService.addListener(listener);
43 log.info("Started"); 45 log.info("Started");
46 +
44 } 47 }
45 48
46 @Deactivate 49 @Deactivate
...@@ -81,7 +84,22 @@ public class StatisticManager implements StatisticService { ...@@ -81,7 +84,22 @@ public class StatisticManager implements StatisticService {
81 84
82 @Override 85 @Override
83 public void event(FlowRuleEvent event) { 86 public void event(FlowRuleEvent event) {
84 - 87 +// FlowRule rule = event.subject();
88 +// switch (event.type()) {
89 +// case RULE_ADDED:
90 +// case RULE_UPDATED:
91 +// if (rule instanceof FlowEntry) {
92 +// statisticStore.addOrUpdateStatistic((FlowEntry) rule);
93 +// }
94 +// break;
95 +// case RULE_ADD_REQUESTED:
96 +// statisticStore.prepareForStatistics(rule);
97 +// break;
98 +// case RULE_REMOVE_REQUESTED:
99 +// case RULE_REMOVED:
100 +// statisticStore.removeFromStatistics(rule);
101 +// break;
102 +// }
85 } 103 }
86 } 104 }
87 105
......
...@@ -15,6 +15,7 @@ public class TestEventDispatcher extends DefaultEventSinkRegistry ...@@ -15,6 +15,7 @@ public class TestEventDispatcher extends DefaultEventSinkRegistry
15 implements EventDeliveryService { 15 implements EventDeliveryService {
16 16
17 @Override 17 @Override
18 + @SuppressWarnings("unchecked")
18 public void post(Event event) { 19 public void post(Event event) {
19 EventSink sink = getSink(event.getClass()); 20 EventSink sink = getSink(event.getClass());
20 checkState(sink != null, "No sink for event %s", event); 21 checkState(sink != null, "No sink for event %s", event);
......
1 package org.onlab.onos.net.flow.impl; 1 package org.onlab.onos.net.flow.impl;
2 2
3 -import static java.util.Collections.EMPTY_LIST;
4 -import static org.junit.Assert.assertEquals;
5 -import static org.junit.Assert.assertFalse;
6 -import static org.junit.Assert.assertNotNull;
7 -import static org.junit.Assert.assertTrue;
8 -import static org.junit.Assert.fail;
9 -import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_ADDED;
10 -import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED;
11 -import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_UPDATED;
12 -
13 import java.util.ArrayList; 3 import java.util.ArrayList;
14 import java.util.Collections; 4 import java.util.Collections;
15 import java.util.HashMap; 5 import java.util.HashMap;
...@@ -65,6 +55,16 @@ import com.google.common.collect.ImmutableMap; ...@@ -65,6 +55,16 @@ import com.google.common.collect.ImmutableMap;
65 import com.google.common.collect.Lists; 55 import com.google.common.collect.Lists;
66 import com.google.common.collect.Sets; 56 import com.google.common.collect.Sets;
67 57
58 +import static java.util.Collections.EMPTY_LIST;
59 +import static org.junit.Assert.assertEquals;
60 +import static org.junit.Assert.assertFalse;
61 +import static org.junit.Assert.assertNotNull;
62 +import static org.junit.Assert.assertTrue;
63 +import static org.junit.Assert.fail;
64 +import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_ADDED;
65 +import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED;
66 +import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_UPDATED;
67 +
68 /** 68 /**
69 * Test codifying the flow rule service & flow rule provider service contracts. 69 * Test codifying the flow rule service & flow rule provider service contracts.
70 */ 70 */
...@@ -176,6 +176,7 @@ public class FlowRuleManagerTest { ...@@ -176,6 +176,7 @@ public class FlowRuleManagerTest {
176 176
177 // TODO: If preserving iteration order is a requirement, redo FlowRuleStore. 177 // TODO: If preserving iteration order is a requirement, redo FlowRuleStore.
178 //backing store is sensitive to the order of additions/removals 178 //backing store is sensitive to the order of additions/removals
179 + @SuppressWarnings("unchecked")
179 private boolean validateState(Map<FlowRule, FlowEntryState> expected) { 180 private boolean validateState(Map<FlowRule, FlowEntryState> expected) {
180 Map<FlowRule, FlowEntryState> expectedToCheck = new HashMap<>(expected); 181 Map<FlowRule, FlowEntryState> expectedToCheck = new HashMap<>(expected);
181 Iterable<FlowEntry> rules = service.getFlowEntries(DID); 182 Iterable<FlowEntry> rules = service.getFlowEntries(DID);
...@@ -539,6 +540,7 @@ public class FlowRuleManagerTest { ...@@ -539,6 +540,7 @@ public class FlowRuleManagerTest {
539 } 540 }
540 541
541 @Override 542 @Override
543 + @SuppressWarnings("unchecked")
542 public CompletedBatchOperation get() 544 public CompletedBatchOperation get()
543 throws InterruptedException, ExecutionException { 545 throws InterruptedException, ExecutionException {
544 return new CompletedBatchOperation(true, EMPTY_LIST); 546 return new CompletedBatchOperation(true, EMPTY_LIST);
......
...@@ -35,6 +35,8 @@ public class InternalDeviceEventSerializer extends Serializer<InternalDeviceEven ...@@ -35,6 +35,8 @@ public class InternalDeviceEventSerializer extends Serializer<InternalDeviceEven
35 Class<InternalDeviceEvent> type) { 35 Class<InternalDeviceEvent> type) {
36 ProviderId providerId = (ProviderId) kryo.readClassAndObject(input); 36 ProviderId providerId = (ProviderId) kryo.readClassAndObject(input);
37 DeviceId deviceId = (DeviceId) kryo.readClassAndObject(input); 37 DeviceId deviceId = (DeviceId) kryo.readClassAndObject(input);
38 +
39 + @SuppressWarnings("unchecked")
38 Timestamped<DeviceDescription> deviceDescription 40 Timestamped<DeviceDescription> deviceDescription
39 = (Timestamped<DeviceDescription>) kryo.readClassAndObject(input); 41 = (Timestamped<DeviceDescription>) kryo.readClassAndObject(input);
40 42
......
...@@ -37,6 +37,8 @@ public class InternalPortEventSerializer extends Serializer<InternalPortEvent> { ...@@ -37,6 +37,8 @@ public class InternalPortEventSerializer extends Serializer<InternalPortEvent> {
37 Class<InternalPortEvent> type) { 37 Class<InternalPortEvent> type) {
38 ProviderId providerId = (ProviderId) kryo.readClassAndObject(input); 38 ProviderId providerId = (ProviderId) kryo.readClassAndObject(input);
39 DeviceId deviceId = (DeviceId) kryo.readClassAndObject(input); 39 DeviceId deviceId = (DeviceId) kryo.readClassAndObject(input);
40 +
41 + @SuppressWarnings("unchecked")
40 Timestamped<List<PortDescription>> portDescriptions 42 Timestamped<List<PortDescription>> portDescriptions
41 = (Timestamped<List<PortDescription>>) kryo.readClassAndObject(input); 43 = (Timestamped<List<PortDescription>>) kryo.readClassAndObject(input);
42 44
......
...@@ -177,6 +177,7 @@ public class SimpleFlowRuleStore ...@@ -177,6 +177,7 @@ public class SimpleFlowRuleStore
177 public boolean deleteFlowRule(FlowRule rule) { 177 public boolean deleteFlowRule(FlowRule rule) {
178 178
179 List<StoredFlowEntry> entries = getFlowEntries(rule.deviceId(), rule.id()); 179 List<StoredFlowEntry> entries = getFlowEntries(rule.deviceId(), rule.id());
180 +
180 synchronized (entries) { 181 synchronized (entries) {
181 for (StoredFlowEntry entry : entries) { 182 for (StoredFlowEntry entry : entries) {
182 if (entry.equals(rule)) { 183 if (entry.equals(rule)) {
......
...@@ -82,12 +82,28 @@ public class SimpleIntentStore ...@@ -82,12 +82,28 @@ public class SimpleIntentStore
82 public IntentEvent setState(Intent intent, IntentState state) { 82 public IntentEvent setState(Intent intent, IntentState state) {
83 IntentId id = intent.id(); 83 IntentId id = intent.id();
84 states.put(id, state); 84 states.put(id, state);
85 - IntentEvent.Type type = (state == SUBMITTED ? IntentEvent.Type.SUBMITTED : 85 + IntentEvent.Type type = null;
86 - (state == INSTALLED ? IntentEvent.Type.INSTALLED : 86 +
87 - (state == FAILED ? IntentEvent.Type.FAILED : 87 + switch (state) {
88 - state == WITHDRAWN ? IntentEvent.Type.WITHDRAWN : 88 + case SUBMITTED:
89 - null))); 89 + type = IntentEvent.Type.SUBMITTED;
90 - return type == null ? null : new IntentEvent(type, intent); 90 + break;
91 + case INSTALLED:
92 + type = IntentEvent.Type.INSTALLED;
93 + break;
94 + case FAILED:
95 + type = IntentEvent.Type.FAILED;
96 + break;
97 + case WITHDRAWN:
98 + type = IntentEvent.Type.WITHDRAWN;
99 + break;
100 + default:
101 + break;
102 + }
103 + if (type == null) {
104 + return null;
105 + }
106 + return new IntentEvent(type, intent);
91 } 107 }
92 108
93 @Override 109 @Override
......
...@@ -110,8 +110,7 @@ public interface OpenFlowSwitch { ...@@ -110,8 +110,7 @@ public interface OpenFlowSwitch {
110 * 110 *
111 * @param role the failed role 111 * @param role the failed role
112 */ 112 */
113 - void returnRoleAssertFailure(RoleState role); 113 + public void returnRoleAssertFailure(RoleState role);
114 -
115 114
116 /** 115 /**
117 * Indicates if this switch is optical. 116 * Indicates if this switch is optical.
...@@ -120,5 +119,4 @@ public interface OpenFlowSwitch { ...@@ -120,5 +119,4 @@ public interface OpenFlowSwitch {
120 */ 119 */
121 public boolean isOptical(); 120 public boolean isOptical();
122 121
123 -
124 } 122 }
......
...@@ -20,6 +20,12 @@ public interface OpenFlowSwitchListener { ...@@ -20,6 +20,12 @@ public interface OpenFlowSwitchListener {
20 public void switchRemoved(Dpid dpid); 20 public void switchRemoved(Dpid dpid);
21 21
22 /** 22 /**
23 + * Notify that the switch has changed in some way.
24 + * @param dpid the switch that changed
25 + */
26 + public void switchChanged(Dpid dpid);
27 +
28 + /**
23 * Notify that a port has changed. 29 * Notify that a port has changed.
24 * @param dpid the switch on which the change happened. 30 * @param dpid the switch on which the change happened.
25 * @param status the new state of the port. 31 * @param status the new state of the port.
......
...@@ -565,6 +565,9 @@ class OFChannelHandler extends IdleStateAwareChannelHandler { ...@@ -565,6 +565,9 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
565 @Override 565 @Override
566 void processOFStatisticsReply(OFChannelHandler h, 566 void processOFStatisticsReply(OFChannelHandler h,
567 OFStatsReply m) { 567 OFStatsReply m) {
568 + if (m.getStatsType().equals(OFStatsType.PORT_DESC)) {
569 + h.sw.setPortDescReply((OFPortDescStatsReply) m);
570 + }
568 h.dispatchMessage(m); 571 h.dispatchMessage(m);
569 } 572 }
570 573
...@@ -608,6 +611,12 @@ class OFChannelHandler extends IdleStateAwareChannelHandler { ...@@ -608,6 +611,12 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
608 h.dispatchMessage(m); 611 h.dispatchMessage(m);
609 } 612 }
610 613
614 + @Override
615 + void processOFFeaturesReply(OFChannelHandler h, OFFeaturesReply m) {
616 + h.sw.setFeaturesReply(m);
617 + h.dispatchMessage(m);
618 + }
619 +
611 }; 620 };
612 621
613 private final boolean handshakeComplete; 622 private final boolean handshakeComplete;
......
...@@ -27,6 +27,8 @@ import org.onlab.onos.openflow.controller.driver.OpenFlowAgent; ...@@ -27,6 +27,8 @@ import org.onlab.onos.openflow.controller.driver.OpenFlowAgent;
27 import org.projectfloodlight.openflow.protocol.OFMessage; 27 import org.projectfloodlight.openflow.protocol.OFMessage;
28 import org.projectfloodlight.openflow.protocol.OFPacketIn; 28 import org.projectfloodlight.openflow.protocol.OFPacketIn;
29 import org.projectfloodlight.openflow.protocol.OFPortStatus; 29 import org.projectfloodlight.openflow.protocol.OFPortStatus;
30 +import org.projectfloodlight.openflow.protocol.OFStatsReply;
31 +import org.projectfloodlight.openflow.protocol.OFStatsType;
30 import org.slf4j.Logger; 32 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory; 33 import org.slf4j.LoggerFactory;
32 34
...@@ -146,6 +148,11 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -146,6 +148,11 @@ public class OpenFlowControllerImpl implements OpenFlowController {
146 l.portChanged(dpid, (OFPortStatus) msg); 148 l.portChanged(dpid, (OFPortStatus) msg);
147 } 149 }
148 break; 150 break;
151 + case FEATURES_REPLY:
152 + for (OpenFlowSwitchListener l : ofSwitchListener) {
153 + l.switchChanged(dpid);
154 + }
155 + break;
149 case PACKET_IN: 156 case PACKET_IN:
150 OpenFlowPacketContext pktCtx = DefaultOpenFlowPacketContext 157 OpenFlowPacketContext pktCtx = DefaultOpenFlowPacketContext
151 .packetContextFromPacketIn(this.getSwitch(dpid), 158 .packetContextFromPacketIn(this.getSwitch(dpid),
...@@ -154,9 +161,15 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -154,9 +161,15 @@ public class OpenFlowControllerImpl implements OpenFlowController {
154 p.handlePacket(pktCtx); 161 p.handlePacket(pktCtx);
155 } 162 }
156 break; 163 break;
164 + case STATS_REPLY:
165 + OFStatsReply reply = (OFStatsReply) msg;
166 + if (reply.getStatsType().equals(OFStatsType.PORT_DESC)) {
167 + for (OpenFlowSwitchListener l : ofSwitchListener) {
168 + l.switchChanged(dpid);
169 + }
170 + }
157 case FLOW_REMOVED: 171 case FLOW_REMOVED:
158 case ERROR: 172 case ERROR:
159 - case STATS_REPLY:
160 case BARRIER_REPLY: 173 case BARRIER_REPLY:
161 executor.submit(new OFMessageHandler(dpid, msg)); 174 executor.submit(new OFMessageHandler(dpid, msg));
162 break; 175 break;
......
...@@ -344,7 +344,8 @@ public class LinkDiscovery implements TimerTask { ...@@ -344,7 +344,8 @@ public class LinkDiscovery implements TimerTask {
344 } 344 }
345 345
346 private void sendProbes(Long portNumber) { 346 private void sendProbes(Long portNumber) {
347 - if (mastershipService.getLocalRole(this.device.id()) == 347 + if (device.type() != Device.Type.ROADM &&
348 + mastershipService.getLocalRole(this.device.id()) ==
348 MastershipRole.MASTER) { 349 MastershipRole.MASTER) {
349 OutboundPacket pkt = this.createOutBoundLLDP(portNumber); 350 OutboundPacket pkt = this.createOutBoundLLDP(portNumber);
350 pktService.emit(pkt); 351 pktService.emit(pkt);
......
...@@ -23,7 +23,9 @@ import org.onlab.onos.openflow.controller.OpenFlowController; ...@@ -23,7 +23,9 @@ import org.onlab.onos.openflow.controller.OpenFlowController;
23 import org.onlab.onos.openflow.controller.OpenFlowSwitch; 23 import org.onlab.onos.openflow.controller.OpenFlowSwitch;
24 import org.onlab.onos.openflow.controller.OpenFlowSwitchListener; 24 import org.onlab.onos.openflow.controller.OpenFlowSwitchListener;
25 import org.onlab.onos.openflow.controller.RoleState; 25 import org.onlab.onos.openflow.controller.RoleState;
26 +import org.onlab.onos.openflow.controller.driver.OpenFlowSwitchDriver;
26 import org.onlab.packet.ChassisId; 27 import org.onlab.packet.ChassisId;
28 +import org.projectfloodlight.openflow.protocol.OFFactory;
27 import org.projectfloodlight.openflow.protocol.OFPortConfig; 29 import org.projectfloodlight.openflow.protocol.OFPortConfig;
28 import org.projectfloodlight.openflow.protocol.OFPortDesc; 30 import org.projectfloodlight.openflow.protocol.OFPortDesc;
29 import org.projectfloodlight.openflow.protocol.OFPortState; 31 import org.projectfloodlight.openflow.protocol.OFPortState;
...@@ -89,6 +91,28 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -89,6 +91,28 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
89 @Override 91 @Override
90 public void triggerProbe(Device device) { 92 public void triggerProbe(Device device) {
91 LOG.info("Triggering probe on device {}", device.id()); 93 LOG.info("Triggering probe on device {}", device.id());
94 +
95 + // 1. check device liveness
96 + // FIXME if possible, we might want this to be part of
97 + // OpenFlowSwitch interface so the driver interface isn't misused.
98 + OpenFlowSwitch sw = controller.getSwitch(dpid(device.id().uri()));
99 + if (!((OpenFlowSwitchDriver) sw).isConnected()) {
100 + providerService.deviceDisconnected(device.id());
101 + return;
102 + }
103 +
104 + // 2. Prompt an update of port information. Do we have an XID for this?
105 + OFFactory fact = sw.factory();
106 + switch (fact.getVersion()) {
107 + case OF_10:
108 + sw.sendMsg(fact.buildFeaturesRequest().setXid(0).build());
109 + break;
110 + case OF_13:
111 + sw.sendMsg(fact.buildPortDescStatsRequest().setXid(0).build());
112 + break;
113 + default:
114 + LOG.warn("Unhandled protocol version");
115 + }
92 } 116 }
93 117
94 @Override 118 @Override
...@@ -141,6 +165,17 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -141,6 +165,17 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
141 providerService.deviceDisconnected(deviceId(uri(dpid))); 165 providerService.deviceDisconnected(deviceId(uri(dpid)));
142 } 166 }
143 167
168 +
169 + @Override
170 + public void switchChanged(Dpid dpid) {
171 + if (providerService == null) {
172 + return;
173 + }
174 + DeviceId did = deviceId(uri(dpid));
175 + OpenFlowSwitch sw = controller.getSwitch(dpid);
176 + providerService.updatePorts(did, buildPortDescriptions(sw.getPorts()));
177 + }
178 +
144 @Override 179 @Override
145 public void portChanged(Dpid dpid, OFPortStatus status) { 180 public void portChanged(Dpid dpid, OFPortStatus status) {
146 PortDescription portDescription = buildPortDescription(status.getDesc()); 181 PortDescription portDescription = buildPortDescription(status.getDesc());
......
...@@ -233,6 +233,10 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr ...@@ -233,6 +233,10 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
233 } 233 }
234 234
235 @Override 235 @Override
236 + public void switchChanged(Dpid dpid) {
237 + }
238 +
239 + @Override
236 public void portChanged(Dpid dpid, OFPortStatus status) { 240 public void portChanged(Dpid dpid, OFPortStatus status) {
237 //TODO: Decide whether to evict flows internal store. 241 //TODO: Decide whether to evict flows internal store.
238 } 242 }
...@@ -313,6 +317,7 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr ...@@ -313,6 +317,7 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
313 } 317 }
314 return false; 318 return false;
315 } 319 }
320 +
316 } 321 }
317 322
318 private class InstallationFuture implements Future<CompletedBatchOperation> { 323 private class InstallationFuture implements Future<CompletedBatchOperation> {
......
...@@ -118,6 +118,12 @@ public class OpenFlowLinkProvider extends AbstractProvider implements LinkProvid ...@@ -118,6 +118,12 @@ public class OpenFlowLinkProvider extends AbstractProvider implements LinkProvid
118 DeviceId.deviceId("of:" + Long.toHexString(dpid.value()))); 118 DeviceId.deviceId("of:" + Long.toHexString(dpid.value())));
119 } 119 }
120 120
121 +
122 + @Override
123 + public void switchChanged(Dpid dpid) {
124 + //might not need to do anything since DeviceManager is notified
125 + }
126 +
121 @Override 127 @Override
122 public void portChanged(Dpid dpid, OFPortStatus status) { 128 public void portChanged(Dpid dpid, OFPortStatus status) {
123 LinkDiscovery ld = discoverers.get(dpid); 129 LinkDiscovery ld = discoverers.get(dpid);
......
...@@ -6,6 +6,7 @@ import com.google.common.collect.MutableClassToInstanceMap; ...@@ -6,6 +6,7 @@ import com.google.common.collect.MutableClassToInstanceMap;
6 /** 6 /**
7 * Service directory implementation suitable for testing. 7 * Service directory implementation suitable for testing.
8 */ 8 */
9 +@SuppressWarnings("unchecked")
9 public class TestServiceDirectory implements ServiceDirectory { 10 public class TestServiceDirectory implements ServiceDirectory {
10 11
11 private ClassToInstanceMap<Object> services = MutableClassToInstanceMap.create(); 12 private ClassToInstanceMap<Object> services = MutableClassToInstanceMap.create();
......
...@@ -32,20 +32,20 @@ ...@@ -32,20 +32,20 @@
32 <div id="view"></div> 32 <div id="view"></div>
33 </div> 33 </div>
34 34
35 - // Initialize the UI... 35 + <!-- Initialize the UI...-->
36 <script type="text/javascript"> 36 <script type="text/javascript">
37 var ONOS = $.onos({note: "config, if needed"}); 37 var ONOS = $.onos({note: "config, if needed"});
38 </script> 38 </script>
39 39
40 - // include module files 40 + <!-- include module files-->
41 - // + mast.js 41 + <!-- + mast.js-->
42 - // + nav.js 42 + <!-- + nav.js-->
43 - // + .... application views 43 + <!-- + .... application views-->
44 44
45 - // for now, we are just bootstrapping the network visualization 45 + <!-- for now, we are just bootstrapping the network visualization-->
46 <script src="network.js" type="text/javascript"></script> 46 <script src="network.js" type="text/javascript"></script>
47 47
48 - // finally, build the UI 48 + <!-- finally, build the UI-->
49 <script type="text/javascript"> 49 <script type="text/javascript">
50 $(ONOS.buildUi); 50 $(ONOS.buildUi);
51 </script> 51 </script>
......
...@@ -100,7 +100,7 @@ ...@@ -100,7 +100,7 @@
100 100
101 network.data.nodes.forEach(function(n) { 101 network.data.nodes.forEach(function(n) {
102 var ypc = yPosConstraintForNode(n), 102 var ypc = yPosConstraintForNode(n),
103 - ix = Math.random() * 0.8 * nw + 0.1 * nw, 103 + ix = Math.random() * 0.6 * nw + 0.2 * nw,
104 iy = ypc * nh, 104 iy = ypc * nh,
105 node = { 105 node = {
106 id: n.id, 106 id: n.id,
...@@ -152,11 +152,49 @@ ...@@ -152,11 +152,49 @@
152 .attr('width', view.width) 152 .attr('width', view.width)
153 .attr('height', view.height) 153 .attr('height', view.height)
154 .append('g') 154 .append('g')
155 - .attr('transform', config.force.translate()); 155 +// .attr('id', 'zoomable')
156 + .attr('transform', config.force.translate())
157 +// .call(d3.behavior.zoom().on("zoom", zoomRedraw));
158 +
159 +// function zoomRedraw() {
160 +// d3.select("#zoomable").attr("transform",
161 +// "translate(" + d3.event.translate + ")"
162 +// + " scale(" + d3.event.scale + ")");
163 +// }
164 +
165 + // TODO: svg.append('defs') for markers?
166 +
167 + // TODO: move glow/blur stuff to util script
168 + var glow = network.svg.append('filter')
169 + .attr('x', '-50%')
170 + .attr('y', '-50%')
171 + .attr('width', '200%')
172 + .attr('height', '200%')
173 + .attr('id', 'blue-glow');
174 +
175 + glow.append('feColorMatrix')
176 + .attr('type', 'matrix')
177 + .attr('values', '0 0 0 0 0 ' +
178 + '0 0 0 0 0 ' +
179 + '0 0 0 0 .7 ' +
180 + '0 0 0 1 0 ');
181 +
182 + glow.append('feGaussianBlur')
183 + .attr('stdDeviation', 3)
184 + .attr('result', 'coloredBlur');
185 +
186 + glow.append('feMerge').selectAll('feMergeNode')
187 + .data(['coloredBlur', 'SourceGraphic'])
188 + .enter().append('feMergeNode')
189 + .attr('in', String);
156 190
157 - // TODO: svg.append('defs')
158 - // TODO: glow/blur stuff
159 // TODO: legend (and auto adjust on scroll) 191 // TODO: legend (and auto adjust on scroll)
192 +// $('#view').on('scroll', function() {
193 +//
194 +// });
195 +
196 +
197 +
160 198
161 network.link = network.svg.append('g').selectAll('.link') 199 network.link = network.svg.append('g').selectAll('.link')
162 .data(network.force.links(), function(d) {return d.id}) 200 .data(network.force.links(), function(d) {return d.id})
...@@ -164,27 +202,90 @@ ...@@ -164,27 +202,90 @@
164 .attr('class', 'link'); 202 .attr('class', 'link');
165 203
166 // TODO: drag behavior 204 // TODO: drag behavior
167 - // TODO: closest node deselect 205 + network.draggedThreshold = d3.scale.linear()
206 + .domain([0, 0.1])
207 + .range([5, 20])
208 + .clamp(true);
209 +
210 + function dragged(d) {
211 + var threshold = network.draggedThreshold(network.force.alpha()),
212 + dx = d.oldX - d.px,
213 + dy = d.oldY - d.py;
214 + if (Math.abs(dx) >= threshold || Math.abs(dy) >= threshold) {
215 + d.dragged = true;
216 + }
217 + return d.dragged;
218 + }
219 +
220 + network.drag = d3.behavior.drag()
221 + .origin(function(d) { return d; })
222 + .on('dragstart', function(d) {
223 + d.oldX = d.x;
224 + d.oldY = d.y;
225 + d.dragged = false;
226 + d.fixed |= 2;
227 + })
228 + .on('drag', function(d) {
229 + d.px = d3.event.x;
230 + d.py = d3.event.y;
231 + if (dragged(d)) {
232 + if (!network.force.alpha()) {
233 + network.force.alpha(.025);
234 + }
235 + }
236 + })
237 + .on('dragend', function(d) {
238 + if (!dragged(d)) {
239 + selectObject(d, this);
240 + }
241 + d.fixed &= ~6;
242 + });
243 +
244 + $('#view').on('click', function(e) {
245 + if (!$(e.target).closest('.node').length) {
246 + deselectObject();
247 + }
248 + });
168 249
169 // TODO: add drag, mouseover, mouseout behaviors 250 // TODO: add drag, mouseover, mouseout behaviors
170 network.node = network.svg.selectAll('.node') 251 network.node = network.svg.selectAll('.node')
171 .data(network.force.nodes(), function(d) {return d.id}) 252 .data(network.force.nodes(), function(d) {return d.id})
172 .enter().append('g') 253 .enter().append('g')
173 - .attr('class', 'node') 254 + .attr('class', function(d) {
255 + return 'node ' + d.type;
256 + })
174 .attr('transform', function(d) { 257 .attr('transform', function(d) {
175 return translate(d.x, d.y); 258 return translate(d.x, d.y);
176 }) 259 })
177 - // .call(network.drag) 260 + .call(network.drag)
178 - .on('mouseover', function(d) {}) 261 + .on('mouseover', function(d) {
179 - .on('mouseout', function(d) {}); 262 + if (!selected.obj) {
263 + if (network.mouseoutTimeout) {
264 + clearTimeout(network.mouseoutTimeout);
265 + network.mouseoutTimeout = null;
266 + }
267 + highlightObject(d);
268 + }
269 + })
270 + .on('mouseout', function(d) {
271 + if (!selected.obj) {
272 + if (network.mouseoutTimeout) {
273 + clearTimeout(network.mouseoutTimeout);
274 + network.mouseoutTimeout = null;
275 + }
276 + network.mouseoutTimeout = setTimeout(function() {
277 + highlightObject(null);
278 + }, 160);
279 + }
280 + });
180 281
181 // TODO: augment stroke and fill functions 282 // TODO: augment stroke and fill functions
182 network.nodeRect = network.node.append('rect') 283 network.nodeRect = network.node.append('rect')
183 // TODO: css for node rects 284 // TODO: css for node rects
184 .attr('rx', 5) 285 .attr('rx', 5)
185 .attr('ry', 5) 286 .attr('ry', 5)
186 - .attr('stroke', function(d) { return '#000'}) 287 +// .attr('stroke', function(d) { return '#000'})
187 - .attr('fill', function(d) { return '#ddf'}) 288 +// .attr('fill', function(d) { return '#ddf'})
188 .attr('width', 60) 289 .attr('width', 60)
189 .attr('height', 24); 290 .attr('height', 24);
190 291
......
...@@ -13,7 +13,7 @@ body, html { ...@@ -13,7 +13,7 @@ body, html {
13 */ 13 */
14 14
15 span.title { 15 span.title {
16 - color: red; 16 + color: darkblue;
17 font-size: 16pt; 17 font-size: 16pt;
18 font-style: italic; 18 font-style: italic;
19 } 19 }
...@@ -30,7 +30,7 @@ span.right { ...@@ -30,7 +30,7 @@ span.right {
30 * === DEBUGGING ====== 30 * === DEBUGGING ======
31 */ 31 */
32 svg { 32 svg {
33 - border: 1px dashed red; 33 + /*border: 1px dashed red;*/
34 } 34 }
35 35
36 36
...@@ -64,36 +64,45 @@ marker#end { ...@@ -64,36 +64,45 @@ marker#end {
64 -moz-transition: opacity 250ms; 64 -moz-transition: opacity 250ms;
65 } 65 }
66 66
67 -.node text { 67 +/*differentiate between packet and optical nodes*/
68 - fill: #000; 68 +svg .node.pkt rect {
69 + fill: #77a;
70 +}
71 +
72 +svg .node.opt rect {
73 + fill: #7a7;
74 +}
75 +
76 +svg .node text {
77 + fill: white;
69 font: 10px sans-serif; 78 font: 10px sans-serif;
70 pointer-events: none; 79 pointer-events: none;
71 } 80 }
72 81
73 -.node.selected rect { 82 +svg .node.selected rect {
74 filter: url(#blue-glow); 83 filter: url(#blue-glow);
75 } 84 }
76 85
77 -.link.inactive, 86 +svg .link.inactive,
78 -.node.inactive rect, 87 +svg .node.inactive rect,
79 -.node.inactive text { 88 +svg .node.inactive text {
80 opacity: .2; 89 opacity: .2;
81 } 90 }
82 91
83 -.node.inactive.selected rect, 92 +svg .node.inactive.selected rect,
84 -.node.inactive.selected text { 93 +svg .node.inactive.selected text {
85 opacity: .6; 94 opacity: .6;
86 } 95 }
87 96
88 -.legend { 97 +svg .legend {
89 position: fixed; 98 position: fixed;
90 } 99 }
91 100
92 -.legend .category rect { 101 +svg .legend .category rect {
93 stroke-width: 1px; 102 stroke-width: 1px;
94 } 103 }
95 104
96 -.legend .category text { 105 +svg .legend .category text {
97 fill: #000; 106 fill: #000;
98 font: 10px sans-serif; 107 font: 10px sans-serif;
99 pointer-events: none; 108 pointer-events: none;
...@@ -110,15 +119,15 @@ marker#end { ...@@ -110,15 +119,15 @@ marker#end {
110 #frame { 119 #frame {
111 width: 100%; 120 width: 100%;
112 height: 100%; 121 height: 100%;
113 - background-color: #ffd; 122 + background-color: #cdf;
114 } 123 }
115 124
116 #mast { 125 #mast {
117 height: 32px; 126 height: 32px;
118 - background-color: #dda; 127 + background-color: #abe;
119 vertical-align: baseline; 128 vertical-align: baseline;
120 } 129 }
121 130
122 #main { 131 #main {
123 - background-color: #99b; 132 + background-color: #99c;
124 } 133 }
......