diff --git a/core/api/src/main/java/org/onosproject/security/AppPermission.java b/core/api/src/main/java/org/onosproject/security/AppPermission.java index 09fe17a817..2eafb7c7c5 100644 --- a/core/api/src/main/java/org/onosproject/security/AppPermission.java +++ b/core/api/src/main/java/org/onosproject/security/AppPermission.java @@ -34,6 +34,9 @@ public class AppPermission extends BasicPermission { CLUSTER_READ, CLUSTER_WRITE, CLUSTER_EVENT, + DEVICE_KEY_EVENT, + DEVICE_KEY_READ, + DEVICE_KEY_WRITE, DEVICE_READ, DEVICE_EVENT, DRIVER_READ, diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/key/DeviceKeyId.java b/incubator/api/src/main/java/org/onosproject/incubator/net/key/DeviceKeyId.java index 2ec5c60315..a4bdac7b09 100644 --- a/incubator/api/src/main/java/org/onosproject/incubator/net/key/DeviceKeyId.java +++ b/incubator/api/src/main/java/org/onosproject/incubator/net/key/DeviceKeyId.java @@ -48,7 +48,7 @@ public final class DeviceKeyId { * @param id for the device key identifier * @return device key identifier */ - static final DeviceKeyId deviceKeyId(String id) { + public static final DeviceKeyId deviceKeyId(String id) { return new DeviceKeyId(id); } diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/key/DeviceKeyService.java b/incubator/api/src/main/java/org/onosproject/incubator/net/key/DeviceKeyService.java index 03723599df..b869aebad7 100644 --- a/incubator/api/src/main/java/org/onosproject/incubator/net/key/DeviceKeyService.java +++ b/incubator/api/src/main/java/org/onosproject/incubator/net/key/DeviceKeyService.java @@ -17,26 +17,29 @@ package org.onosproject.incubator.net.key; import com.google.common.annotations.Beta; +import org.onosproject.event.ListenerService; + +import java.util.Collection; /** * Service for querying device keys. */ @Beta -public interface DeviceKeyService { +public interface DeviceKeyService extends ListenerService { /** * Returns all device keys. * - * @return collection of device keys + * @return Collection of device keys */ - Iterable getDeviceKeys(); + Collection getDeviceKeys(); /** - * Returns the device key(s) using a device key identifier. + * Returns the device key using a device key identifier. * - * @param id device key identifier - * @return collection of device keys + * @param deviceKeyId device key identifier + * @return device key */ - Iterable getDeviceKey(DeviceKeyId id); + DeviceKey getDeviceKey(DeviceKeyId deviceKeyId); } diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/key/DeviceKeyStore.java b/incubator/api/src/main/java/org/onosproject/incubator/net/key/DeviceKeyStore.java index f25b662b73..d25c28f343 100644 --- a/incubator/api/src/main/java/org/onosproject/incubator/net/key/DeviceKeyStore.java +++ b/incubator/api/src/main/java/org/onosproject/incubator/net/key/DeviceKeyStore.java @@ -19,6 +19,8 @@ package org.onosproject.incubator.net.key; import com.google.common.annotations.Beta; import org.onosproject.store.Store; +import java.util.Collection; + /** * Manages inventory of device keys; not intended for direct use. */ @@ -28,15 +30,28 @@ public interface DeviceKeyStore extends Store getDeviceKeys(); + + /** + * Returns the device key matching a device key identifier. + * + * @param deviceKeyId device key unique identifier + * @return device key + */ + DeviceKey getDeviceKey(DeviceKeyId deviceKeyId); } diff --git a/incubator/net/src/main/java/org/onosproject/incubator/net/key/impl/DeviceKeyManager.java b/incubator/net/src/main/java/org/onosproject/incubator/net/key/impl/DeviceKeyManager.java new file mode 100644 index 0000000000..91d1364e69 --- /dev/null +++ b/incubator/net/src/main/java/org/onosproject/incubator/net/key/impl/DeviceKeyManager.java @@ -0,0 +1,99 @@ +/* + * 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.incubator.net.key.impl; + +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.onosproject.event.AbstractListenerManager; +import org.onosproject.incubator.net.key.DeviceKey; +import org.onosproject.incubator.net.key.DeviceKeyAdminService; +import org.onosproject.incubator.net.key.DeviceKeyEvent; +import org.onosproject.incubator.net.key.DeviceKeyId; +import org.onosproject.incubator.net.key.DeviceKeyListener; +import org.onosproject.incubator.net.key.DeviceKeyService; +import org.onosproject.incubator.net.key.DeviceKeyStore; +import org.onosproject.incubator.net.key.DeviceKeyStoreDelegate; +import org.slf4j.Logger; + +import java.util.Collection; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.onosproject.security.AppGuard.checkPermission; +import static org.onosproject.security.AppPermission.Type.DEVICE_KEY_READ; +import static org.onosproject.security.AppPermission.Type.DEVICE_KEY_WRITE; +import static org.slf4j.LoggerFactory.getLogger; + +/** + * Implementation of device key services. + */ +public class DeviceKeyManager extends AbstractListenerManager + implements DeviceKeyService, DeviceKeyAdminService { + + private final Logger log = getLogger(getClass()); + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected DeviceKeyService deviceKeyService; + + private DeviceKeyStoreDelegate delegate = this::post; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected DeviceKeyStore store; + + @Activate + public void activate() { + store.setDelegate(delegate); + eventDispatcher.addSink(DeviceKeyEvent.class, listenerRegistry); + log.info("Started"); + } + + @Deactivate + public void deactivate() { + store.unsetDelegate(delegate); + eventDispatcher.removeSink(DeviceKeyEvent.class); + log.info("Stopped"); + } + + @Override + public void addKey(DeviceKey deviceKey) { + checkPermission(DEVICE_KEY_WRITE); + checkNotNull(deviceKey, "Device key cannot be null"); + store.createOrUpdateDeviceKey(deviceKey); + } + + @Override + public void removeKey(DeviceKeyId deviceKeyId) { + checkPermission(DEVICE_KEY_WRITE); + checkNotNull(deviceKeyId, "Device key identifier cannot be null"); + store.deleteDeviceKey(deviceKeyId); + } + + @Override + public Collection getDeviceKeys() { + checkPermission(DEVICE_KEY_READ); + return store.getDeviceKeys(); + } + + @Override + public DeviceKey getDeviceKey(DeviceKeyId deviceKeyId) { + checkPermission(DEVICE_KEY_READ); + checkNotNull(deviceKeyId, "Device key identifier cannot be null"); + return store.getDeviceKey(deviceKeyId); + } +} + diff --git a/incubator/net/src/main/java/org/onosproject/incubator/net/key/impl/package-info.java b/incubator/net/src/main/java/org/onosproject/incubator/net/key/impl/package-info.java new file mode 100644 index 0000000000..261176c3aa --- /dev/null +++ b/incubator/net/src/main/java/org/onosproject/incubator/net/key/impl/package-info.java @@ -0,0 +1,20 @@ +/* + * 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. + */ + +/** + * Implementation of device key subsystem. + */ +package org.onosproject.incubator.net.key.impl; diff --git a/incubator/net/src/test/java/org/onosproject/incubator/net/key/impl/DeviceKeyManagerTest.java b/incubator/net/src/test/java/org/onosproject/incubator/net/key/impl/DeviceKeyManagerTest.java new file mode 100644 index 0000000000..4a1519173f --- /dev/null +++ b/incubator/net/src/test/java/org/onosproject/incubator/net/key/impl/DeviceKeyManagerTest.java @@ -0,0 +1,210 @@ +/* + * 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.incubator.net.key.impl; + +import com.google.common.collect.Lists; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onlab.junit.TestTools; +import org.onlab.junit.TestUtils; +import org.onosproject.common.event.impl.TestEventDispatcher; +import org.onosproject.event.Event; +import org.onosproject.incubator.net.key.DeviceKey; +import org.onosproject.incubator.net.key.DeviceKeyEvent; +import org.onosproject.incubator.net.key.DeviceKeyId; +import org.onosproject.incubator.net.key.DeviceKeyListener; +import org.onosproject.incubator.net.key.DeviceKeyService; +import org.onosproject.incubator.store.key.impl.DistributedDeviceKeyStore; +import org.onosproject.net.NetTestTools; +import org.onosproject.store.service.TestStorageService; + +import java.util.Collection; +import java.util.List; + +import static org.junit.Assert.*; + +/** + * Tests for DeviceKeyManager. + */ +public class DeviceKeyManagerTest { + + final String deviceKeyIdValue = "DeviceKeyId"; + final String deviceKeyLabel = "DeviceKeyLabel"; + final String deviceKeyLabel2 = "DeviceKeyLabel2"; + final String deviceKeySnmpName = "DeviceKeySnmpName"; + + private DeviceKeyManager manager; + private DeviceKeyService deviceKeyService; + private DistributedDeviceKeyStore deviceKeyStore; + protected TestListener listener = new TestListener(); + + @Before + public void setUp() throws Exception { + deviceKeyStore = new DistributedDeviceKeyStore(); + TestUtils.setField(deviceKeyStore, "storageService", new TestStorageService()); + deviceKeyStore.activate(); + + manager = new DeviceKeyManager(); + manager.store = deviceKeyStore; + manager.addListener(listener); + NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher()); + manager.activate(); + deviceKeyService = manager; + } + + @After + public void tearDown() { + deviceKeyStore.deactivate(); + manager.removeListener(listener); + manager.deactivate(); + NetTestTools.injectEventDispatcher(manager, null); + } + + /** + * Tests adding, query and removal of a device key. + */ + @Test(expected = NullPointerException.class) + public void testAddNullKey() { + manager.addKey(null); + } + + /** + * Tests adding a device key using the device key manager. + * This also tests the device key manager query methods. + */ + @Test + public void testAddKey() { + DeviceKeyId deviceKeyId = DeviceKeyId.deviceKeyId(deviceKeyIdValue); + + DeviceKey deviceKey = DeviceKey.createDeviceKeyUsingCommunityName(deviceKeyId, + deviceKeyLabel, deviceKeySnmpName); + + // Test to make sure that the device key store is empty + Collection deviceKeys = manager.getDeviceKeys(); + assertTrue("The device key set should be empty.", deviceKeys.isEmpty()); + + // Add the new device key using the device key manager. + manager.addKey(deviceKey); + + // Test the getDeviceKeys method to make sure that the new device key exists + deviceKeys = manager.getDeviceKeys(); + assertEquals("There should be one device key in the set.", deviceKeys.size(), 1); + + // Test the getDeviceKey method using the device key unique identifier + deviceKey = manager.getDeviceKey(deviceKeyId); + assertEquals("There should be one device key in the set.", deviceKeys.size(), 1); + + // Validate that only the DEVICE_KEY_ADDED event was received. + validateEvents(DeviceKeyEvent.Type.DEVICE_KEY_ADDED); + + } + + /** + * Tests re-adding the same device key to the store but with a different label. + */ + @Test + public void testAddSameKey() { + DeviceKeyId deviceKeyId = DeviceKeyId.deviceKeyId(deviceKeyIdValue); + + DeviceKey deviceKey = DeviceKey.createDeviceKeyUsingCommunityName(deviceKeyId, + deviceKeyLabel, deviceKeySnmpName); + + // Add the first device key via the device key manager + manager.addKey(deviceKey); + + // Test the getDeviceKeys method + Collection deviceKeys = manager.getDeviceKeys(); + assertEquals("There should be one device key in the set.", deviceKeys.size(), 1); + + // Now let's create a new device key with the same device key identifier as exists in the store. + DeviceKey deviceKey2 = DeviceKey.createDeviceKeyUsingCommunityName(deviceKeyId, + deviceKeyLabel2, deviceKeySnmpName); + + // Replace the new device key in the store + manager.addKey(deviceKey2); + + // Test the getDeviceKeys method to ensure that only 1 device key exists in the store. + deviceKeys = manager.getDeviceKeys(); + assertEquals("There should be one device key in the set.", deviceKeys.size(), 1); + + // Test the getDeviceKey method using the device key unique identifier + deviceKey = manager.getDeviceKey(deviceKeyId); + assertNotNull("The device key should not be null.", deviceKey); + assertEquals("The device key label should match.", deviceKeyLabel2, deviceKey.label()); + + // Validate that the following events were received in order, + // DEVICE_KEY_ADDED, DEVICE_KEY_REMOVED, DEVICE_KEY_ADDED. + validateEvents(DeviceKeyEvent.Type.DEVICE_KEY_ADDED, DeviceKeyEvent.Type.DEVICE_KEY_UPDATED); + + } + + /** + * Tests removal of a device key from the store using the device key identifier. + */ + @Test + public void testRemoveKey() { + DeviceKeyId deviceKeyId = DeviceKeyId.deviceKeyId(deviceKeyIdValue); + DeviceKey deviceKey = DeviceKey.createDeviceKeyUsingCommunityName(deviceKeyId, + deviceKeyLabel, deviceKeySnmpName); + // Add the new device key using the device key manager + manager.addKey(deviceKey); + + // Remove the device key from the store + manager.removeKey(deviceKeyId); + + // Validate that the device key was removed from the store by querying it. + deviceKey = manager.getDeviceKey(deviceKeyId); + assertNull("The device key set should be empty.", deviceKey); + + // Validate that the following events were received in order, + // DEVICE_KEY_ADDED, DEVICE_KEY_REMOVED. + validateEvents(DeviceKeyEvent.Type.DEVICE_KEY_ADDED, DeviceKeyEvent.Type.DEVICE_KEY_REMOVED); + } + + /** + * Method to validate that actual versus expected device key events were + * received correctly. + * + * @param types expected device key events. + */ + private void validateEvents(Enum... types) { + TestTools.assertAfter(100, () -> { + int i = 0; + assertEquals("wrong events received", types.length, listener.events.size()); + for (Event event : listener.events) { + assertEquals("incorrect event type", types[i], event.type()); + i++; + } + listener.events.clear(); + }); + } + + /** + * Test listener class to receive device key events. + */ + private static class TestListener implements DeviceKeyListener { + + protected List events = Lists.newArrayList(); + + @Override + public void event(DeviceKeyEvent event) { + events.add(event); + } + + } +} diff --git a/incubator/store/src/main/java/org/onosproject/incubator/store/key/impl/DistributedDeviceKeyStore.java b/incubator/store/src/main/java/org/onosproject/incubator/store/key/impl/DistributedDeviceKeyStore.java new file mode 100644 index 0000000000..eaaf59711b --- /dev/null +++ b/incubator/store/src/main/java/org/onosproject/incubator/store/key/impl/DistributedDeviceKeyStore.java @@ -0,0 +1,142 @@ +/* + * 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.incubator.store.key.impl; + +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.incubator.net.key.DeviceKey; +import org.onosproject.incubator.net.key.DeviceKeyEvent; +import org.onosproject.incubator.net.key.DeviceKeyId; +import org.onosproject.incubator.net.key.DeviceKeyStore; +import org.onosproject.incubator.net.key.DeviceKeyStoreDelegate; +import org.onosproject.store.AbstractStore; +import org.onosproject.store.serializers.KryoNamespaces; +import org.onosproject.store.service.ConsistentMap; +import org.onosproject.store.service.MapEvent; +import org.onosproject.store.service.MapEventListener; +import org.onosproject.store.service.Serializer; +import org.onosproject.store.service.StorageService; +import org.slf4j.Logger; + +import java.util.Collection; +import java.util.Map; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.slf4j.LoggerFactory.getLogger; + +/** + * A distributed device key store implementation, device keys are stored consistently + * across the cluster. + */ +@Component(immediate = true) +@Service +public class DistributedDeviceKeyStore + extends AbstractStore + implements DeviceKeyStore { + + private final Logger log = getLogger(getClass()); + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected StorageService storageService; + + private ConsistentMap deviceKeys; + private Map deviceKeysMap; + + private final MapEventListener listener = new InternalMapListener(); + + /** + * Activate the distributed device key store. + */ + @Activate + public void activate() { + deviceKeys = storageService.consistentMapBuilder() + .withSerializer(Serializer.using(KryoNamespaces.API)) + .withName("onos-device-keys") + .withRelaxedReadConsistency() + .build(); + deviceKeys.addListener(listener); + deviceKeysMap = deviceKeys.asJavaMap(); + + log.info("Started"); + } + + /** + * Deactivate the distributed device key store. + */ + @Deactivate + public void deactivate() { + deviceKeys.removeListener(listener); + log.info("Stopped"); + } + + @Override + public void createOrUpdateDeviceKey(DeviceKey deviceKey) { + + // Add the device key to the store, if the device key already exists + // then it will be replaced with the new one. + deviceKeys.put(deviceKey.deviceKeyId(), deviceKey); + } + + @Override + public void deleteDeviceKey(DeviceKeyId deviceKeyId) { + // Remove the device key from the store if the device key identifier exists. + deviceKeys.remove(deviceKeyId); + } + + @Override + public Collection getDeviceKeys() { + return deviceKeysMap.values(); + } + + @Override + public DeviceKey getDeviceKey(DeviceKeyId deviceKeyId) { + return deviceKeysMap.get(deviceKeyId); + } + + /** + * Listener class to map listener events to the device key events. + */ + private class InternalMapListener implements MapEventListener { + @Override + public void event(MapEvent event) { + DeviceKey deviceKey = null; + + DeviceKeyEvent.Type type = null; + switch (event.type()) { + case INSERT: + type = DeviceKeyEvent.Type.DEVICE_KEY_ADDED; + deviceKey = checkNotNull(event.newValue().value()); + break; + case UPDATE: + type = DeviceKeyEvent.Type.DEVICE_KEY_UPDATED; + deviceKey = checkNotNull(event.newValue().value()); + break; + case REMOVE: + type = DeviceKeyEvent.Type.DEVICE_KEY_REMOVED; + deviceKey = checkNotNull(event.oldValue().value()); + break; + default: + log.error("Unsupported event type: " + event.type()); + } + notifyDelegate(new DeviceKeyEvent(type, deviceKey)); + } + } +} diff --git a/incubator/store/src/main/java/org/onosproject/incubator/store/key/impl/package-info.java b/incubator/store/src/main/java/org/onosproject/incubator/store/key/impl/package-info.java new file mode 100644 index 0000000000..e7ce4ca993 --- /dev/null +++ b/incubator/store/src/main/java/org/onosproject/incubator/store/key/impl/package-info.java @@ -0,0 +1,21 @@ +/* + * 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. + */ + +/** + * A distributed device key store implementation that stores device key + * data consistently across the cluster. + */ +package org.onosproject.incubator.store.key.impl; \ No newline at end of file diff --git a/incubator/store/src/test/java/org/onosproject/incubator/store/key/impl/DistributedDeviceKeyStoreTest.java b/incubator/store/src/test/java/org/onosproject/incubator/store/key/impl/DistributedDeviceKeyStoreTest.java new file mode 100644 index 0000000000..6b271217c6 --- /dev/null +++ b/incubator/store/src/test/java/org/onosproject/incubator/store/key/impl/DistributedDeviceKeyStoreTest.java @@ -0,0 +1,148 @@ +/* + * 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.incubator.store.key.impl; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onosproject.incubator.net.key.DeviceKey; +import org.onosproject.incubator.net.key.DeviceKeyId; +import org.onosproject.store.service.TestStorageService; + +import java.util.Collection; + +import static org.junit.Assert.*; + +/** + * Test class for DistributedDeviceKeyStore. + */ +public class DistributedDeviceKeyStoreTest { + private DistributedDeviceKeyStore deviceKeyStore; + + final String deviceKeyIdValue = "DeviceKeyId"; + final String deviceKeyLabel = "DeviceKeyLabel"; + final String deviceKeyLabel2 = "DeviceKeyLabel2"; + final String deviceKeySnmpName = "DeviceKeySnmpName"; + + /** + * Sets up the device key store and the storage service test harness. + */ + @Before + public void setUp() { + deviceKeyStore = new DistributedDeviceKeyStore(); + deviceKeyStore.storageService = new TestStorageService(); + deviceKeyStore.setDelegate(event -> { + }); + deviceKeyStore.activate(); + } + + /** + * Tears down the device key store. + */ + @After + public void tearDown() { + deviceKeyStore.deactivate(); + } + + /** + * Tests adding, query and removal of a device key. + */ + @Test(expected = NullPointerException.class) + public void testAddNullKey() { + deviceKeyStore.createOrUpdateDeviceKey(null); + } + + /** + * Tests adding a device key to the store. This also tests the device key store + * query methods. + */ + @Test + public void testAddKey() { + DeviceKeyId deviceKeyId = DeviceKeyId.deviceKeyId(deviceKeyIdValue); + + DeviceKey deviceKey = DeviceKey.createDeviceKeyUsingCommunityName(deviceKeyId, + deviceKeyLabel, deviceKeySnmpName); + + // Test to make sure that the device key store is empty + Collection deviceKeys = deviceKeyStore.getDeviceKeys(); + assertTrue("The device key set should be empty.", deviceKeys.isEmpty()); + + // Add the new device key to the store + deviceKeyStore.createOrUpdateDeviceKey(deviceKey); + + // Test the getDeviceKeys method to make sure that the new device key exists + deviceKeys = deviceKeyStore.getDeviceKeys(); + assertEquals("There should be one device key in the set.", deviceKeys.size(), 1); + + // Test the getDeviceKey method using the device key unique identifier + deviceKey = deviceKeyStore.getDeviceKey(deviceKeyId); + assertEquals("There should be one device key in the set.", deviceKeys.size(), 1); + } + + /** + * Tests re-adding the same device key to the store but with a different label. + */ + @Test + public void testAddSameKey() { + DeviceKeyId deviceKeyId = DeviceKeyId.deviceKeyId(deviceKeyIdValue); + + DeviceKey deviceKey = DeviceKey.createDeviceKeyUsingCommunityName(deviceKeyId, + deviceKeyLabel, deviceKeySnmpName); + + // Add the first device key to the store + deviceKeyStore.createOrUpdateDeviceKey(deviceKey); + + // Test the getDeviceKeys method + Collection deviceKeys = deviceKeyStore.getDeviceKeys(); + assertEquals("There should be one device key in the set.", deviceKeys.size(), 1); + + // Now let's create a new device key with the same device key identifier as exists in the store. + DeviceKey deviceKey2 = DeviceKey.createDeviceKeyUsingCommunityName(deviceKeyId, + deviceKeyLabel2, deviceKeySnmpName); + + // Replace the new device key in the store + deviceKeyStore.createOrUpdateDeviceKey(deviceKey2); + + // Test the getDeviceKeys method to ensure that only 1 device key exists in the store. + deviceKeys = deviceKeyStore.getDeviceKeys(); + assertEquals("There should be one device key in the set.", deviceKeys.size(), 1); + + // Test the getDeviceKey method using the device key unique identifier + deviceKey = deviceKeyStore.getDeviceKey(deviceKeyId); + assertNotNull("The device key should not be null.", deviceKey); + assertEquals("The device key label should match.", deviceKeyLabel2, deviceKey.label()); + } + + /** + * Tests removal of a device key from the store using the device key identifier. + */ + @Test + public void testRemoveKey() { + DeviceKeyId deviceKeyId = DeviceKeyId.deviceKeyId(deviceKeyIdValue); + DeviceKey deviceKey = DeviceKey.createDeviceKeyUsingCommunityName(deviceKeyId, + deviceKeyLabel, deviceKeySnmpName); + // Add the new device key to the store + deviceKeyStore.createOrUpdateDeviceKey(deviceKey); + + // Remove the device key from the store + deviceKeyStore.deleteDeviceKey(deviceKeyId); + + // Validate that the device key was removed from the store by querying it. + deviceKey = deviceKeyStore.getDeviceKey(deviceKeyId); + assertNull("The device key set should be empty.", deviceKey); + } +}