blob: f2d5269bb8260411a42f9220788a205c565cfe18 [file] [log] [blame]
Madan Jampani09342702015-02-05 23:32:40 -08001package org.onosproject.store.consistent.impl;
2
3import static com.google.common.base.Preconditions.checkArgument;
4import static com.google.common.base.Preconditions.checkNotNull;
5import static org.slf4j.LoggerFactory.getLogger;
6
7import java.io.File;
8import java.io.IOException;
9import java.util.HashMap;
10import java.util.HashSet;
11import java.util.Iterator;
12import java.util.Map;
13import java.util.Map.Entry;
14import java.util.Set;
15
16import org.onosproject.cluster.DefaultControllerNode;
17import org.onosproject.cluster.NodeId;
18import org.onlab.packet.IpAddress;
19import org.slf4j.Logger;
20
21import com.fasterxml.jackson.core.JsonEncoding;
22import com.fasterxml.jackson.core.JsonFactory;
23import com.fasterxml.jackson.databind.JsonNode;
24import com.fasterxml.jackson.databind.ObjectMapper;
25import com.fasterxml.jackson.databind.node.ArrayNode;
26import com.fasterxml.jackson.databind.node.ObjectNode;
27import com.google.common.collect.Maps;
28
29/**
30 * Allows for reading and writing partitioned database definition as a JSON file.
31 */
32public class DatabaseDefinitionStore {
33
34 private final Logger log = getLogger(getClass());
35
36 private final File definitionfile;
37
38 /**
39 * Creates a reader/writer of the database definition file.
40 *
41 * @param filePath location of the definition file
42 */
43 public DatabaseDefinitionStore(String filePath) {
44 definitionfile = new File(filePath);
45 }
46
47 /**
48 * Creates a reader/writer of the database definition file.
49 *
50 * @param filePath location of the definition file
51 */
52 public DatabaseDefinitionStore(File filePath) {
53 definitionfile = checkNotNull(filePath);
54 }
55
56 /**
57 * Returns the Map from database partition name to set of initial active member nodes.
58 *
59 * @return Map from partition name to set of active member nodes
60 * @throws IOException when I/O exception of some sort has occurred.
61 */
62 public Map<String, Set<DefaultControllerNode>> read() throws IOException {
63
64 final Map<String, Set<DefaultControllerNode>> partitions = Maps.newHashMap();
65
66 final ObjectMapper mapper = new ObjectMapper();
67 final ObjectNode tabletNodes = (ObjectNode) mapper.readTree(definitionfile);
68 final Iterator<Entry<String, JsonNode>> fields = tabletNodes.fields();
69 while (fields.hasNext()) {
70 final Entry<String, JsonNode> next = fields.next();
71 final Set<DefaultControllerNode> nodes = new HashSet<>();
72 final Iterator<JsonNode> elements = next.getValue().elements();
73 while (elements.hasNext()) {
74 ObjectNode nodeDef = (ObjectNode) elements.next();
75 nodes.add(new DefaultControllerNode(new NodeId(nodeDef.get("id").asText()),
76 IpAddress.valueOf(nodeDef.get("ip").asText()),
77 nodeDef.get("tcpPort").asInt(DatabaseManager.COPYCAT_TCP_PORT)));
78 }
79
80 partitions.put(next.getKey(), nodes);
81 }
82 return partitions;
83 }
84
85 /**
86 * Updates the Map from database partition name to set of member nodes.
87 *
88 * @param partitionName name of the database partition to update
89 * @param nodes set of initial member nodes
90 * @throws IOException when I/O exception of some sort has occurred.
91 */
92 public void write(String partitionName, Set<DefaultControllerNode> nodes) throws IOException {
93 checkNotNull(partitionName);
94 checkArgument(partitionName.isEmpty(), "Partition name cannot be empty");
95
96 // load current
97 Map<String, Set<DefaultControllerNode>> config;
98 try {
99 config = read();
100 } catch (IOException e) {
101 log.info("Reading partition config failed, assuming empty definition.");
102 config = new HashMap<>();
103 }
104 // update with specified
105 config.put(partitionName, nodes);
106
107 // write back to file
108 final ObjectMapper mapper = new ObjectMapper();
109 final ObjectNode partitionNodes = mapper.createObjectNode();
110 for (Entry<String, Set<DefaultControllerNode>> tablet : config.entrySet()) {
111 ArrayNode nodeDefs = mapper.createArrayNode();
112 partitionNodes.set(tablet.getKey(), nodeDefs);
113
114 for (DefaultControllerNode node : tablet.getValue()) {
115 ObjectNode nodeDef = mapper.createObjectNode();
116 nodeDef.put("id", node.id().toString())
117 .put("ip", node.ip().toString())
118 .put("tcpPort", node.tcpPort());
119 nodeDefs.add(nodeDef);
120 }
121 }
122 mapper.writeTree(new JsonFactory().createGenerator(definitionfile, JsonEncoding.UTF8),
123 partitionNodes);
124 }
125}