blob: 0e8afe4fa9cdb7fee144a714e5163d0486960354 [file] [log] [blame]
Yuta HIGUCHI1ef85c42014-01-29 17:23:21 -08001package net.onrc.onos.datastore.topology;
2
3import java.nio.ByteBuffer;
4import java.util.Arrays;
5import java.util.Collection;
6import java.util.Collections;
7import java.util.HashMap;
8import java.util.Map;
9import java.util.Set;
10import java.util.TreeSet;
11
12import org.slf4j.Logger;
13import org.slf4j.LoggerFactory;
14
15import com.esotericsoftware.kryo.Kryo;
16
17import net.onrc.onos.datastore.RCObject;
18import net.onrc.onos.datastore.RCTable;
19import net.onrc.onos.datastore.topology.RCLink.STATUS;
20import net.onrc.onos.datastore.utils.ByteArrayComparator;
21
22public class RCDevice extends RCObject {
23 @SuppressWarnings("unused")
24 private static final Logger log = LoggerFactory.getLogger(RCDevice.class);
25
26 private static final ThreadLocal<Kryo> deviceKryo = new ThreadLocal<Kryo>() {
27 @Override
28 protected Kryo initialValue() {
29 Kryo kryo = new Kryo();
30 kryo.setRegistrationRequired(true);
31 kryo.setReferences(false);
32 kryo.register(byte[].class);
33 kryo.register(byte[][].class);
34 kryo.register(HashMap.class);
35 // TODO check if we should explicitly specify EnumSerializer
36 kryo.register(STATUS.class);
37 return kryo;
38 }
39 };
40
41 public static final String GLOBAL_DEVICE_TABLE_NAME = "G:Device";
42
43 // FIXME these should be Enum or some number, not String
44 private static final String PROP_MAC = "mac";
45 private static final String PROP_PORT_IDS = "port-ids";
46
47 private final byte[] mac;
48 private TreeSet<byte[]> portIds;
49 transient private boolean isPortIdsModified;
50
51 // Assuming mac is unique cluster-wide
52 public static byte[] getDeviceID(final byte[] mac) {
53 return ByteBuffer.allocate(2 + mac.length).putChar('D').put(mac)
54 .array();
55 }
56
57 public static byte[] getMacFromKey(byte[] key) {
58 ByteBuffer keyBuf = ByteBuffer.wrap(key);
59 if (keyBuf.getChar() != 'D') {
60 throw new IllegalArgumentException("Invalid Device key");
61 }
62 byte[] mac = new byte[keyBuf.remaining()];
63 keyBuf.get(mac);
64 return mac;
65 }
66
67 public RCDevice(byte[] mac) {
68 super(RCTable.getTable(GLOBAL_DEVICE_TABLE_NAME), getDeviceID(mac));
69
70 this.mac = mac;
71 this.portIds = new TreeSet<>(ByteArrayComparator.BYTEARRAY_COMPARATOR);
72 this.isPortIdsModified = true;
73 }
74
75 public static RCDevice createFromKey(byte[] key) {
76 return new RCDevice(getMacFromKey(key));
77 }
78
79 public byte[] getMac() {
80 // TODO may need to clone() to be sure this object will be immutable.
81 return mac;
82 }
83
84 public byte[] getId() {
85 return getKey();
86 }
87
88 public void addPortId(byte[] portId) {
89 // TODO: Should we copy portId, or reference is OK.
90 isPortIdsModified |= portIds.add(portId);
91 }
92
93 public void removePortId(byte[] portId) {
94 isPortIdsModified |= portIds.remove(portId);
95 }
96
97 public void emptyPortIds() {
98 portIds.clear();
99 this.isPortIdsModified = true;
100 }
101
102 public void addAllToPortIds(Collection<byte[]> portIds) {
103 // TODO: Should we copy portId, or reference is OK.
104 isPortIdsModified |= this.portIds.addAll(portIds);
105 }
106
107 /**
108 *
109 * @return Unmodifiable Set view of all the PortIds;
110 */
111 public Set<byte[]> getAllPortIds() {
112 return Collections.unmodifiableSet(portIds);
113 }
114
115 @Override
116 public void serializeAndSetValue() {
117 Map<Object, Object> map = getObjectMap();
118
119 map.put(PROP_MAC, mac);
120 if (isPortIdsModified) {
121 byte[] portIdArray[] = new byte[portIds.size()][];
122 map.put(PROP_PORT_IDS, portIds.toArray(portIdArray));
123 isPortIdsModified = false;
124 }
125
126 serializeAndSetValue(deviceKryo.get(), map);
127 }
128
129 @Override
130 public Map<Object, Object> deserializeObjectFromValue() {
131 Map<Object, Object> map = deserializeObjectFromValue(deviceKryo.get());
132
133 if (this.portIds == null) {
134 this.portIds = new TreeSet<>(
135 ByteArrayComparator.BYTEARRAY_COMPARATOR);
136 }
137 byte[] portIdArray[] = (byte[][]) map.get(PROP_PORT_IDS);
138 if (portIdArray != null) {
139 this.portIds.clear();
140 this.portIds.addAll(Arrays.asList(portIdArray));
141 isPortIdsModified = false;
142 } else {
143 // trigger write on next serialize
144 isPortIdsModified = true;
145 }
146
147 return map;
148 }
149
150 public static void main(String[] args) {
151 // TODO Auto-generated method stub
152
153 }
154
155}