2 * Copyright 2015 Open Networking Laboratory
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package org.onosproject.persistence.impl;
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;
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;
30 import java.io.IOException;
31 import java.nio.file.Files;
32 import java.nio.file.Path;
33 import java.nio.file.Paths;
36 import java.util.Timer;
37 import java.util.TimerTask;
39 import static org.slf4j.LoggerFactory.getLogger;
42 * Service that maintains local disk backed maps and sets. This implementation automatically deletes empty structures
45 @Component(immediate = true)
47 public class PersistenceManager implements PersistenceService {
49 private static final String DATABASE_PATH = "../data/localDB";
51 private static final String ENCLOSING_FOLDER = "../data";
53 static final String MAP_PREFIX = "map:";
55 static final String SET_PREFIX = "set:";
57 private final Logger log = getLogger(getClass());
59 private DB localDB = null;
61 private static final int FLUSH_FREQUENCY_MILLIS = 3000;
65 private final CommitTask commitTask = new CommitTask();
68 public void activate() {
70 Path dbPath = Paths.get(DATABASE_PATH);
71 Path dbFolderPath = Paths.get(ENCLOSING_FOLDER);
72 //Make sure the directory exists, if it does not, make it.
73 if (!dbFolderPath.toFile().isDirectory()) {
74 log.info("The specified folder location for the database did not exist and will be created.");
76 Files.createDirectories(dbFolderPath);
77 } catch (IOException e) {
78 log.error("Could not create the required folder for the database.");
79 throw new PersistenceException("Database folder could not be created.");
82 //Notify if the database file does not exist.
83 boolean dbFound = Files.exists(dbPath);
85 log.info("The database file could not be located, a new database will be constructed.");
88 log.info("A previous database file has been found.");
90 localDB = DBMaker.newFileDB(dbPath.toFile())
94 timer.schedule(commitTask, FLUSH_FREQUENCY_MILLIS, FLUSH_FREQUENCY_MILLIS);
99 public void deactivate() {
101 for (Map.Entry<String, Object> entry : localDB.getAll().entrySet()) {
102 String key = entry.getKey();
103 Object value = entry.getValue();
104 //This is a map implementation to be handled as such
105 if (value instanceof Map) {
106 Map asMap = (Map) value;
107 if (asMap.isEmpty()) {
108 //the map is empty and may be deleted
111 //This is a set implementation and can be handled as such
112 } else if (value instanceof Set) {
113 Set asSet = (Set) value;
114 if (asSet.isEmpty()) {
115 //the set is empty and may be deleted
125 public <K, V> PersistentMapBuilder<K, V> persistentMapBuilder() {
126 return new DefaultPersistentMapBuilder<>(localDB);
129 public <E> PersistentSetBuilder<E> persistentSetBuilder() {
130 return new DefaultPersistentSetBuilder<>(localDB);
133 private class CommitTask extends TimerTask {