blob: 669124d87d83a4ec3dc0c96e03eb10fa991fd132 [file] [log] [blame]
/*
* Copyright 2016 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.newoptical;
import org.apache.commons.lang3.tuple.Pair;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.ChassisId;
import org.onlab.packet.IpAddress;
import org.onlab.util.Bandwidth;
import org.onlab.util.Frequency;
import org.onosproject.cluster.ClusterServiceAdapter;
import org.onosproject.cluster.ControllerNode;
import org.onosproject.cluster.NodeId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreServiceAdapter;
import org.onosproject.core.DefaultApplicationId;
import org.onosproject.core.IdGenerator;
import org.onosproject.event.DefaultEventSinkRegistry;
import org.onosproject.event.Event;
import org.onosproject.event.EventDeliveryService;
import org.onosproject.event.EventSink;
import org.onosproject.mastership.MastershipServiceAdapter;
import org.onosproject.net.ChannelSpacing;
import org.onosproject.net.CltSignalType;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultDevice;
import org.onosproject.net.DefaultLink;
import org.onosproject.net.DefaultPath;
import org.onosproject.net.DefaultPort;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.ElementId;
import org.onosproject.net.Link;
import org.onosproject.net.MastershipRole;
import org.onosproject.net.OchSignal;
import org.onosproject.net.OduSignalType;
import org.onosproject.net.Path;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.config.Config;
import org.onosproject.net.config.NetworkConfigServiceAdapter;
import org.onosproject.net.config.basics.BandwidthCapacity;
import org.onosproject.net.device.DeviceServiceAdapter;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentEvent;
import org.onosproject.net.intent.IntentListener;
import org.onosproject.net.intent.IntentServiceAdapter;
import org.onosproject.net.intent.Key;
import org.onosproject.net.intent.OpticalConnectivityIntent;
import org.onosproject.net.link.LinkServiceAdapter;
import org.onosproject.net.optical.impl.DefaultOchPort;
import org.onosproject.net.optical.impl.DefaultOduCltPort;
import org.onosproject.net.optical.impl.DefaultOmsPort;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.net.resource.DiscreteResourceId;
import org.onosproject.net.resource.Resource;
import org.onosproject.net.resource.ResourceAllocation;
import org.onosproject.net.resource.ResourceConsumer;
import org.onosproject.net.resource.ResourceId;
import org.onosproject.net.resource.ResourceListener;
import org.onosproject.net.resource.ResourceService;
import org.onosproject.net.topology.LinkWeight;
import org.onosproject.net.topology.PathServiceAdapter;
import org.onosproject.newoptical.api.OpticalConnectivityId;
import org.onosproject.newoptical.api.OpticalPathEvent;
import org.onosproject.newoptical.api.OpticalPathListener;
import org.onosproject.store.service.AsyncConsistentMap;
import org.onosproject.store.service.AsyncDistributedSet;
import org.onosproject.store.service.AtomicCounter;
import org.onosproject.store.service.ConsistentMap;
import org.onosproject.store.service.ConsistentMapAdapter;
import org.onosproject.store.service.ConsistentMapBuilder;
import org.onosproject.store.service.DistributedSet;
import org.onosproject.store.service.DistributedSetAdapter;
import org.onosproject.store.service.DistributedSetBuilder;
import org.onosproject.store.service.MapEvent;
import org.onosproject.store.service.MapEventListener;
import org.onosproject.store.service.SetEventListener;
import org.onosproject.store.service.StorageServiceAdapter;
import org.onosproject.store.service.Versioned;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.function.BiFunction;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static com.google.common.base.Preconditions.checkState;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.onosproject.net.NetTestTools.injectEventDispatcher;
/**
* Tests for OpticalPathProvisioner class.
*/
public class OpticalPathProvisionerTest {
private static final ProviderId PROVIDER_ID = new ProviderId("of", "foo");
// 7-nodes linear topology containing packet/cross-connect/optical links
private static final ConnectPoint CP11 = createConnectPoint(1, 1);
private static final ConnectPoint CP12 = createConnectPoint(1, 2);
private static final ConnectPoint CP21 = createConnectPoint(2, 1);
private static final ConnectPoint CP22 = createConnectPoint(2, 2); // cross connect port (packet)
private static final ConnectPoint CP31 = createConnectPoint(3, 1); // cross connect port (oductl)
private static final ConnectPoint CP32 = createConnectPoint(3, 2);
private static final ConnectPoint CP41 = createConnectPoint(4, 1);
private static final ConnectPoint CP42 = createConnectPoint(4, 2);
private static final ConnectPoint CP51 = createConnectPoint(5, 1);
private static final ConnectPoint CP52 = createConnectPoint(5, 2); // cross connect port (oductl)
private static final ConnectPoint CP61 = createConnectPoint(6, 1); // cross connect port (packet)
private static final ConnectPoint CP62 = createConnectPoint(6, 2);
private static final ConnectPoint CP71 = createConnectPoint(7, 1);
private static final ConnectPoint CP72 = createConnectPoint(7, 2);
private static final Link LINK1 = createLink(CP12, CP21, Link.Type.DIRECT);
private static final Link LINK2 = createLink(CP22, CP31, Link.Type.OPTICAL); // cross connect link
private static final Link LINK3 = createLink(CP32, CP41, Link.Type.OPTICAL);
private static final Link LINK4 = createLink(CP42, CP51, Link.Type.OPTICAL);
private static final Link LINK5 = createLink(CP52, CP61, Link.Type.OPTICAL); // cross connect link
private static final Link LINK6 = createLink(CP62, CP71, Link.Type.DIRECT);
private static final Device DEVICE1 = createDevice(1, Device.Type.SWITCH);
private static final Device DEVICE2 = createDevice(2, Device.Type.SWITCH);
private static final Device DEVICE3 = createDevice(3, Device.Type.ROADM);
private static final Device DEVICE4 = createDevice(4, Device.Type.ROADM);
private static final Device DEVICE5 = createDevice(5, Device.Type.ROADM);
private static final Device DEVICE6 = createDevice(6, Device.Type.SWITCH);
private static final Device DEVICE7 = createDevice(7, Device.Type.SWITCH);
private static final Port PORT11 = createPacketPort(DEVICE1, CP11);
private static final Port PORT12 = createPacketPort(DEVICE1, CP12);
private static final Port PORT21 = createPacketPort(DEVICE2, CP21);
private static final Port PORT22 = createOduCltPort(DEVICE2, CP22);
private static final Port PORT31 = createOchPort(DEVICE3, CP31);
private static final Port PORT32 = createOmsPort(DEVICE3, CP32);
private static final Port PORT41 = createOmsPort(DEVICE4, CP41);
private static final Port PORT42 = createOmsPort(DEVICE4, CP42);
private static final Port PORT51 = createOmsPort(DEVICE5, CP51);
private static final Port PORT52 = createOchPort(DEVICE5, CP52);
private static final Port PORT61 = createOduCltPort(DEVICE6, CP61);
private static final Port PORT62 = createPacketPort(DEVICE6, CP62);
private static final Port PORT71 = createPacketPort(DEVICE7, CP71);
private static final Port PORT72 = createPacketPort(DEVICE7, CP72);
protected OpticalPathProvisioner target;
protected TestListener listener = new TestListener();
protected TestDeviceService deviceService;
protected TestLinkService linkService;
protected TestPathService pathService;
protected TestIntentService intentService;
protected TestMastershipService mastershipService;
protected TestClusterService clusterService;
protected IdGenerator idGenerator;
@Before
public void setUp() {
this.deviceService = new TestDeviceService();
deviceService.devMap.put(deviceIdOf(1), DEVICE1);
deviceService.devMap.put(deviceIdOf(2), DEVICE2);
deviceService.devMap.put(deviceIdOf(3), DEVICE3);
deviceService.devMap.put(deviceIdOf(4), DEVICE4);
deviceService.devMap.put(deviceIdOf(5), DEVICE5);
deviceService.devMap.put(deviceIdOf(6), DEVICE6);
deviceService.devMap.put(deviceIdOf(7), DEVICE7);
deviceService.portMap.put(CP11, PORT11);
deviceService.portMap.put(CP12, PORT12);
deviceService.portMap.put(CP21, PORT21);
deviceService.portMap.put(CP22, PORT22);
deviceService.portMap.put(CP31, PORT31);
deviceService.portMap.put(CP32, PORT32);
deviceService.portMap.put(CP41, PORT41);
deviceService.portMap.put(CP42, PORT42);
deviceService.portMap.put(CP51, PORT51);
deviceService.portMap.put(CP52, PORT52);
deviceService.portMap.put(CP61, PORT61);
deviceService.portMap.put(CP62, PORT62);
deviceService.portMap.put(CP71, PORT71);
deviceService.portMap.put(CP72, PORT72);
this.linkService = new TestLinkService();
linkService.links.addAll(Stream.of(LINK1, LINK2, LINK3, LINK4, LINK5, LINK6)
.collect(Collectors.toList()));
this.pathService = new TestPathService();
this.intentService = new TestIntentService();
this.mastershipService = new TestMastershipService();
this.clusterService = new TestClusterService();
mastershipService.setMastership(DEVICE1.id(), MastershipRole.MASTER);
mastershipService.setMastership(DEVICE2.id(), MastershipRole.MASTER);
mastershipService.setMastership(DEVICE3.id(), MastershipRole.MASTER);
mastershipService.setMastership(DEVICE4.id(), MastershipRole.MASTER);
mastershipService.setMastership(DEVICE5.id(), MastershipRole.MASTER);
mastershipService.setMastership(DEVICE6.id(), MastershipRole.MASTER);
mastershipService.setMastership(DEVICE7.id(), MastershipRole.MASTER);
this.target = new OpticalPathProvisioner();
target.coreService = new TestCoreService();
target.intentService = this.intentService;
target.pathService = this.pathService;
target.linkService = this.linkService;
target.mastershipService = this.mastershipService;
target.clusterService = this.clusterService;
target.storageService = new TestStorageService();
target.deviceService = this.deviceService;
target.networkConfigService = new TestNetworkConfigService();
target.resourceService = new TestResourceService();
injectEventDispatcher(target, new TestEventDispatcher());
target.addListener(listener);
target.activate();
// To overwrite opticalView-ed deviceService
target.deviceService = this.deviceService;
idGenerator = new IdGenerator() {
int counter = 1;
@Override
public long getNewId() {
return counter++;
}
};
Intent.bindIdGenerator(idGenerator);
}
@After
public void tearDown() {
Intent.unbindIdGenerator(idGenerator);
target.removeListener(listener);
target = null;
}
/**
* Checks setupConnectivity method works.
*/
@Test
public void testSetupConnectivity() {
Bandwidth bandwidth = Bandwidth.bps(100);
Duration latency = Duration.ofMillis(10);
OpticalConnectivityId cid = target.setupConnectivity(CP12, CP71, bandwidth, latency);
assertNotNull(cid);
// Checks path computation is called as expected
assertEquals(1, pathService.edges.size());
assertEquals(CP12.deviceId(), pathService.edges.get(0).getKey());
assertEquals(CP71.deviceId(), pathService.edges.get(0).getValue());
// Checks intents are installed as expected
assertEquals(1, intentService.submitted.size());
assertEquals(OpticalConnectivityIntent.class, intentService.submitted.get(0).getClass());
OpticalConnectivityIntent connIntent = (OpticalConnectivityIntent) intentService.submitted.get(0);
assertEquals(CP31, connIntent.getSrc());
assertEquals(CP52, connIntent.getDst());
}
/**
* Checks setupPath method works.
*/
@Test
public void testSetupPath() {
Bandwidth bandwidth = Bandwidth.bps(100);
Duration latency = Duration.ofMillis(10);
List<Link> links = Stream.of(LINK1, LINK2, LINK3, LINK4, LINK5, LINK6)
.collect(Collectors.toList());
Path path = new DefaultPath(PROVIDER_ID, links, 0);
OpticalConnectivityId cid = target.setupPath(path, bandwidth, latency);
assertNotNull(cid);
// Checks intents are installed as expected
assertEquals(1, intentService.submitted.size());
assertEquals(OpticalConnectivityIntent.class, intentService.submitted.get(0).getClass());
OpticalConnectivityIntent connIntent = (OpticalConnectivityIntent) intentService.submitted.get(0);
assertEquals(CP31, connIntent.getSrc());
assertEquals(CP52, connIntent.getDst());
}
/**
* Checks removeConnectivity method works.
*/
@Test
public void testRemoveConnectivity() {
Bandwidth bandwidth = Bandwidth.bps(100);
Duration latency = Duration.ofMillis(10);
OpticalConnectivityId cid = target.setupConnectivity(CP12, CP71, bandwidth, latency);
// Checks intents are withdrawn
assertTrue(target.removeConnectivity(cid));
assertEquals(1, intentService.withdrawn.size());
assertEquals(OpticalConnectivityIntent.class, intentService.withdrawn.get(0).getClass());
OpticalConnectivityIntent connIntent = (OpticalConnectivityIntent) intentService.withdrawn.get(0);
assertEquals(CP31, connIntent.getSrc());
assertEquals(CP52, connIntent.getDst());
}
/**
* Checks getPath method works.
*/
@Test
public void testGetPath() {
Bandwidth bandwidth = Bandwidth.bps(100);
Duration latency = Duration.ofMillis(10);
List<Link> links = Stream.of(LINK1, LINK2, LINK3, LINK4, LINK5, LINK6)
.collect(Collectors.toList());
OpticalConnectivityId cid = target.setupConnectivity(CP12, CP71, bandwidth, latency);
Optional<List<Link>> path = target.getPath(cid);
// Checks returned path is as expected
assertTrue(path.isPresent());
assertEquals(links, path.get());
}
/**
* Checks if PATH_INSTALLED event comes up after intent whose master is this node is installed.
*/
@Test
public void testInstalledEventLocal() {
Bandwidth bandwidth = Bandwidth.bps(100);
Duration latency = Duration.ofMillis(10);
OpticalConnectivityId cid = target.setupConnectivity(CP12, CP71, bandwidth, latency);
// notify all intents are installed
intentService.notifyInstalled();
assertEquals(1, listener.events.size());
assertEquals(OpticalPathEvent.Type.PATH_INSTALLED, listener.events.get(0).type());
assertEquals(cid, listener.events.get(0).subject());
}
/**
* Checks if PATH_INSTALLED event comes up after intent whose master is remote node is installed.
*/
@Test
public void testInstalledEventRemote() {
// set the master for ingress device of intent to remote node
mastershipService.setMastership(DEVICE2.id(), MastershipRole.NONE);
Bandwidth bandwidth = Bandwidth.bps(100);
Duration latency = Duration.ofMillis(10);
OpticalConnectivityId cid = target.setupConnectivity(CP12, CP71, bandwidth, latency);
// notify all intents are installed
intentService.notifyInstalled();
// remote nodes must not receive event before distributed map is updated
assertEquals(0, listener.events.size());
}
/**
* Checks if PATH_REMOVED event comes up after packet link is removed.
*/
@Test
public void testRemovedEventLocal() {
Bandwidth bandwidth = Bandwidth.bps(100);
Duration latency = Duration.ofMillis(10);
OpticalConnectivityId cid = target.setupConnectivity(CP12, CP71, bandwidth, latency);
// notify all intents are installed
intentService.notifyInstalled();
target.removeConnectivity(cid);
// notify all intents are withdrawn
intentService.notifyWithdrawn();
// must have received "INSTALLED" and "REMOVED" events
assertEquals(2, listener.events.size());
assertEquals(OpticalPathEvent.Type.PATH_INSTALLED, listener.events.get(0).type());
assertEquals(cid, listener.events.get(0).subject());
assertEquals(OpticalPathEvent.Type.PATH_REMOVED, listener.events.get(1).type());
assertEquals(cid, listener.events.get(1).subject());
}
/**
* Checks if PATH_REMOVED event comes up after packet link is removed.
*/
@Test
public void testRemovedEventRemote() {
// set the master for ingress device of intent to remote node
mastershipService.setMastership(DEVICE2.id(), MastershipRole.NONE);
Bandwidth bandwidth = Bandwidth.bps(100);
Duration latency = Duration.ofMillis(10);
OpticalConnectivityId cid = target.setupConnectivity(CP12, CP71, bandwidth, latency);
// notify all intents are installed
intentService.notifyInstalled();
target.removeConnectivity(cid);
// notify all intents are withdrawn
intentService.notifyWithdrawn();
// remote nodes must not receive event before distributed map is updated
assertEquals(0, listener.events.size());
}
private static ConnectPoint createConnectPoint(long devIdNum, long portIdNum) {
return new ConnectPoint(
deviceIdOf(devIdNum),
PortNumber.portNumber(portIdNum));
}
private static Link createLink(ConnectPoint src, ConnectPoint dst, Link.Type type) {
return DefaultLink.builder()
.providerId(PROVIDER_ID)
.src(src)
.dst(dst)
.state(Link.State.ACTIVE)
.type(type).build();
}
private static Device createDevice(long devIdNum, Device.Type type) {
return new DefaultDevice(PROVIDER_ID,
deviceIdOf(devIdNum),
type,
"manufacturer",
"hwVersion",
"swVersion",
"serialNumber",
new ChassisId(1));
}
private static Port createPacketPort(Device device, ConnectPoint cp) {
return new DefaultPort(device, cp.port(), true);
}
private static Port createOchPort(Device device, ConnectPoint cp) {
return new DefaultOchPort(new DefaultPort(device, cp.port(), true),
OduSignalType.ODU4,
true,
OchSignal.newDwdmSlot(ChannelSpacing.CHL_50GHZ, 1));
}
private static Port createOduCltPort(Device device, ConnectPoint cp) {
return new DefaultOduCltPort(new DefaultPort(device, cp.port(), true),
CltSignalType.CLT_100GBE);
}
private static Port createOmsPort(Device device, ConnectPoint cp) {
return new DefaultOmsPort(new DefaultPort(device, cp.port(), true),
Frequency.ofKHz(3),
Frequency.ofKHz(33),
Frequency.ofKHz(2));
}
private static DeviceId deviceIdOf(long devIdNum) {
return DeviceId.deviceId(String.format("of:%016d", devIdNum));
}
private static class TestListener implements OpticalPathListener {
final List<OpticalPathEvent> events = new ArrayList<>();
@Override
public void event(OpticalPathEvent event) {
events.add(event);
}
}
private static class TestPathService extends PathServiceAdapter {
List<Pair<DeviceId, DeviceId>> edges = new ArrayList<>();
@Override
public Set<Path> getPaths(ElementId src, ElementId dst, LinkWeight weight) {
if (!(src instanceof DeviceId && dst instanceof DeviceId)) {
return Collections.emptySet();
}
edges.add(Pair.of((DeviceId) src, (DeviceId) dst));
Set<Path> paths = new HashSet<>();
List<Link> links = Stream.of(LINK1, LINK2, LINK3, LINK4, LINK5, LINK6)
.collect(Collectors.toList());
paths.add(new DefaultPath(PROVIDER_ID, links, 0));
// returns paths containing single path
return paths;
}
}
private static class TestIntentService extends IntentServiceAdapter {
List<Intent> submitted = new ArrayList<>();
List<Intent> withdrawn = new ArrayList<>();
List<IntentListener> listeners = new ArrayList<>();
@Override
public void submit(Intent intent) {
submitted.add(intent);
}
@Override
public void withdraw(Intent intent) {
withdrawn.add(intent);
}
@Override
public void addListener(IntentListener listener) {
listeners.add(listener);
}
@Override
public Intent getIntent(Key intentKey) {
Intent intent = submitted.stream().filter(i -> i.key().equals(intentKey))
.findAny()
.get();
return intent;
}
void notifyInstalled() {
submitted.forEach(i -> {
IntentEvent event = new IntentEvent(IntentEvent.Type.INSTALLED, i);
listeners.forEach(l -> l.event(event));
});
}
void notifyWithdrawn() {
withdrawn.forEach(i -> {
IntentEvent event = new IntentEvent(IntentEvent.Type.WITHDRAWN, i);
listeners.forEach(l -> l.event(event));
});
}
}
private static class TestLinkService extends LinkServiceAdapter {
List<Link> links = new ArrayList<>();
@Override
public Set<Link> getLinks(ConnectPoint connectPoint) {
return links.stream()
.filter(l -> l.src().equals(connectPoint) || l.dst().equals(connectPoint))
.collect(Collectors.toSet());
}
}
private static class TestCoreService extends CoreServiceAdapter {
@Override
public ApplicationId registerApplication(String name) {
return new DefaultApplicationId(0, name);
}
}
private static class TestMastershipService extends MastershipServiceAdapter {
private Map<DeviceId, MastershipRole> mastershipMap = new HashMap<>();
public void setMastership(DeviceId deviceId, MastershipRole role) {
mastershipMap.put(deviceId, role);
}
public void clear() {
mastershipMap.clear();
}
@Override
public MastershipRole getLocalRole(DeviceId deviceId) {
return mastershipMap.get(deviceId);
}
}
private static class TestClusterService extends ClusterServiceAdapter {
private NodeId nodeId;
public void setLocalNode(String nodeIdStr) {
nodeId = NodeId.nodeId(nodeIdStr);
}
@Override
public ControllerNode getLocalNode() {
return new ControllerNode() {
@Override
public NodeId id() {
return nodeId;
}
@Override
public IpAddress ip() {
return null;
}
@Override
public int tcpPort() {
return 0;
}
};
}
}
private static class TestStorageService extends StorageServiceAdapter {
@Override
public <K, V> ConsistentMapBuilder<K, V> consistentMapBuilder() {
ConsistentMapBuilder<K, V> builder = new ConsistentMapBuilder<K, V>() {
@Override
public AsyncConsistentMap<K, V> buildAsyncMap() {
return null;
}
@Override
public ConsistentMap<K, V> build() {
return new TestConsistentMap<>();
}
};
return builder;
}
@Override
public <E> DistributedSetBuilder<E> setBuilder() {
DistributedSetBuilder<E> builder = new DistributedSetBuilder<E>() {
@Override
public AsyncDistributedSet<E> build() {
return new DistributedSetAdapter<E>() {
@Override
public DistributedSet<E> asDistributedSet() {
return new TestDistributedSet<>();
}
};
}
};
return builder;
}
@Override
public AtomicCounter getAtomicCounter(String name) {
return new MockAtomicCounter();
}
// Mock ConsistentMap that behaves as a HashMap
class TestConsistentMap<K, V> extends ConsistentMapAdapter<K, V> {
private Map<K, Versioned<V>> map = new HashMap<>();
private Map<MapEventListener<K, V>, Executor> listeners = new HashMap<>();
public void notifyListeners(MapEvent<K, V> event) {
listeners.forEach((c, e) -> e.execute(() -> c.event(event)));
}
@Override
public int size() {
return map.size();
}
@Override
public Versioned<V> put(K key, V value) {
Versioned<V> oldValue = map.get(key);
Versioned<V> newValue = new Versioned<>(value, oldValue == null ? 0 : oldValue.version() + 1);
map.put(key, newValue);
notifyListeners(new MapEvent<>(name(), key, newValue, oldValue));
return newValue;
}
@Override
public Versioned<V> get(K key) {
return map.get(key);
}
@Override
public Versioned<V> remove(K key) {
Versioned<V> oldValue = map.remove(key);
notifyListeners(new MapEvent<>(name(), key, oldValue, null));
return oldValue;
}
@Override
public Versioned<V> computeIfPresent(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
Versioned<V> oldValue = map.get(key);
Versioned<V> newValue = new Versioned<>(remappingFunction.apply(key, oldValue.value()),
oldValue == null ? 0 : oldValue.version() + 1);
map.put(key, newValue);
notifyListeners(new MapEvent<>(name(), key, newValue, oldValue));
return newValue;
}
@Override
public Set<Map.Entry<K, Versioned<V>>> entrySet() {
return map.entrySet();
}
@Override
public Set<K> keySet() {
return map.keySet();
}
@Override
public Collection<Versioned<V>> values() {
return map.values();
}
@Override
public void clear() {
map.clear();
}
@Override
public void addListener(MapEventListener<K, V> listener, Executor executor) {
listeners.put(listener, executor);
}
@Override
public void removeListener(MapEventListener<K, V> listener) {
listeners.remove(listener);
}
}
// Mock DistributedSet that behaves as a HashSet
class TestDistributedSet<E> extends HashSet<E> implements DistributedSet<E> {
@Override
public void addListener(SetEventListener<E> listener) {
}
@Override
public void removeListener(SetEventListener<E> listener) {
}
@Override
public String name() {
return null;
}
@Override
public Type primitiveType() {
return null;
}
}
}
private static class TestDeviceService extends DeviceServiceAdapter {
Map<DeviceId, Device> devMap = new HashMap<>();
Map<ConnectPoint, Port> portMap = new HashMap<>();
@Override
public Device getDevice(DeviceId deviceId) {
return devMap.get(deviceId);
}
@Override
public Port getPort(DeviceId deviceId, PortNumber portNumber) {
return portMap.get(new ConnectPoint(deviceId, portNumber));
}
}
private static class TestNetworkConfigService extends NetworkConfigServiceAdapter {
@Override
@SuppressWarnings("unchecked")
public <S, C extends Config<S>> C addConfig(S subject, Class<C> configClass) {
if (BandwidthCapacity.class.equals(configClass)) {
return (C) new BandwidthCapacity() {
@Override
public void apply() {
// do nothing
}
@Override
public BandwidthCapacity capacity(Bandwidth bandwidth) {
// do nothing
return this;
}
};
}
return null;
}
}
private static class TestResourceService implements ResourceService {
@Override
public List<ResourceAllocation> allocate(ResourceConsumer consumer, List<Resource> resources) {
List<ResourceAllocation> allocations = new ArrayList<>();
resources.forEach(r -> allocations.add(new ResourceAllocation(r, consumer.consumerId())));
return allocations;
}
@Override
public boolean release(List<ResourceAllocation> allocations) {
return false;
}
@Override
public boolean release(ResourceConsumer consumer) {
return true;
}
@Override
public void addListener(ResourceListener listener) {
}
@Override
public void removeListener(ResourceListener listener) {
}
@Override
public List<ResourceAllocation> getResourceAllocations(ResourceId id) {
return null;
}
@Override
public <T> Collection<ResourceAllocation> getResourceAllocations(DiscreteResourceId parent, Class<T> cls) {
return null;
}
@Override
public Collection<ResourceAllocation> getResourceAllocations(ResourceConsumer consumer) {
return null;
}
@Override
public Set<Resource> getAvailableResources(DiscreteResourceId parent) {
return null;
}
@Override
public <T> Set<Resource> getAvailableResources(DiscreteResourceId parent, Class<T> cls) {
return null;
}
@Override
public <T> Set<T> getAvailableResourceValues(DiscreteResourceId parent, Class<T> cls) {
return null;
}
@Override
public Set<Resource> getRegisteredResources(DiscreteResourceId parent) {
return null;
}
@Override
public boolean isAvailable(Resource resource) {
return true;
}
}
private static class MockAtomicCounter implements AtomicCounter {
long id = 0;
@Override
public long incrementAndGet() {
return ++id;
}
@Override
public long getAndIncrement() {
return id++;
}
@Override
public long getAndAdd(long delta) {
long oldId = id;
id += delta;
return oldId;
}
@Override
public long addAndGet(long delta) {
id += delta;
return id;
}
@Override
public void set(long value) {
id = value;
}
@Override
public boolean compareAndSet(long expectedValue, long updateValue) {
if (id == expectedValue) {
id = updateValue;
return true;
} else {
return false;
}
}
@Override
public long get() {
return id;
}
@Override
public String name() {
return "MockAtomicCounter";
}
}
// copied from org.onosproject.common.event.impl.TestEventDispatcher
/**
* Implements event delivery system that delivers events synchronously, or
* in-line with the post method invocation.
*/
public class TestEventDispatcher extends DefaultEventSinkRegistry
implements EventDeliveryService {
@Override
@SuppressWarnings("unchecked")
public synchronized void post(Event event) {
EventSink sink = getSink(event.getClass());
checkState(sink != null, "No sink for event %s", event);
sink.process(event);
}
@Override
public void setDispatchTimeLimit(long millis) {
}
@Override
public long getDispatchTimeLimit() {
return 0;
}
}
}