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()); | ... | ... |
providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/OpenFlowRuleProvider.java
... | @@ -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> { | ... | ... |
providers/openflow/link/src/main/java/org/onlab/onos/provider/of/link/impl/OpenFlowLinkProvider.java
... | @@ -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 | } | ... | ... |
-
Please register or login to post a comment