[ONOS-6073] Implement init version of MappingManager with unit test
Change-Id: Ib2b198e51556bb29e44d20b7bdf9130bbd0aa96d
diff --git a/apps/mappingmanagement/api/src/main/java/org/onosproject/mapping/DefaultMapping.java b/apps/mappingmanagement/api/src/main/java/org/onosproject/mapping/DefaultMapping.java
index 42415ff..17f3ce8 100644
--- a/apps/mappingmanagement/api/src/main/java/org/onosproject/mapping/DefaultMapping.java
+++ b/apps/mappingmanagement/api/src/main/java/org/onosproject/mapping/DefaultMapping.java
@@ -175,7 +175,7 @@
@Override
public Mapping build() {
- checkArgument((id != null) ^ (appId != null), "Either an application" +
+ checkArgument((id != null) || (appId != null), "Either an application" +
" id or a mapping id must be supplied");
checkNotNull(key, "Mapping key cannot be null");
checkNotNull(deviceId, "Must refer to a device");
diff --git a/apps/mappingmanagement/api/src/main/java/org/onosproject/mapping/MappingService.java b/apps/mappingmanagement/api/src/main/java/org/onosproject/mapping/MappingService.java
index e1862e1..e15507f 100644
--- a/apps/mappingmanagement/api/src/main/java/org/onosproject/mapping/MappingService.java
+++ b/apps/mappingmanagement/api/src/main/java/org/onosproject/mapping/MappingService.java
@@ -15,11 +15,76 @@
*/
package org.onosproject.mapping;
+import org.onosproject.core.ApplicationId;
import org.onosproject.event.ListenerService;
+import org.onosproject.mapping.MappingStore.Type;
+import org.onosproject.net.DeviceId;
/**
* Interface of mapping management service.
*/
public interface MappingService
- extends ListenerService<MappingEvent, MappingListener> {
+ extends ListenerService<MappingEvent, MappingListener> {
+
+ /**
+ * Obtains the number of mappings in the system.
+ *
+ * @param type mapping store type
+ * @return mapping count
+ */
+ int getMappingCount(Type type);
+
+ /**
+ * Stores a mapping entry.
+ *
+ * @param type mapping store type
+ * @param entry mapping entry to be stored
+ */
+ void storeMappingEntry(Type type, MappingEntry entry);
+
+ /**
+ * Obtains the collection of mapping entries applied on the specific device.
+ * The will include mapping which may not yet have been applied to device.
+ *
+ * @param type mapping store type
+ * @param deviceId device identifier
+ * @return collection of mapping entries
+ */
+ Iterable<MappingEntry> getMappingEntries(Type type, DeviceId deviceId);
+
+ /**
+ * Obtains the collection of mapping entries with a given application ID.
+ *
+ * @param type mapping store type
+ * @param appId application identifier
+ * @return collection of mapping entries
+ */
+ Iterable<MappingEntry> getMappingEntriesByAddId(Type type, ApplicationId appId);
+
+ /**
+ * Removes the specified mapping entries from their respective devices and
+ * mapping store.
+ *
+ * @param type mapping store type
+ * @param entries one or more mapping entries
+ */
+ void removeMappingEntries(Type type, MappingEntry... entries);
+
+ /**
+ * Removes all mapping entries submitted by a particular application.
+ *
+ * @param type mapping store type
+ * @param appId identifier of application whose mapping entries will be removed
+ */
+ void removeMappingEntriesByAppId(Type type, ApplicationId appId);
+
+ /**
+ * Purges all mappings on the specified device and mapping store.
+ * Note that the mappings will only be removed from storage, the mappings
+ * are still remaining in the device.
+ *
+ * @param type mapping store type
+ * @param deviceId device identifier
+ */
+ void purgeMappings(Type type, DeviceId deviceId);
}
diff --git a/apps/mappingmanagement/api/src/main/java/org/onosproject/mapping/MappingStore.java b/apps/mappingmanagement/api/src/main/java/org/onosproject/mapping/MappingStore.java
index 49d8169..e2d6109 100644
--- a/apps/mappingmanagement/api/src/main/java/org/onosproject/mapping/MappingStore.java
+++ b/apps/mappingmanagement/api/src/main/java/org/onosproject/mapping/MappingStore.java
@@ -79,9 +79,18 @@
* provider indicates that the mapping has been removed.
*
* @param type store type
- * @param mapping the mapping to delete
+ * @param mapping the mapping to be marked as delete
*/
- void deleteMapping(Type type, Mapping mapping);
+ void pendingDeleteMapping(Type type, Mapping mapping);
+
+ /**
+ * Removes an existing mapping from the specified store.
+ *
+ * @param type store type
+ * @param mapping the mapping to remove
+ * @return mapping_removed event, or null if nothing removed
+ */
+ MappingEvent removeMapping(Type type, Mapping mapping);
/**
* Stores a new mapping or updates an existing entry from/to the
@@ -94,15 +103,6 @@
MappingEvent addOrUpdateMappingEntry(Type type, MappingEntry entry);
/**
- * Removes an existing mapping from the specified store.
- *
- * @param type store type
- * @param entry the mapping to remove
- * @return mapping_removed event, or null if nothing removed
- */
- MappingEvent removeMappingEntry(Type type, MappingEntry entry);
-
- /**
* Marks a mapping as PENDING_ADD during retry.
* <p>
* Emits mapping_update event if the state is changed
diff --git a/apps/mappingmanagement/api/src/test/java/org/onosproject/mapping/MappingServiceAdapter.java b/apps/mappingmanagement/api/src/test/java/org/onosproject/mapping/MappingServiceAdapter.java
index 7eb68cb..c767c36 100644
--- a/apps/mappingmanagement/api/src/test/java/org/onosproject/mapping/MappingServiceAdapter.java
+++ b/apps/mappingmanagement/api/src/test/java/org/onosproject/mapping/MappingServiceAdapter.java
@@ -15,6 +15,10 @@
*/
package org.onosproject.mapping;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.mapping.MappingStore.Type;
+import org.onosproject.net.DeviceId;
+
/**
* Adapter for testing against mapping service.
*/
@@ -28,4 +32,39 @@
public void removeListener(MappingListener listener) {
}
+
+ @Override
+ public int getMappingCount(Type type) {
+ return 0;
+ }
+
+ @Override
+ public void storeMappingEntry(Type type, MappingEntry entry) {
+
+ }
+
+ @Override
+ public Iterable<MappingEntry> getMappingEntries(Type type, DeviceId deviceId) {
+ return null;
+ }
+
+ @Override
+ public Iterable<MappingEntry> getMappingEntriesByAddId(Type type, ApplicationId appId) {
+ return null;
+ }
+
+ @Override
+ public void removeMappingEntries(Type type, MappingEntry... mappingEntries) {
+
+ }
+
+ @Override
+ public void removeMappingEntriesByAppId(Type type, ApplicationId appId) {
+
+ }
+
+ @Override
+ public void purgeMappings(Type type, DeviceId deviceId) {
+
+ }
}
diff --git a/apps/mappingmanagement/mgr/src/main/java/org/onosproject/mapping/impl/DistributedMappingStore.java b/apps/mappingmanagement/mgr/src/main/java/org/onosproject/mapping/impl/DistributedMappingStore.java
index 0125fe5..55208ce 100644
--- a/apps/mappingmanagement/mgr/src/main/java/org/onosproject/mapping/impl/DistributedMappingStore.java
+++ b/apps/mappingmanagement/mgr/src/main/java/org/onosproject/mapping/impl/DistributedMappingStore.java
@@ -188,20 +188,20 @@
}
@Override
- public void deleteMapping(Type type, Mapping mapping) {
+ public MappingEvent removeMapping(Type type, Mapping mapping) {
getStore(type).remove(mapping.id());
- }
-
- @Override
- public MappingEvent addOrUpdateMappingEntry(Type type, MappingEntry entry) {
- // TODO: this will be implemented when management plane is ready
- log.error("This method will be available when management plane is ready");
return null;
}
@Override
- public MappingEvent removeMappingEntry(Type type, MappingEntry entry) {
+ public void pendingDeleteMapping(Type type, Mapping mapping) {
+ // TODO: this will be implemented when management plane is ready
+ log.error("This method will be available when management plane is ready");
+ }
+
+ @Override
+ public MappingEvent addOrUpdateMappingEntry(Type type, MappingEntry entry) {
// TODO: this will be implemented when management plane is ready
log.error("This method will be available when management plane is ready");
return null;
diff --git a/apps/mappingmanagement/mgr/src/main/java/org/onosproject/mapping/impl/MappingManager.java b/apps/mappingmanagement/mgr/src/main/java/org/onosproject/mapping/impl/MappingManager.java
index 7668375..72be9e7 100644
--- a/apps/mappingmanagement/mgr/src/main/java/org/onosproject/mapping/impl/MappingManager.java
+++ b/apps/mappingmanagement/mgr/src/main/java/org/onosproject/mapping/impl/MappingManager.java
@@ -15,20 +15,152 @@
*/
package org.onosproject.mapping.impl;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Sets;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.mapping.MappingEntry;
+import org.onosproject.mapping.MappingEvent;
import org.onosproject.mapping.MappingListener;
+import org.onosproject.mapping.MappingProvider;
+import org.onosproject.mapping.MappingProviderRegistry;
+import org.onosproject.mapping.MappingProviderService;
import org.onosproject.mapping.MappingService;
+import org.onosproject.mapping.MappingStore;
+import org.onosproject.mapping.MappingStore.Type;
+import org.onosproject.mapping.MappingStoreDelegate;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.provider.AbstractListenerProviderRegistry;
+import org.onosproject.net.provider.AbstractProviderService;
+import org.slf4j.Logger;
+
+import java.util.Set;
+
+import static org.slf4j.LoggerFactory.getLogger;
/**
* Implementation of mapping management service.
*/
-public class MappingManager implements MappingService {
- @Override
- public void addListener(MappingListener listener) {
+@Component(immediate = true)
+@Service
+public class MappingManager
+ extends AbstractListenerProviderRegistry<MappingEvent, MappingListener,
+ MappingProvider, MappingProviderService>
+ implements MappingService, MappingProviderRegistry {
+ private final Logger log = getLogger(getClass());
+
+ private static final String MAPPING_OP_TOPIC = "mapping-ops-ids";
+ private final MappingStoreDelegate delegate = new InternalStoreDelegate();
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected MappingStore store;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected DeviceService deviceService;
+
+ @Activate
+ public void activate() {
+ store.setDelegate(delegate);
+ eventDispatcher.addSink(MappingEvent.class, listenerRegistry);
+ log.info("Started");
+ }
+
+ @Deactivate
+ public void deactivate() {
+ store.unsetDelegate(delegate);
+ eventDispatcher.removeSink(MappingEvent.class);
+ log.info("Stopped");
}
@Override
- public void removeListener(MappingListener listener) {
+ public int getMappingCount(Type type) {
+ return store.getMappingCount(type);
+ }
+ @Override
+ public void storeMappingEntry(Type type, MappingEntry entry) {
+ store.storeMapping(type, entry);
+ }
+
+ @Override
+ public Iterable<MappingEntry> getMappingEntries(Type type, DeviceId deviceId) {
+ return store.getMappingEntries(type, deviceId);
+ }
+
+ @Override
+ public Iterable<MappingEntry> getMappingEntriesByAddId(Type type, ApplicationId appId) {
+
+ Set<MappingEntry> mappingEntries = Sets.newHashSet();
+ for (Device d : deviceService.getDevices()) {
+ for (MappingEntry mappingEntry : store.getMappingEntries(type, d.id())) {
+ if (mappingEntry.appId() == appId.id()) {
+ mappingEntries.add(mappingEntry);
+ }
+ }
+ }
+ return mappingEntries;
+ }
+
+ @Override
+ public void removeMappingEntries(Type type, MappingEntry... mappingEntries) {
+ for (MappingEntry entry : mappingEntries) {
+ store.removeMapping(type, entry);
+ }
+ }
+
+ @Override
+ public void removeMappingEntriesByAppId(Type type, ApplicationId appId) {
+ removeMappingEntries(type, Iterables.toArray(
+ getMappingEntriesByAddId(type, appId), MappingEntry.class));
+ }
+
+ @Override
+ public void purgeMappings(Type type, DeviceId deviceId) {
+ store.purgeMappingEntry(type, deviceId);
+ }
+
+ @Override
+ protected MappingProviderService createProviderService(MappingProvider provider) {
+ return new InternalMappingProviderService(provider);
+ }
+
+ /**
+ * Store delegate.
+ */
+ private class InternalStoreDelegate implements MappingStoreDelegate {
+
+ @Override
+ public void notify(MappingEvent event) {
+ post(event);
+ }
+ }
+
+ /**
+ * Internal mapping provider service.
+ */
+ private class InternalMappingProviderService
+ extends AbstractProviderService<MappingProvider> implements MappingProviderService {
+
+ /**
+ * Initializes internal mapping provider service.
+ *
+ * @param provider mapping provider
+ */
+ protected InternalMappingProviderService(MappingProvider provider) {
+ super(provider);
+ }
+
+ @Override
+ public void mappingAdded(MappingEntry mappingEntry, Type type) {
+ storeMappingEntry(type, mappingEntry);
+ }
}
}
diff --git a/apps/mappingmanagement/mgr/src/main/java/org/onosproject/mapping/impl/SimpleMappingStore.java b/apps/mappingmanagement/mgr/src/main/java/org/onosproject/mapping/impl/SimpleMappingStore.java
index 17b403f..c349423 100644
--- a/apps/mappingmanagement/mgr/src/main/java/org/onosproject/mapping/impl/SimpleMappingStore.java
+++ b/apps/mappingmanagement/mgr/src/main/java/org/onosproject/mapping/impl/SimpleMappingStore.java
@@ -225,7 +225,7 @@
}
@Override
- public void deleteMapping(Type type, Mapping mapping) {
+ public void pendingDeleteMapping(Type type, Mapping mapping) {
List<StoredMappingEntry> entries =
getMappingEntriesInternal(type, mapping.deviceId(), mapping.id());
@@ -264,13 +264,13 @@
}
@Override
- public MappingEvent removeMappingEntry(Type type, MappingEntry entry) {
+ public MappingEvent removeMapping(Type type, Mapping mapping) {
List<StoredMappingEntry> entries =
- getMappingEntriesInternal(type, entry.deviceId(), entry.id());
+ getMappingEntriesInternal(type, mapping.deviceId(), mapping.id());
synchronized (entries) {
- if (entries.remove(entry)) {
- return new MappingEvent(MAPPING_REMOVED, entry);
+ if (entries.remove(mapping)) {
+ return new MappingEvent(MAPPING_REMOVED, mapping);
}
}
return null;
diff --git a/apps/mappingmanagement/mgr/src/test/java/org/onosproject/mapping/impl/DistributedMappingStoreTest.java b/apps/mappingmanagement/mgr/src/test/java/org/onosproject/mapping/impl/DistributedMappingStoreTest.java
index 57b7ed3..9246f6d 100644
--- a/apps/mappingmanagement/mgr/src/test/java/org/onosproject/mapping/impl/DistributedMappingStoreTest.java
+++ b/apps/mappingmanagement/mgr/src/test/java/org/onosproject/mapping/impl/DistributedMappingStoreTest.java
@@ -164,7 +164,7 @@
.iterator().next()));
assertTrue("The mapping1 should be identical.",
mappingStore.getMappingEntry(MAP_DATABASE, mapping1).equals(mapping1));
- mappingStore.deleteMapping(MAP_DATABASE, mapping1);
+ mappingStore.removeMapping(MAP_DATABASE, mapping1);
assertFalse("There should not be any mapping1 in the map database.",
mappingStore.getMappingEntries(MAP_DATABASE, DEVICE_ID_1).iterator().hasNext());
}
diff --git a/apps/mappingmanagement/mgr/src/test/java/org/onosproject/mapping/impl/MappingManagerTest.java b/apps/mappingmanagement/mgr/src/test/java/org/onosproject/mapping/impl/MappingManagerTest.java
new file mode 100644
index 0000000..54fc652
--- /dev/null
+++ b/apps/mappingmanagement/mgr/src/test/java/org/onosproject/mapping/impl/MappingManagerTest.java
@@ -0,0 +1,380 @@
+/*
+ * Copyright 2017-present 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.mapping.impl;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.common.event.impl.TestEventDispatcher;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.mapping.DefaultMapping;
+import org.onosproject.mapping.DefaultMappingEntry;
+import org.onosproject.mapping.Mapping;
+import org.onosproject.mapping.MappingEntry;
+import org.onosproject.mapping.MappingEvent;
+import org.onosproject.mapping.MappingKey;
+import org.onosproject.mapping.MappingListener;
+import org.onosproject.mapping.MappingProvider;
+import org.onosproject.mapping.MappingProviderRegistry;
+import org.onosproject.mapping.MappingProviderService;
+import org.onosproject.mapping.MappingService;
+import org.onosproject.mapping.MappingStore.Type;
+import org.onosproject.mapping.MappingTreatment;
+import org.onosproject.mapping.MappingValue;
+import org.onosproject.mapping.actions.MappingAction;
+import org.onosproject.mapping.addresses.MappingAddress;
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.device.DeviceServiceAdapter;
+import org.onosproject.net.provider.AbstractProvider;
+import org.onosproject.net.provider.ProviderId;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.onosproject.mapping.MappingStore.Type.MAP_DATABASE;
+import static org.onosproject.net.NetTestTools.injectEventDispatcher;
+
+/**
+ * Unit tests for mapping manager.
+ */
+public class MappingManagerTest {
+
+ private static final ProviderId LISP_PID = new ProviderId("lisp", "lisp");
+ private static final ProviderId BAR_PID = new ProviderId("bar", "bar");
+
+ private static final DeviceId LISP_DID = DeviceId.deviceId("lisp:001");
+ private static final DeviceId BAR_DID = DeviceId.deviceId("bar:002");
+
+ private static final DefaultAnnotations ANNOTATIONS =
+ DefaultAnnotations.builder().set(AnnotationKeys.DRIVER, "bar").build();
+
+ private static final Device LISP_DEV =
+ new DefaultDevice(LISP_PID, LISP_DID, Device.Type.SWITCH, "", "", "", "", null);
+ private static final Device BAR_DEV =
+ new DefaultDevice(BAR_PID, BAR_DID, Device.Type.SWITCH, "", "", "", "", null, ANNOTATIONS);
+
+
+ private MappingManager manager;
+
+ private MappingService service;
+ private MappingProviderRegistry registry;
+ private MappingProviderService providerService;
+ private TestProvider provider;
+ private TestListener listener = new TestListener();
+ private ApplicationId appId;
+
+ @Before
+ public void setUp() {
+ manager = new MappingManager();
+ manager.store = new SimpleMappingStore();
+ injectEventDispatcher(manager, new TestEventDispatcher());
+ manager.deviceService = new TestDeviceService();
+
+ service = manager;
+ registry = manager;
+
+ manager.activate();
+ manager.addListener(listener);
+ provider = new TestProvider(LISP_PID);
+ providerService = registry.register(provider);
+ appId = new TestApplicationId(0, "MappingManagerTest");
+ assertTrue("provider should be registered",
+ registry.getProviders().contains(provider.id()));
+ }
+
+ @After
+ public void tearDown() {
+ registry.unregister(provider);
+ assertFalse("provider should not be registered",
+ registry.getProviders().contains(provider.id()));
+ service.removeListener(listener);
+ manager.deactivate();
+ injectEventDispatcher(manager, null);
+ manager.deviceService = null;
+ }
+
+ /**
+ * Creates a mapping from a specified deviceID, key and value.
+ *
+ * @param did device identifier
+ * @param key test value for mapping key
+ * @param value test value for mapping value
+ * @return mapping instance
+ */
+ private Mapping mapping(DeviceId did, int key, int value) {
+ TestMappingKey mappingKey = new TestMappingKey(key);
+ TestMappingValue mappingValue = new TestMappingValue(value);
+
+ return DefaultMapping.builder()
+ .forDevice(did)
+ .withKey(mappingKey)
+ .withValue(mappingValue)
+ .fromApp(appId)
+ .withId(key + value)
+ .build();
+ }
+
+ /**
+ * Creates a mapping from a specified key and value.
+ *
+ * @param key test value for mapping key
+ * @param value test value for mapping value
+ * @return mapping instance
+ */
+ private Mapping mapping(int key, int value) {
+ return mapping(LISP_DID, key, value);
+ }
+
+ /**
+ * Adds a new mapping into the mapping store.
+ *
+ * @param type mapping store type
+ * @param tval test value
+ * @return a mapping that has been added to the store
+ */
+ private Mapping addMapping(Type type, int tval) {
+ Mapping mapping = mapping(tval, tval);
+ MappingEntry entry = new DefaultMappingEntry(mapping);
+ service.storeMappingEntry(type, entry);
+
+ assertNotNull("mapping should be found",
+ service.getMappingEntries(type, LISP_DID));
+ return mapping;
+ }
+
+ /**
+ * Obtains the number of mappings.
+ *
+ * @param type mapping store type
+ * @return number of mappings
+ */
+ private int mappingCount(Type type) {
+ return Sets.newHashSet(service.getMappingEntries(type, LISP_DID)).size();
+ }
+
+ /**
+ * Tests retrieving mapping entries method.
+ */
+ @Test
+ public void getMappingEntries() {
+
+ assertTrue("Store should be empty", Sets.newHashSet(
+ service.getMappingEntries(MAP_DATABASE, LISP_DID)).isEmpty());
+ addMapping(MAP_DATABASE, 1);
+ addMapping(MAP_DATABASE, 2);
+ assertEquals("2 mappings should exist", 2, mappingCount(MAP_DATABASE));
+
+ addMapping(MAP_DATABASE, 1);
+ assertEquals("should still be 2 mappings", 2, mappingCount(MAP_DATABASE));
+ }
+
+ /**
+ * Tests storing mapping entry method.
+ */
+ @Test
+ public void storeMappingEntry() {
+
+ Mapping m1 = mapping(1, 1);
+ Mapping m2 = mapping(2, 2);
+ Mapping m3 = mapping(3, 3);
+
+ MappingEntry me1 = new DefaultMappingEntry(m1);
+ MappingEntry me2 = new DefaultMappingEntry(m2);
+ MappingEntry me3 = new DefaultMappingEntry(m3);
+
+ assertTrue("store should be empty", Sets.newHashSet(
+ service.getMappingEntries(MAP_DATABASE, LISP_DID)).isEmpty());
+ service.storeMappingEntry(MAP_DATABASE, me1);
+ service.storeMappingEntry(MAP_DATABASE, me2);
+ service.storeMappingEntry(MAP_DATABASE, me3);
+ assertEquals("3 mappings should exist", 3, mappingCount(MAP_DATABASE));
+ }
+
+ /**
+ * Tests removing mapping entries method.
+ */
+ @Test
+ public void removeMappingEntries() {
+
+ Mapping m1 = addMapping(MAP_DATABASE, 1);
+ Mapping m2 = addMapping(MAP_DATABASE, 2);
+ addMapping(MAP_DATABASE, 3);
+ assertEquals("3 mappings should exist", 3, mappingCount(MAP_DATABASE));
+
+ MappingEntry me1 = new DefaultMappingEntry(m1);
+ MappingEntry me2 = new DefaultMappingEntry(m2);
+
+ service.removeMappingEntries(MAP_DATABASE, me1, me2);
+ assertEquals("1 mappings should exist", 1, mappingCount(MAP_DATABASE));
+ }
+
+ /**
+ * Tests purging all mappings.
+ */
+ @Test
+ public void purgeMappings() {
+
+ addMapping(MAP_DATABASE, 1);
+ addMapping(MAP_DATABASE, 2);
+ addMapping(MAP_DATABASE, 3);
+ assertEquals("3 mappings should exist", 3, mappingCount(MAP_DATABASE));
+
+ service.purgeMappings(MAP_DATABASE, LISP_DID);
+ assertEquals("0 mappings should exist", 0, mappingCount(MAP_DATABASE));
+ }
+
+ /**
+ * Tests obtaining mapping entries by application ID.
+ */
+ @Test
+ public void getMappingEntriesByAddId() {
+ addMapping(MAP_DATABASE, 1);
+ addMapping(MAP_DATABASE, 2);
+
+ assertTrue("should have two mappings",
+ Lists.newLinkedList(
+ service.getMappingEntriesByAddId(MAP_DATABASE, appId)).size() == 2);
+ }
+
+ /**
+ * Tests removing mapping entries by application ID.
+ */
+ @Test
+ public void removeMappingEntriesByAppId() {
+ addMapping(MAP_DATABASE, 1);
+ addMapping(MAP_DATABASE, 2);
+
+ service.removeMappingEntriesByAppId(MAP_DATABASE, appId);
+
+ assertTrue("should not have any mappings",
+ Lists.newLinkedList(
+ service.getMappingEntriesByAddId(MAP_DATABASE, appId)).size() == 0);
+ }
+
+ private static class TestDeviceService extends DeviceServiceAdapter {
+ @Override
+ public int getDeviceCount() {
+ return 2;
+ }
+
+ @Override
+ public Iterable<Device> getDevices() {
+ return ImmutableList.of(LISP_DEV, BAR_DEV);
+ }
+
+ @Override
+ public Iterable<Device> getAvailableDevices() {
+ return getDevices();
+ }
+
+ @Override
+ public Device getDevice(DeviceId deviceId) {
+ return deviceId.equals(BAR_DID) ? BAR_DEV : LISP_DEV;
+ }
+ }
+
+ private static class TestListener implements MappingListener {
+ final List<MappingEvent> events = new ArrayList<>();
+
+ @Override
+ public void event(MappingEvent event) {
+ events.add(event);
+ }
+ }
+
+ private class TestProvider extends AbstractProvider implements MappingProvider {
+
+ /**
+ * Creates a provider with the supplied identifier.
+ *
+ * @param id provider id
+ */
+ TestProvider(ProviderId id) {
+ super(id);
+ }
+ }
+
+ private class TestApplicationId extends DefaultApplicationId {
+ TestApplicationId(int id, String name) {
+ super(id, name);
+ }
+ }
+
+ private class TestMappingKey implements MappingKey {
+
+ private final int val;
+
+ TestMappingKey(int val) {
+ this.val = val;
+ }
+
+ @Override
+ public MappingAddress address() {
+ return null;
+ }
+
+ @Override
+ public int hashCode() {
+ return val;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return o instanceof TestMappingKey && this.val == ((TestMappingKey) o).val;
+ }
+ }
+
+ private class TestMappingValue implements MappingValue {
+
+ private final int val;
+
+ TestMappingValue(int val) {
+ this.val = val;
+ }
+
+ @Override
+ public MappingAction action() {
+ return null;
+ }
+
+ @Override
+ public List<MappingTreatment> treatments() {
+ return null;
+ }
+
+ @Override
+ public int hashCode() {
+ return val;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return o instanceof TestMappingValue && this.val == ((TestMappingValue) o).val;
+ }
+ }
+}