Committed by
Gerrit Code Review
Creating persistence service.
Change-Id: Ib78b4001a24c71b4096e5a2a446dbd5009aa1090
Showing
18 changed files
with
1133 additions
and
4 deletions
| ... | @@ -19,7 +19,6 @@ | ... | @@ -19,7 +19,6 @@ |
| 19 | <command> | 19 | <command> |
| 20 | <action class="org.onosproject.cli.SummaryCommand"/> | 20 | <action class="org.onosproject.cli.SummaryCommand"/> |
| 21 | </command> | 21 | </command> |
| 22 | - | ||
| 23 | <command> | 22 | <command> |
| 24 | <action class="org.onosproject.cli.security.ReviewCommand"/> | 23 | <action class="org.onosproject.cli.security.ReviewCommand"/> |
| 25 | <completers> | 24 | <completers> | ... | ... |
| ... | @@ -63,6 +63,11 @@ | ... | @@ -63,6 +63,11 @@ |
| 63 | <artifactId>onlab-rest</artifactId> | 63 | <artifactId>onlab-rest</artifactId> |
| 64 | <version>${project.version}</version> | 64 | <version>${project.version}</version> |
| 65 | </dependency> | 65 | </dependency> |
| 66 | + <dependency> | ||
| 67 | + <groupId>org.mapdb</groupId> | ||
| 68 | + <artifactId>mapdb</artifactId> | ||
| 69 | + <version>1.0.8</version> | ||
| 70 | + </dependency> | ||
| 66 | </dependencies> | 71 | </dependencies> |
| 67 | 72 | ||
| 68 | </project> | 73 | </project> | ... | ... |
| 1 | +/* | ||
| 2 | + * Copyright 2015 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +package org.onosproject.persistence; | ||
| 18 | + | ||
| 19 | +/** | ||
| 20 | + * Service that allows for the creation of local disk backed map for instance specific values that persist across | ||
| 21 | + * restarts. Empty maps and sets are deleted on shutdown. | ||
| 22 | + */ | ||
| 23 | +public interface PersistenceService { | ||
| 24 | + /** | ||
| 25 | + * A builder for the creation of local persistent maps backed by disk. | ||
| 26 | + * | ||
| 27 | + * @param <K> the type of keys in this map | ||
| 28 | + * @param <V> the type of values in this map | ||
| 29 | + * @return a persistent map builder | ||
| 30 | + */ | ||
| 31 | + <K, V> PersistentMapBuilder<K, V> persistentMapBuilder(); | ||
| 32 | + | ||
| 33 | + /** | ||
| 34 | + * A builder for the creation of local persistent sets backed by disk. | ||
| 35 | + * | ||
| 36 | + * @param <E> the type of the elements | ||
| 37 | + * @return a persistent set builder | ||
| 38 | + */ | ||
| 39 | + <E> PersistentSetBuilder<E> persistentSetBuilder(); | ||
| 40 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +/* | ||
| 2 | + * Copyright 2015 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +package org.onosproject.persistence; | ||
| 18 | + | ||
| 19 | + | ||
| 20 | +import org.onosproject.store.service.Serializer; | ||
| 21 | + | ||
| 22 | +import java.util.Map; | ||
| 23 | + | ||
| 24 | +/** | ||
| 25 | + * The interface for a persistent map builder for use with mapDB. | ||
| 26 | + */ | ||
| 27 | +public interface PersistentMapBuilder<K, V> { | ||
| 28 | + | ||
| 29 | + /** | ||
| 30 | + * Sets the name of this map. | ||
| 31 | + * @param name the string name of this map | ||
| 32 | + * @return a persistent map builder with the name option now set | ||
| 33 | + */ | ||
| 34 | + PersistentMapBuilder<K, V> withName(String name); | ||
| 35 | + | ||
| 36 | + /** | ||
| 37 | + * Sets the key serializer to be used to serialize this map, this is a required parameter. | ||
| 38 | + * @param serializer the serializer to be used for keys | ||
| 39 | + * @return a persistent map builder with the key serializer set | ||
| 40 | + */ | ||
| 41 | + PersistentMapBuilder<K, V> withSerializer(Serializer serializer); | ||
| 42 | + | ||
| 43 | + /** | ||
| 44 | + * Validates the map settings and then builds this map in the database. Throws an exception if invalid settings | ||
| 45 | + * are found. | ||
| 46 | + * @return The map that was created | ||
| 47 | + */ | ||
| 48 | + Map<K, V> build(); | ||
| 49 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +/* | ||
| 2 | + * Copyright 2015 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +package org.onosproject.persistence; | ||
| 18 | + | ||
| 19 | +import org.onosproject.store.service.Serializer; | ||
| 20 | + | ||
| 21 | +import java.util.Set; | ||
| 22 | + | ||
| 23 | +/** | ||
| 24 | + * The default interface for the persistent set builder for use with mapDB. | ||
| 25 | + */ | ||
| 26 | +public interface PersistentSetBuilder<E> { | ||
| 27 | + | ||
| 28 | + /** | ||
| 29 | + * Sets the name of this set. | ||
| 30 | + * @param name the string name of this set | ||
| 31 | + * @return a persistent set builder with the name option now set | ||
| 32 | + */ | ||
| 33 | + PersistentSetBuilder<E> withName(String name); | ||
| 34 | + | ||
| 35 | + /** | ||
| 36 | + * Sets the serializer to be used to serialize this set, this is a required parameter. | ||
| 37 | + * @param serializer the serializer to be used | ||
| 38 | + * @return a persistent set builder with the serializer set | ||
| 39 | + */ | ||
| 40 | + PersistentSetBuilder<E> withSerializer(Serializer serializer); | ||
| 41 | + | ||
| 42 | + /** | ||
| 43 | + * Validates the set settings and then builds this map in the database. Throws an exception if invalid settings | ||
| 44 | + * are found. | ||
| 45 | + * @return The set that was created | ||
| 46 | + */ | ||
| 47 | + Set<E> build(); | ||
| 48 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| ... | @@ -71,7 +71,7 @@ | ... | @@ -71,7 +71,7 @@ |
| 71 | <dependency> | 71 | <dependency> |
| 72 | <groupId>org.mapdb</groupId> | 72 | <groupId>org.mapdb</groupId> |
| 73 | <artifactId>mapdb</artifactId> | 73 | <artifactId>mapdb</artifactId> |
| 74 | - <version>1.0.7</version> | 74 | + <version>1.0.8</version> |
| 75 | </dependency> | 75 | </dependency> |
| 76 | 76 | ||
| 77 | <dependency> | 77 | <dependency> | ... | ... |
| ... | @@ -100,4 +100,4 @@ class MapDbPersistentStore<K, V> implements PersistentStore<K, V> { | ... | @@ -100,4 +100,4 @@ class MapDbPersistentStore<K, V> implements PersistentStore<K, V> { |
| 100 | items.remove(keyBytes); | 100 | items.remove(keyBytes); |
| 101 | database.commit(); | 101 | database.commit(); |
| 102 | } | 102 | } |
| 103 | -} | 103 | +} |
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
core/store/persistence/pom.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<!-- | ||
| 3 | + ~ Copyright 2015 Open Networking Laboratory | ||
| 4 | + ~ | ||
| 5 | + ~ Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | + ~ you may not use this file except in compliance with the License. | ||
| 7 | + ~ You may obtain a copy of the License at | ||
| 8 | + ~ | ||
| 9 | + ~ http://www.apache.org/licenses/LICENSE-2.0 | ||
| 10 | + ~ | ||
| 11 | + ~ Unless required by applicable law or agreed to in writing, software | ||
| 12 | + ~ distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | + ~ See the License for the specific language governing permissions and | ||
| 15 | + ~ limitations under the License. | ||
| 16 | + --> | ||
| 17 | +<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
| 18 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| 19 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> | ||
| 20 | + <modelVersion>4.0.0</modelVersion> | ||
| 21 | + <repositories> | ||
| 22 | + <repository> | ||
| 23 | + <id>repository.springsource.com.release</id> | ||
| 24 | + <name>SpringSource OBR - Release</name> | ||
| 25 | + <url>http://repository.springsource.com/maven/bundles/release</url> | ||
| 26 | + </repository> | ||
| 27 | + <repository> | ||
| 28 | + <id>repository.springsource.com.external</id> | ||
| 29 | + <name>SpringSource OBR - External</name> | ||
| 30 | + <url>http://repository.springsource.com/maven/bundles/external</url> | ||
| 31 | + </repository> | ||
| 32 | + </repositories> | ||
| 33 | + | ||
| 34 | + <parent> | ||
| 35 | + <groupId>org.onosproject</groupId> | ||
| 36 | + <artifactId>onos-core-store</artifactId> | ||
| 37 | + <version>1.4.0-SNAPSHOT</version> | ||
| 38 | + <relativePath>../pom.xml</relativePath> | ||
| 39 | + </parent> | ||
| 40 | + | ||
| 41 | + <artifactId>onos-core-persistence</artifactId> | ||
| 42 | + <packaging>bundle</packaging> | ||
| 43 | + | ||
| 44 | + <description>ONOS Core persistent local store subsystem</description> | ||
| 45 | + | ||
| 46 | + | ||
| 47 | + | ||
| 48 | + <dependencies> | ||
| 49 | + <dependency> | ||
| 50 | + <groupId>org.onosproject</groupId> | ||
| 51 | + <artifactId>onos-api</artifactId> | ||
| 52 | + </dependency> | ||
| 53 | + <dependency> | ||
| 54 | + <groupId>org.mapdb</groupId> | ||
| 55 | + <artifactId>mapdb</artifactId> | ||
| 56 | + <version>1.0.8</version> | ||
| 57 | + </dependency> | ||
| 58 | + <dependency> | ||
| 59 | + <groupId>org.junit</groupId> | ||
| 60 | + <artifactId>com.springsource.org.junit</artifactId> | ||
| 61 | + <version>4.11.0</version> | ||
| 62 | + </dependency> | ||
| 63 | + </dependencies> | ||
| 64 | + | ||
| 65 | +</project> |
| 1 | +/* | ||
| 2 | + * Copyright 2015 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +package org.onosproject.persistence.impl; | ||
| 18 | + | ||
| 19 | +import org.mapdb.DB; | ||
| 20 | +import org.onosproject.persistence.PersistentMapBuilder; | ||
| 21 | +import org.onosproject.store.service.Serializer; | ||
| 22 | + | ||
| 23 | +import java.util.Map; | ||
| 24 | + | ||
| 25 | +import static com.google.common.base.Preconditions.checkArgument; | ||
| 26 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
| 27 | + | ||
| 28 | +/** | ||
| 29 | + * Default builder for persistent maps stored in the mapDB local database via the persistence service. | ||
| 30 | + */ | ||
| 31 | +public class DefaultPersistentMapBuilder<K, V> implements PersistentMapBuilder<K, V> { | ||
| 32 | + | ||
| 33 | + private final DB localDB; | ||
| 34 | + | ||
| 35 | + private String name = null; | ||
| 36 | + | ||
| 37 | + private Serializer serializer = null; | ||
| 38 | + | ||
| 39 | + | ||
| 40 | + public DefaultPersistentMapBuilder(DB localDB) { | ||
| 41 | + checkNotNull(localDB, "The local database cannot be null."); | ||
| 42 | + this.localDB = localDB; | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + public PersistentMapBuilder<K, V> withName(String name) { | ||
| 46 | + this.name = PersistenceManager.MAP_PREFIX + checkNotNull(name); | ||
| 47 | + return this; | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + public PersistentMapBuilder<K, V> withSerializer(Serializer serializer) { | ||
| 51 | + checkArgument(this.serializer == null); | ||
| 52 | + checkNotNull(serializer); | ||
| 53 | + this.serializer = serializer; | ||
| 54 | + return this; | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + public Map<K, V> build() { | ||
| 58 | + checkNotNull(name, "The name must be assigned."); | ||
| 59 | + checkNotNull(serializer, "The key serializer must be assigned."); | ||
| 60 | + | ||
| 61 | + return new PersistentMap<K, V>(serializer, localDB, name); | ||
| 62 | + } | ||
| 63 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +/* | ||
| 2 | + * Copyright 2015 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +package org.onosproject.persistence.impl; | ||
| 18 | + | ||
| 19 | +import org.mapdb.DB; | ||
| 20 | +import org.onosproject.persistence.PersistentSetBuilder; | ||
| 21 | +import org.onosproject.store.service.Serializer; | ||
| 22 | + | ||
| 23 | +import static com.google.common.base.Preconditions.checkArgument; | ||
| 24 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
| 25 | + | ||
| 26 | +/** | ||
| 27 | + * Default builder for persistent sets stored in the mapDB local database via the persistence service.. | ||
| 28 | + */ | ||
| 29 | +public class DefaultPersistentSetBuilder<E> implements PersistentSetBuilder<E> { | ||
| 30 | + | ||
| 31 | + private final DB localDB; | ||
| 32 | + | ||
| 33 | + private String name = null; | ||
| 34 | + | ||
| 35 | + private Serializer serializer = null; | ||
| 36 | + | ||
| 37 | + public DefaultPersistentSetBuilder(DB localDB) { | ||
| 38 | + this.localDB = checkNotNull(localDB, "The local database cannot be null."); | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | + public PersistentSetBuilder<E> withName(String name) { | ||
| 42 | + this.name = PersistenceManager.SET_PREFIX + checkNotNull(name); | ||
| 43 | + return this; | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + public PersistentSetBuilder<E> withSerializer(Serializer serializer) { | ||
| 47 | + checkArgument(this.serializer == null); | ||
| 48 | + checkNotNull(serializer); | ||
| 49 | + this.serializer = serializer; | ||
| 50 | + return this; | ||
| 51 | + } | ||
| 52 | + | ||
| 53 | + public PersistentSet<E> build() { | ||
| 54 | + checkNotNull(name, "The name must be assigned."); | ||
| 55 | + checkNotNull(serializer, "The serializer must be assigned."); | ||
| 56 | + | ||
| 57 | + return new PersistentSet<E>(serializer, localDB, name); | ||
| 58 | + } | ||
| 59 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
core/store/persistence/src/main/java/org/onosproject/persistence/impl/PersistenceException.java
0 → 100644
| 1 | +/* | ||
| 2 | + * Copyright 2015 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +package org.onosproject.persistence.impl; | ||
| 18 | + | ||
| 19 | +/** | ||
| 20 | + * An exception defined for failures of the local persistent store system. | ||
| 21 | + */ | ||
| 22 | + | ||
| 23 | +/** | ||
| 24 | + * Throws an exception with the specified message. | ||
| 25 | + */ | ||
| 26 | +public class PersistenceException extends RuntimeException { | ||
| 27 | + public PersistenceException(String s) { | ||
| 28 | + super(s); | ||
| 29 | + } | ||
| 30 | +} |
core/store/persistence/src/main/java/org/onosproject/persistence/impl/PersistenceManager.java
0 → 100644
| 1 | +/* | ||
| 2 | + * Copyright 2015 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +package org.onosproject.persistence.impl; | ||
| 18 | + | ||
| 19 | +import org.apache.felix.scr.annotations.Activate; | ||
| 20 | +import org.apache.felix.scr.annotations.Component; | ||
| 21 | +import org.apache.felix.scr.annotations.Deactivate; | ||
| 22 | +import org.apache.felix.scr.annotations.Service; | ||
| 23 | +import org.mapdb.DB; | ||
| 24 | +import org.mapdb.DBMaker; | ||
| 25 | +import org.onosproject.persistence.PersistenceService; | ||
| 26 | +import org.onosproject.persistence.PersistentMapBuilder; | ||
| 27 | +import org.onosproject.persistence.PersistentSetBuilder; | ||
| 28 | +import org.slf4j.Logger; | ||
| 29 | + | ||
| 30 | +import java.io.IOException; | ||
| 31 | +import java.nio.file.Files; | ||
| 32 | +import java.nio.file.Path; | ||
| 33 | +import java.nio.file.Paths; | ||
| 34 | +import java.util.Map; | ||
| 35 | +import java.util.Set; | ||
| 36 | +import java.util.Timer; | ||
| 37 | +import java.util.TimerTask; | ||
| 38 | + | ||
| 39 | +import static org.slf4j.LoggerFactory.getLogger; | ||
| 40 | + | ||
| 41 | +/** | ||
| 42 | + * Service that maintains local disk backed maps and sets. This implementation automatically deletes empty structures | ||
| 43 | + * on shutdown. | ||
| 44 | + */ | ||
| 45 | +@Component(immediate = true) | ||
| 46 | +@Service | ||
| 47 | +public class PersistenceManager implements PersistenceService { | ||
| 48 | + | ||
| 49 | + private static final String DATABASE_PATH = "../data/localDB"; | ||
| 50 | + | ||
| 51 | + private static final String ENCLOSING_FOLDER = "../data"; | ||
| 52 | + | ||
| 53 | + static final String MAP_PREFIX = "map:"; | ||
| 54 | + | ||
| 55 | + static final String SET_PREFIX = "set:"; | ||
| 56 | + | ||
| 57 | + private final Logger log = getLogger(getClass()); | ||
| 58 | + | ||
| 59 | + private DB localDB = null; | ||
| 60 | + | ||
| 61 | + private static final int FLUSH_FREQUENCY_MILLIS = 3000; | ||
| 62 | + | ||
| 63 | + private final Timer timer = new Timer(); | ||
| 64 | + | ||
| 65 | + private final CommitTask commitTask = new CommitTask(); | ||
| 66 | + | ||
| 67 | + @Activate | ||
| 68 | + public void activate() { | ||
| 69 | + Path dbPath = Paths.get(DATABASE_PATH); | ||
| 70 | + Path dbFolderPath = Paths.get(ENCLOSING_FOLDER); | ||
| 71 | + //Make sure the directory exists, if it does not, make it. | ||
| 72 | + if (!dbFolderPath.toFile().isDirectory()) { | ||
| 73 | + log.info("The specified folder location for the database did not exist and will be created."); | ||
| 74 | + try { | ||
| 75 | + Files.createDirectories(dbFolderPath); | ||
| 76 | + } catch (IOException e) { | ||
| 77 | + log.error("Could not create the required folder for the database."); | ||
| 78 | + throw new PersistenceException("Database folder could not be created."); | ||
| 79 | + } | ||
| 80 | + } | ||
| 81 | + //Notify if the database file does not exist. | ||
| 82 | + boolean dbFound = Files.exists(dbPath); | ||
| 83 | + if (!dbFound) { | ||
| 84 | + log.info("The database file could not be located, a new database will be constructed."); | ||
| 85 | + | ||
| 86 | + } else { | ||
| 87 | + log.info("A previous database file has been found."); | ||
| 88 | + } | ||
| 89 | + localDB = DBMaker.newFileDB(dbPath.toFile()) | ||
| 90 | + .asyncWriteEnable() | ||
| 91 | + .closeOnJvmShutdown() | ||
| 92 | + .make(); | ||
| 93 | + timer.schedule(commitTask, FLUSH_FREQUENCY_MILLIS, FLUSH_FREQUENCY_MILLIS); | ||
| 94 | + log.info("Started"); | ||
| 95 | + } | ||
| 96 | + | ||
| 97 | + @Deactivate | ||
| 98 | + public void deactivate() { | ||
| 99 | + for (Map.Entry<String, Object> entry : localDB.getAll().entrySet()) { | ||
| 100 | + String key = entry.getKey(); | ||
| 101 | + Object value = entry.getValue(); | ||
| 102 | + //This is a map implementation to be handled as such | ||
| 103 | + if (value instanceof Map) { | ||
| 104 | + Map asMap = (Map) value; | ||
| 105 | + if (asMap.isEmpty()) { | ||
| 106 | + //the map is empty and may be deleted | ||
| 107 | + localDB.delete(key); | ||
| 108 | + } | ||
| 109 | + //This is a set implementation and can be handled as such | ||
| 110 | + } else if (value instanceof Set) { | ||
| 111 | + Set asSet = (Set) value; | ||
| 112 | + if (asSet.isEmpty()) { | ||
| 113 | + //the set is empty and may be deleted | ||
| 114 | + localDB.delete(key); | ||
| 115 | + } | ||
| 116 | + } | ||
| 117 | + } | ||
| 118 | + localDB.commit(); | ||
| 119 | + localDB.close(); | ||
| 120 | + log.info("Stopped"); | ||
| 121 | + } | ||
| 122 | + | ||
| 123 | + public <K, V> PersistentMapBuilder<K, V> persistentMapBuilder() { | ||
| 124 | + return new DefaultPersistentMapBuilder<>(localDB); | ||
| 125 | + } | ||
| 126 | + | ||
| 127 | + public <E> PersistentSetBuilder<E> persistentSetBuilder() { | ||
| 128 | + return new DefaultPersistentSetBuilder<>(localDB); | ||
| 129 | + } | ||
| 130 | + | ||
| 131 | + private class CommitTask extends TimerTask { | ||
| 132 | + | ||
| 133 | + @Override | ||
| 134 | + public void run() { | ||
| 135 | + localDB.commit(); | ||
| 136 | + } | ||
| 137 | + } | ||
| 138 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +/* | ||
| 2 | + * Copyright 2015 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +package org.onosproject.persistence.impl; | ||
| 18 | + | ||
| 19 | +import com.google.common.collect.Maps; | ||
| 20 | +import com.google.common.collect.Sets; | ||
| 21 | +import org.mapdb.DB; | ||
| 22 | +import org.mapdb.Hasher; | ||
| 23 | +import org.onosproject.store.service.Serializer; | ||
| 24 | + | ||
| 25 | +import java.util.Collection; | ||
| 26 | +import java.util.Map; | ||
| 27 | +import java.util.Set; | ||
| 28 | + | ||
| 29 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
| 30 | + | ||
| 31 | + | ||
| 32 | +/** | ||
| 33 | + * A map implementation that stores and receives all data from a serialized internal map. | ||
| 34 | + */ | ||
| 35 | +public class PersistentMap<K, V> implements Map<K, V> { | ||
| 36 | + | ||
| 37 | + private final Serializer serializer; | ||
| 38 | + | ||
| 39 | + private final org.mapdb.DB database; | ||
| 40 | + | ||
| 41 | + private final Map<byte[], byte[]> items; | ||
| 42 | + | ||
| 43 | + private final String name; | ||
| 44 | + | ||
| 45 | + public PersistentMap(Serializer serializer, DB database, String name) { | ||
| 46 | + this.serializer = checkNotNull(serializer); | ||
| 47 | + this.database = checkNotNull(database); | ||
| 48 | + this.name = checkNotNull(name); | ||
| 49 | + | ||
| 50 | + items = database | ||
| 51 | + .createHashMap(name) | ||
| 52 | + .keySerializer(org.mapdb.Serializer.BYTE_ARRAY) | ||
| 53 | + .valueSerializer(org.mapdb.Serializer.BYTE_ARRAY) | ||
| 54 | + .hasher(Hasher.BYTE_ARRAY) | ||
| 55 | + .makeOrGet(); | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + /** | ||
| 59 | + * Reads this set in deserialized form into the provided map. | ||
| 60 | + * | ||
| 61 | + * @param items the map to be populated | ||
| 62 | + */ | ||
| 63 | + public void readInto(Map<K, V> items) { | ||
| 64 | + this.items.forEach((keyBytes, valueBytes) -> | ||
| 65 | + items.put(serializer.decode(keyBytes), | ||
| 66 | + serializer.decode(valueBytes))); | ||
| 67 | + } | ||
| 68 | + | ||
| 69 | + @Override | ||
| 70 | + public V remove(Object key) { | ||
| 71 | + checkNotNull(key, "Key can not be null."); | ||
| 72 | + V removed = get(key); | ||
| 73 | + items.remove(serializer.encode(key)); | ||
| 74 | + return removed; | ||
| 75 | + } | ||
| 76 | + | ||
| 77 | + @Override | ||
| 78 | + public int size() { | ||
| 79 | + return items.size(); | ||
| 80 | + } | ||
| 81 | + | ||
| 82 | + @Override | ||
| 83 | + public boolean isEmpty() { | ||
| 84 | + return items.isEmpty(); | ||
| 85 | + } | ||
| 86 | + | ||
| 87 | + @Override | ||
| 88 | + public boolean containsKey(Object key) { | ||
| 89 | + checkNotNull(key, "Key cannot be null."); | ||
| 90 | + return items.containsKey(serializer.encode(key)); | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | + @Override | ||
| 94 | + public boolean containsValue(Object value) { | ||
| 95 | + checkNotNull(value, "Value cannot be null."); | ||
| 96 | + byte[] serialized = serializer.encode(value); | ||
| 97 | + for (byte[] compareValue : items.values()) { | ||
| 98 | + boolean same = true; | ||
| 99 | + if (compareValue == null) { | ||
| 100 | + same = false; | ||
| 101 | + } else if (compareValue.length != serialized.length) { | ||
| 102 | + same = false; | ||
| 103 | + } else { | ||
| 104 | + for (int i = 0; i < serialized.length; i++) { | ||
| 105 | + if (serialized[i] != compareValue[i]) { | ||
| 106 | + same = false; | ||
| 107 | + break; | ||
| 108 | + } | ||
| 109 | + } | ||
| 110 | + } | ||
| 111 | + if (same) { | ||
| 112 | + return true; | ||
| 113 | + } | ||
| 114 | + } | ||
| 115 | + return false; | ||
| 116 | + } | ||
| 117 | + | ||
| 118 | + @Override | ||
| 119 | + public V get(Object key) { | ||
| 120 | + checkNotNull(key, "Key cannot be null."); | ||
| 121 | + return serializer.decode(items.get(serializer.encode(key))); | ||
| 122 | + } | ||
| 123 | + | ||
| 124 | + @Override | ||
| 125 | + public V put(K key, V value) { | ||
| 126 | + checkNotNull(key, "Key cannot be null."); | ||
| 127 | + checkNotNull(value, "Value cannot be null."); | ||
| 128 | + byte[] prevVal = items.put(serializer.encode(key), serializer.encode(value)); | ||
| 129 | + if (prevVal == null) { | ||
| 130 | + return null; | ||
| 131 | + } | ||
| 132 | + return serializer.decode(prevVal); | ||
| 133 | + } | ||
| 134 | + | ||
| 135 | + @Override | ||
| 136 | + public void putAll(Map<? extends K, ? extends V> m) { | ||
| 137 | + checkNotNull(m, "The passed in map cannot be null."); | ||
| 138 | + m.forEach((k, v) -> items.put(serializer.encode(k), serializer.encode(v))); | ||
| 139 | + } | ||
| 140 | + | ||
| 141 | + @Override | ||
| 142 | + public void clear() { | ||
| 143 | + items.clear(); | ||
| 144 | + } | ||
| 145 | + | ||
| 146 | + @Override | ||
| 147 | + public Set<K> keySet() { | ||
| 148 | + Set<K> keys = Sets.newHashSet(); | ||
| 149 | + items.keySet().forEach(k -> keys.add(serializer.decode(k))); | ||
| 150 | + return keys; | ||
| 151 | + } | ||
| 152 | + | ||
| 153 | + @Override | ||
| 154 | + public Collection<V> values() { | ||
| 155 | + Collection<V> values = Sets.newHashSet(); | ||
| 156 | + items.values().forEach(v -> values.add(serializer.decode(v))); | ||
| 157 | + return values; | ||
| 158 | + } | ||
| 159 | + | ||
| 160 | + @Override | ||
| 161 | + public Set<Entry<K, V>> entrySet() { | ||
| 162 | + Set<Entry<K, V>> entries = Sets.newHashSet(); | ||
| 163 | + items.entrySet(). | ||
| 164 | + forEach(e -> entries.add(Maps.immutableEntry(serializer.decode(e.getKey()), | ||
| 165 | + serializer.decode(e.getValue())))); | ||
| 166 | + return entries; | ||
| 167 | + } | ||
| 168 | + | ||
| 169 | + @Override | ||
| 170 | + public boolean equals(Object map) { | ||
| 171 | + //This is not threadsafe and on larger maps incurs a significant processing cost | ||
| 172 | + if (!(map instanceof Map)) { | ||
| 173 | + return false; | ||
| 174 | + } | ||
| 175 | + Map asMap = (Map) map; | ||
| 176 | + if (this.size() != asMap.size()) { | ||
| 177 | + return false; | ||
| 178 | + } | ||
| 179 | + for (Entry entry : this.entrySet()) { | ||
| 180 | + Object key = entry.getKey(); | ||
| 181 | + if (!asMap.containsKey(key) || !asMap.get(key).equals(entry.getValue())) { | ||
| 182 | + return false; | ||
| 183 | + } | ||
| 184 | + } | ||
| 185 | + return true; | ||
| 186 | + } | ||
| 187 | + | ||
| 188 | + @Override | ||
| 189 | + public int hashCode() { | ||
| 190 | + return super.hashCode(); | ||
| 191 | + } | ||
| 192 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +/* | ||
| 2 | + * Copyright 2015 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +package org.onosproject.persistence.impl; | ||
| 18 | + | ||
| 19 | +import com.google.common.collect.Iterators; | ||
| 20 | +import org.mapdb.DB; | ||
| 21 | +import org.mapdb.Hasher; | ||
| 22 | +import org.mapdb.Serializer; | ||
| 23 | + | ||
| 24 | +import java.util.Collection; | ||
| 25 | +import java.util.Iterator; | ||
| 26 | +import java.util.Set; | ||
| 27 | + | ||
| 28 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
| 29 | + | ||
| 30 | +/** | ||
| 31 | + * A set implementation that gets and receives all data from a serialized internal set. | ||
| 32 | + */ | ||
| 33 | +//TODO add locking for reads and writes | ||
| 34 | +public class PersistentSet<E> implements Set<E> { | ||
| 35 | + | ||
| 36 | + private final org.onosproject.store.service.Serializer serializer; | ||
| 37 | + | ||
| 38 | + private final org.mapdb.DB database; | ||
| 39 | + | ||
| 40 | + private final Set<byte[]> items; | ||
| 41 | + | ||
| 42 | + private final String name; | ||
| 43 | + | ||
| 44 | + public PersistentSet(org.onosproject.store.service.Serializer serializer, DB database, String name) { | ||
| 45 | + this.serializer = checkNotNull(serializer); | ||
| 46 | + this.database = checkNotNull(database); | ||
| 47 | + this.name = checkNotNull(name); | ||
| 48 | + | ||
| 49 | + items = database | ||
| 50 | + .createHashSet(name) | ||
| 51 | + .serializer(Serializer.BYTE_ARRAY) | ||
| 52 | + .hasher(Hasher.BYTE_ARRAY) | ||
| 53 | + .makeOrGet(); | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + public void readInto(Set<E> items) { | ||
| 57 | + this.items.forEach(item -> items.add(serializer.decode(item))); | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + @Override | ||
| 61 | + public int size() { | ||
| 62 | + return items.size(); | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + @Override | ||
| 66 | + public boolean isEmpty() { | ||
| 67 | + return items.isEmpty(); | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + @Override | ||
| 71 | + public boolean contains(Object o) { | ||
| 72 | + checkNotNull(o, "The argument cannot be null"); | ||
| 73 | + return items.contains(serializer.encode(o)); | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + @Override | ||
| 77 | + public Iterator<E> iterator() { | ||
| 78 | + return Iterators.transform(items.iterator(), serializer::decode); | ||
| 79 | + } | ||
| 80 | + | ||
| 81 | + @Override | ||
| 82 | + public Object[] toArray() { | ||
| 83 | + Object[] retArray = new Object[items.size()]; | ||
| 84 | + int index = 0; | ||
| 85 | + Iterator<byte[]> iterator = items.iterator(); | ||
| 86 | + while (iterator.hasNext()) { | ||
| 87 | + retArray[index] = serializer.decode(iterator.next()); | ||
| 88 | + index++; | ||
| 89 | + } | ||
| 90 | + return retArray; | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | + @Override | ||
| 94 | + public <T> T[] toArray(T[] a) { | ||
| 95 | + checkNotNull(a, "The passed in array cannot be null."); | ||
| 96 | + int index = 0; | ||
| 97 | + Iterator<byte[]> iterator = items.iterator(); | ||
| 98 | + T[] retArray; | ||
| 99 | + if (a.length >= items.size()) { | ||
| 100 | + retArray = a; | ||
| 101 | + } else { | ||
| 102 | + retArray = (T[]) new Object[items.size()]; | ||
| 103 | + } | ||
| 104 | + while (iterator.hasNext()) { | ||
| 105 | + retArray[index++] = serializer.decode(iterator.next()); | ||
| 106 | + } | ||
| 107 | + if (retArray.length > items.size()) { | ||
| 108 | + retArray[index] = null; | ||
| 109 | + } | ||
| 110 | + return retArray; | ||
| 111 | + } | ||
| 112 | + | ||
| 113 | + @Override | ||
| 114 | + public boolean add(E item) { | ||
| 115 | + checkNotNull("Item to be added cannot be null."); | ||
| 116 | + return items.add(serializer.encode(item)); | ||
| 117 | + } | ||
| 118 | + | ||
| 119 | + @Override | ||
| 120 | + public boolean remove(Object o) { | ||
| 121 | + checkNotNull(o, "Item to be removed cannot be null."); | ||
| 122 | + return items.remove(serializer.encode(o)); | ||
| 123 | + } | ||
| 124 | + | ||
| 125 | + @Override | ||
| 126 | + public boolean containsAll(Collection<?> c) { | ||
| 127 | + checkNotNull(c, "Collection cannot be internal."); | ||
| 128 | + for (Object item : c) { | ||
| 129 | + if (!items.contains(serializer.encode(item))) { | ||
| 130 | + return false; | ||
| 131 | + } | ||
| 132 | + } | ||
| 133 | + return true; | ||
| 134 | + } | ||
| 135 | + | ||
| 136 | + @Override | ||
| 137 | + public boolean addAll(Collection<? extends E> c) { | ||
| 138 | + checkNotNull(c, "The collection to be added cannot be null."); | ||
| 139 | + boolean changed = false; | ||
| 140 | + for (Object item : c) { | ||
| 141 | + changed = items.add(serializer.encode(item)) || changed; | ||
| 142 | + } | ||
| 143 | + return changed; | ||
| 144 | + } | ||
| 145 | + | ||
| 146 | + @Override | ||
| 147 | + public boolean retainAll(Collection<?> c) { | ||
| 148 | + boolean changed = false; | ||
| 149 | + for (byte[] item : items) { | ||
| 150 | + E deserialized = serializer.decode(item); | ||
| 151 | + if (!c.contains(deserialized)) { | ||
| 152 | + changed = items.remove(item) || changed; | ||
| 153 | + } | ||
| 154 | + } | ||
| 155 | + return changed; | ||
| 156 | + } | ||
| 157 | + | ||
| 158 | + @Override | ||
| 159 | + public boolean removeAll(Collection<?> c) { | ||
| 160 | + boolean changed = false; | ||
| 161 | + for (Object item : c) { | ||
| 162 | + changed = items.remove(serializer.encode(item)) || changed; | ||
| 163 | + } | ||
| 164 | + return changed; | ||
| 165 | + } | ||
| 166 | + | ||
| 167 | + @Override | ||
| 168 | + public void clear() { | ||
| 169 | + items.clear(); | ||
| 170 | + } | ||
| 171 | + | ||
| 172 | + @Override | ||
| 173 | + public boolean equals(Object set) { | ||
| 174 | + //This is not threadsafe and on larger sets incurs a significant processing cost | ||
| 175 | + if (!(set instanceof Set)) { | ||
| 176 | + return false; | ||
| 177 | + } | ||
| 178 | + Set asSet = (Set) set; | ||
| 179 | + if (asSet.size() != this.size()) { | ||
| 180 | + return false; | ||
| 181 | + } | ||
| 182 | + for (Object item : this) { | ||
| 183 | + if (!asSet.contains(item)) { | ||
| 184 | + return false; | ||
| 185 | + } | ||
| 186 | + } | ||
| 187 | + return true; | ||
| 188 | + } | ||
| 189 | + | ||
| 190 | + @Override | ||
| 191 | + public int hashCode() { | ||
| 192 | + return super.hashCode(); | ||
| 193 | + } | ||
| 194 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
core/store/persistence/src/main/java/org/onosproject/persistence/impl/test/PersistentMapTest.java
0 → 100644
| 1 | +/* | ||
| 2 | + * Copyright 2015 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +package org.onosproject.persistence.impl.test; | ||
| 18 | + | ||
| 19 | +import com.google.common.collect.Maps; | ||
| 20 | +import org.junit.After; | ||
| 21 | +import org.junit.Before; | ||
| 22 | +import org.junit.Test; | ||
| 23 | +import org.mapdb.DB; | ||
| 24 | +import org.mapdb.DBMaker; | ||
| 25 | +import org.onosproject.persistence.impl.PersistentMap; | ||
| 26 | +import org.onosproject.store.service.Serializer; | ||
| 27 | + | ||
| 28 | +import java.nio.file.Paths; | ||
| 29 | +import java.util.Map; | ||
| 30 | +import java.util.Set; | ||
| 31 | + | ||
| 32 | +import static org.junit.Assert.assertEquals; | ||
| 33 | +import static org.junit.Assert.assertFalse; | ||
| 34 | +import static org.junit.Assert.assertNull; | ||
| 35 | +import static org.junit.Assert.assertTrue; | ||
| 36 | + | ||
| 37 | +/** | ||
| 38 | + * Test suite for Persistent Map. | ||
| 39 | + */ | ||
| 40 | +public class PersistentMapTest { | ||
| 41 | + | ||
| 42 | + private Map<Integer, Integer> map = null; | ||
| 43 | + private DB fakeDB = null; | ||
| 44 | + | ||
| 45 | + | ||
| 46 | + /** | ||
| 47 | + * Set up the database, create a map and a direct executor to handle it. | ||
| 48 | + * | ||
| 49 | + * @throws Exception if instantiation fails | ||
| 50 | + */ | ||
| 51 | + @Before | ||
| 52 | + public void setUp() throws Exception { | ||
| 53 | + //Creates a db, a map within it and a basic integer serializer (async writing is off) | ||
| 54 | + fakeDB = DBMaker | ||
| 55 | + .newFileDB(Paths.get("../testDb").toFile()) | ||
| 56 | + .asyncWriteEnable() | ||
| 57 | + .closeOnJvmShutdown() | ||
| 58 | + .make(); | ||
| 59 | + map = new PersistentMap<Integer, Integer>(new Serializer() { | ||
| 60 | + @Override | ||
| 61 | + public <T> byte[] encode(T object) { | ||
| 62 | + if (object == null) { | ||
| 63 | + return null; | ||
| 64 | + } | ||
| 65 | + int num = (Integer) object; | ||
| 66 | + byte[] result = new byte[4]; | ||
| 67 | + | ||
| 68 | + result[0] = (byte) (num >> 24); | ||
| 69 | + result[1] = (byte) (num >> 16); | ||
| 70 | + result[2] = (byte) (num >> 8); | ||
| 71 | + result[3] = (byte) num; | ||
| 72 | + return result; | ||
| 73 | + } | ||
| 74 | + | ||
| 75 | + @Override | ||
| 76 | + public <T> T decode(byte[] bytes) { | ||
| 77 | + if (bytes == null) { | ||
| 78 | + return null; | ||
| 79 | + } | ||
| 80 | + int num = 0x00000000; | ||
| 81 | + | ||
| 82 | + num = num | bytes[0] << 24; | ||
| 83 | + num = num | bytes[1] << 16; | ||
| 84 | + num = num | bytes[2] << 8; | ||
| 85 | + num = num | bytes[3]; | ||
| 86 | + | ||
| 87 | + return (T) new java.lang.Integer(num); | ||
| 88 | + } | ||
| 89 | + }, fakeDB, "map"); | ||
| 90 | + } | ||
| 91 | + | ||
| 92 | + /** | ||
| 93 | + * Clears and deletes the map, closes the datbase and deletes the file. | ||
| 94 | + * | ||
| 95 | + * @throws Exception if shutdown fails | ||
| 96 | + */ | ||
| 97 | + @After | ||
| 98 | + public void tearDown() throws Exception { | ||
| 99 | + map.clear(); | ||
| 100 | + fakeDB.delete("map:map"); | ||
| 101 | + fakeDB.commit(); | ||
| 102 | + fakeDB.close(); | ||
| 103 | + //This is key to prevent artifacts persisting between tests. | ||
| 104 | + Paths.get("../testDB").toFile().delete(); | ||
| 105 | + | ||
| 106 | + | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | + @Test | ||
| 110 | + public void testRemove() throws Exception { | ||
| 111 | + //Checks removal and return values | ||
| 112 | + fillMap(10); | ||
| 113 | + assertEquals(10, map.size()); | ||
| 114 | + for (int i = 0; i < 10; i++) { | ||
| 115 | + assertEquals("The previous value was wrong.", new Integer(i), map.remove(i)); | ||
| 116 | + assertNull("The previous value was wrong.", map.remove(i)); | ||
| 117 | + //(i+1) compensates for base zero. | ||
| 118 | + assertEquals("The size was wrong.", 10 - (i + 1), map.size()); | ||
| 119 | + } | ||
| 120 | + } | ||
| 121 | + | ||
| 122 | + @Test | ||
| 123 | + public void testSize() throws Exception { | ||
| 124 | + //Checks size values throughout addition and removal | ||
| 125 | + for (int i = 0; i < 10; i++) { | ||
| 126 | + map.put(i, i); | ||
| 127 | + assertEquals("The map size is wrong.", i + 1, map.size()); | ||
| 128 | + } | ||
| 129 | + for (int i = 0; i < 10; i++) { | ||
| 130 | + map.remove(i); | ||
| 131 | + assertEquals("The map size is wrong.", 9 - i, map.size()); | ||
| 132 | + } | ||
| 133 | + } | ||
| 134 | + | ||
| 135 | + @Test | ||
| 136 | + public void testIsEmpty() throws Exception { | ||
| 137 | + //Checks empty condition | ||
| 138 | + //asserts that the map starts out empty | ||
| 139 | + assertTrue("Map should be empty", map.isEmpty()); | ||
| 140 | + map.put(1, 1); | ||
| 141 | + assertFalse("Map shouldn't be empty.", map.isEmpty()); | ||
| 142 | + map.remove(1); | ||
| 143 | + assertTrue("Map should be empty", map.isEmpty()); | ||
| 144 | + } | ||
| 145 | + | ||
| 146 | + @Test | ||
| 147 | + public void testContains() throws Exception { | ||
| 148 | + //Checks both containsKey and containsValue be aware the implementations vary widely (value does not use mapDB | ||
| 149 | + //due to object '=='being an insufficient check) | ||
| 150 | + for (int i = 0; i < 10; i++) { | ||
| 151 | + assertFalse("Map should not contain the key", map.containsKey(i)); | ||
| 152 | + assertFalse("Map should not contain the value", map.containsValue(i)); | ||
| 153 | + map.put(i, i); | ||
| 154 | + assertTrue("Map should contain the key", map.containsKey(i)); | ||
| 155 | + assertTrue("Map should contain the value", map.containsValue(i)); | ||
| 156 | + } | ||
| 157 | + } | ||
| 158 | + | ||
| 159 | + @Test | ||
| 160 | + public void testGet() throws Exception { | ||
| 161 | + //Tests value retrieval and nonexistent key return values | ||
| 162 | + for (int i = 0; i < 10; i++) { | ||
| 163 | + map.put(i, i); | ||
| 164 | + for (int j = 0; j <= i; j++) { | ||
| 165 | + assertEquals("The value was wrong.", new Integer(j), map.get(j)); | ||
| 166 | + } | ||
| 167 | + } | ||
| 168 | + assertNull("Null return value for nonexistent keys.", map.get(10)); | ||
| 169 | + } | ||
| 170 | + | ||
| 171 | + @Test | ||
| 172 | + public void testPutAll() throws Exception { | ||
| 173 | + //Tests adding of an outside map | ||
| 174 | + Map<Integer, Integer> testMap = Maps.newHashMap(); | ||
| 175 | + fillMap(10); | ||
| 176 | + map.putAll(testMap); | ||
| 177 | + for (int i = 0; i < 10; i++) { | ||
| 178 | + assertTrue("The map should contain the current 'i' value.", map.containsKey(i)); | ||
| 179 | + assertTrue("The map should contain the current 'i' value.", map.containsValue(i)); | ||
| 180 | + } | ||
| 181 | + } | ||
| 182 | + | ||
| 183 | + @Test | ||
| 184 | + public void testClear() throws Exception { | ||
| 185 | + //Tests clearing the map | ||
| 186 | + assertTrue("Map was initialized incorrectly, should be empty.", map.isEmpty()); | ||
| 187 | + fillMap(10); | ||
| 188 | + assertFalse("Map should contain entries now.", map.isEmpty()); | ||
| 189 | + map.clear(); | ||
| 190 | + assertTrue("Map should have been cleared of entries.", map.isEmpty()); | ||
| 191 | + | ||
| 192 | + } | ||
| 193 | + | ||
| 194 | + @Test | ||
| 195 | + public void testKeySet() throws Exception { | ||
| 196 | + //Tests key set generation | ||
| 197 | + fillMap(10); | ||
| 198 | + Set<Integer> keys = map.keySet(); | ||
| 199 | + for (int i = 0; i < 10; i++) { | ||
| 200 | + assertTrue("The key set doesn't contain all keys 0-9", keys.contains(i)); | ||
| 201 | + } | ||
| 202 | + assertEquals("The key set has an incorrect number of entries", 10, keys.size()); | ||
| 203 | + } | ||
| 204 | + | ||
| 205 | + @Test | ||
| 206 | + public void testValues() throws Exception { | ||
| 207 | + //Tests value set generation | ||
| 208 | + fillMap(10); | ||
| 209 | + Set<Integer> values = (Set<Integer>) map.values(); | ||
| 210 | + for (int i = 0; i < 10; i++) { | ||
| 211 | + assertTrue("The key set doesn't contain all keys 0-9", values.contains(i)); | ||
| 212 | + } | ||
| 213 | + assertEquals("The key set has an incorrect number of entries", 10, values.size()); | ||
| 214 | + } | ||
| 215 | + | ||
| 216 | + @Test | ||
| 217 | + public void testEntrySet() throws Exception { | ||
| 218 | + //Test entry set generation (violates abstraction by knowing the type of the returned entries) | ||
| 219 | + fillMap(10); | ||
| 220 | + Set<Map.Entry<Integer, Integer>> entries = map.entrySet(); | ||
| 221 | + for (int i = 0; i < 10; i++) { | ||
| 222 | + assertTrue("The key set doesn't contain all keys 0-9", entries.contains(Maps.immutableEntry(i, i))); | ||
| 223 | + } | ||
| 224 | + assertEquals("The key set has an incorrect number of entries", 10, entries.size()); | ||
| 225 | + } | ||
| 226 | + | ||
| 227 | + @Test public void testPut() throws Exception { | ||
| 228 | + //Tests insertion behavior (particularly the returning of previous value) | ||
| 229 | + fillMap(10); | ||
| 230 | + for (int i = 0; i < 10; i++) { | ||
| 231 | + assertEquals("Put should return the previous value", new Integer(i), map.put(i, i + 1)); | ||
| 232 | + } | ||
| 233 | + assertNull(map.put(11, 11)); | ||
| 234 | + } | ||
| 235 | + | ||
| 236 | + /** | ||
| 237 | + * Populated the map with pairs of integers from (0, 0) up to (numEntries - 1, numEntries -1). | ||
| 238 | + * @param numEntries number of entries to add | ||
| 239 | + */ | ||
| 240 | + private void fillMap(int numEntries) { | ||
| 241 | + for (int i = 0; i < numEntries; i++) { | ||
| 242 | + map.put(i, i); | ||
| 243 | + } | ||
| 244 | + } | ||
| 245 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
core/store/persistence/src/main/java/org/onosproject/persistence/impl/test/PersistentSetTest.java
0 → 100644
This diff is collapsed. Click to expand it.
| ... | @@ -33,7 +33,8 @@ | ... | @@ -33,7 +33,8 @@ |
| 33 | 33 | ||
| 34 | <modules> | 34 | <modules> |
| 35 | <module>dist</module> | 35 | <module>dist</module> |
| 36 | - <module>serializers</module> | 36 | + <module>persistence</module> |
| 37 | + <module>serializers</module> | ||
| 37 | </modules> | 38 | </modules> |
| 38 | 39 | ||
| 39 | <dependencies> | 40 | <dependencies> | ... | ... |
| ... | @@ -96,6 +96,7 @@ | ... | @@ -96,6 +96,7 @@ |
| 96 | <bundle>mvn:org.onosproject/onos-core-net/@ONOS-VERSION</bundle> | 96 | <bundle>mvn:org.onosproject/onos-core-net/@ONOS-VERSION</bundle> |
| 97 | <bundle>mvn:org.onosproject/onos-core-common/@ONOS-VERSION</bundle> | 97 | <bundle>mvn:org.onosproject/onos-core-common/@ONOS-VERSION</bundle> |
| 98 | <bundle>mvn:org.onosproject/onos-core-dist/@ONOS-VERSION</bundle> | 98 | <bundle>mvn:org.onosproject/onos-core-dist/@ONOS-VERSION</bundle> |
| 99 | + <bundle>mvn:org.onosproject/onos-core-persistence/@ONOS-VERSION</bundle> | ||
| 99 | <bundle>mvn:org.onosproject/onos-core-serializers/@ONOS-VERSION</bundle> | 100 | <bundle>mvn:org.onosproject/onos-core-serializers/@ONOS-VERSION</bundle> |
| 100 | <bundle>mvn:org.onosproject/onlab-netty/@ONOS-VERSION</bundle> | 101 | <bundle>mvn:org.onosproject/onlab-netty/@ONOS-VERSION</bundle> |
| 101 | </feature> | 102 | </feature> | ... | ... |
-
Please register or login to post a comment