/* * Copyright 2015 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.vtnrsc.util; import java.util.Collection; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.function.BiFunction; import org.onlab.util.KryoNamespace; import org.onosproject.cluster.NodeId; import org.onosproject.store.Timestamp; import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.*; import org.onosproject.store.service.EventuallyConsistentMapListener; import org.onosproject.store.service.EventuallyConsistentMapEvent; import org.onosproject.store.service.EventuallyConsistentMapBuilder; import org.onosproject.store.service.EventuallyConsistentMap; /** * Testing version of an Eventually Consistent Map. */ public final class VtnEventuallyConsistentMapTest extends VtnEventuallyConsistentMapAdapter { private final HashMap map; private final String mapName; private final List> listeners; private final BiFunction> peerUpdateFunction; private VtnEventuallyConsistentMapTest(String mapName, BiFunction> peerUpdateFunction) { map = new HashMap<>(); listeners = new LinkedList<>(); this.mapName = mapName; this.peerUpdateFunction = peerUpdateFunction; } /** * Notify all listeners of an event. */ private void notifyListeners(EventuallyConsistentMapEvent event) { listeners.forEach( listener -> listener.event(event) ); } @Override public int size() { return map.size(); } @Override public boolean isEmpty() { return map.isEmpty(); } @Override public boolean containsKey(K key) { return map.containsKey(key); } @Override public boolean containsValue(V value) { return map.containsValue(value); } @Override public V get(K key) { return map.get(key); } @Override public void put(K key, V value) { map.put(key, value); EventuallyConsistentMapEvent addEvent = new EventuallyConsistentMapEvent<>(mapName, PUT, key, value); notifyListeners(addEvent); if (peerUpdateFunction != null) { peerUpdateFunction.apply(key, value); } } @Override public V remove(K key) { V result = map.remove(key); if (result != null) { EventuallyConsistentMapEvent removeEvent = new EventuallyConsistentMapEvent<>(mapName, REMOVE, key, map.get(key)); notifyListeners(removeEvent); } return result; } @Override public void remove(K key, V value) { boolean removed = map.remove(key, value); if (removed) { EventuallyConsistentMapEvent removeEvent = new EventuallyConsistentMapEvent<>(mapName, REMOVE, key, value); notifyListeners(removeEvent); } } @Override public V compute(K key, BiFunction recomputeFunction) { return map.compute(key, recomputeFunction); } @Override public void putAll(Map m) { map.putAll(m); } @Override public void clear() { map.clear(); } @Override public Set keySet() { return map.keySet(); } @Override public Collection values() { return map.values(); } @Override public Set> entrySet() { return map.entrySet(); } public static Builder builder() { return new Builder<>(); } @Override public void addListener(EventuallyConsistentMapListener listener) { listeners.add(listener); } @Override public void removeListener(EventuallyConsistentMapListener listener) { listeners.remove(listener); } public static class Builder implements EventuallyConsistentMapBuilder { private String name; private BiFunction> peerUpdateFunction; @Override public EventuallyConsistentMapBuilder withName(String name) { this.name = name; return this; } @Override public EventuallyConsistentMapBuilder withSerializer(KryoNamespace.Builder serializerBuilder) { return this; } @Override public EventuallyConsistentMapBuilder withTimestampProvider(BiFunction timestampProvider) { return this; } @Override public EventuallyConsistentMapBuilder withEventExecutor(ExecutorService executor) { return this; } @Override public EventuallyConsistentMapBuilder withCommunicationExecutor(ExecutorService executor) { return this; } @Override public EventuallyConsistentMapBuilder withBackgroundExecutor(ScheduledExecutorService executor) { return this; } @Override public EventuallyConsistentMapBuilder withPeerUpdateFunction(BiFunction> peerUpdateFunction) { this.peerUpdateFunction = peerUpdateFunction; return this; } @Override public EventuallyConsistentMapBuilder withTombstonesDisabled() { return this; } @Override public EventuallyConsistentMapBuilder withAntiEntropyPeriod(long period, TimeUnit unit) { return this; } @Override public EventuallyConsistentMapBuilder withFasterConvergence() { return this; } @Override public EventuallyConsistentMapBuilder withPersistence() { return this; } @Override public EventuallyConsistentMap build() { if (name == null) { name = "test"; } return new VtnEventuallyConsistentMapTest<>(name, peerUpdateFunction); } } }