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