blob: eec6a10d548b53021eac65a608225b1ef7d925e0 [file] [log] [blame]
Yuta HIGUCHI1ef85c42014-01-29 17:23:21 -08001package net.onrc.onos.datastore.topology;
2
3import java.nio.ByteBuffer;
4import java.util.HashMap;
Yuta HIGUCHI10eebea2014-02-03 10:41:41 -08005import java.util.Iterator;
Yuta HIGUCHI1ef85c42014-01-29 17:23:21 -08006import java.util.Map;
7
8import org.slf4j.Logger;
9import org.slf4j.LoggerFactory;
10
11import com.esotericsoftware.kryo.Kryo;
12
Yuta HIGUCHI10eebea2014-02-03 10:41:41 -080013import edu.stanford.ramcloud.JRamCloud;
Yuta HIGUCHI1ef85c42014-01-29 17:23:21 -080014import net.onrc.onos.datastore.RCObject;
15import net.onrc.onos.datastore.RCTable;
16
17public class RCLink extends RCObject {
18 @SuppressWarnings("unused")
19 private static final Logger log = LoggerFactory.getLogger(RCLink.class);
20
21 private static final ThreadLocal<Kryo> linkKryo = new ThreadLocal<Kryo>() {
22 @Override
23 protected Kryo initialValue() {
24 Kryo kryo = new Kryo();
25 kryo.setRegistrationRequired(true);
26 kryo.setReferences(false);
27 kryo.register(byte[].class);
28 kryo.register(byte[][].class);
29 kryo.register(HashMap.class);
30 // TODO check if we should explicitly specify EnumSerializer
31 kryo.register(STATUS.class);
32 return kryo;
33 }
34 };
35
36 public static class SwitchPort {
37 public final Long dpid;
38 public final Long number;
39
40 public SwitchPort(Long dpid, Long number) {
41 this.dpid = dpid;
42 this.number = number;
43 }
44
45 public byte[] getPortID() {
46 return RCPort.getPortID(dpid, number);
47 }
48
49 public byte[] getSwitchID() {
Yuta HIGUCHI10eebea2014-02-03 10:41:41 -080050 return RCSwitch.getSwitchID(dpid);
Yuta HIGUCHI1ef85c42014-01-29 17:23:21 -080051 }
Yuta HIGUCHIc9d06ef2014-01-31 15:55:12 -080052
53 @Override
54 public String toString() {
55 return "(" + Long.toHexString(dpid) + "@" + number + ")";
56 }
57
Yuta HIGUCHI1ef85c42014-01-29 17:23:21 -080058 }
59
60 public static final String GLOBAL_LINK_TABLE_NAME = "G:Link";
61
62 // FIXME these should be Enum or some number, not String
63 private static final String PROP_STATUS = "status";
64 private static final String PROP_SRC_SW_ID = "src-sw-id";
65 private static final String PROP_SRC_PORT_ID = "src-port-id";
66 private static final String PROP_DST_SW_ID = "dst-sw-id";
67 private static final String PROP_DST_PORT_ID = "dst-port-id";
68
69 // must not re-order enum members, ordinal will be sent over wire
70 public enum STATUS {
71 INACTIVE, ACTIVE;
72 }
73
74 private final SwitchPort src;
75 private final SwitchPort dst;
76 private STATUS status;
77
78 public static final int LINKID_BYTES = 2 + RCPort.PORTID_BYTES * 2;
79
80 public static byte[] getLinkID(Long src_dpid, Long src_port_no,
81 Long dst_dpid, Long dst_port_no) {
82 return ByteBuffer.allocate(LINKID_BYTES).putChar('L')
83 .put(RCPort.getPortID(src_dpid, src_port_no))
84 .put(RCPort.getPortID(dst_dpid, dst_port_no)).array();
85 }
86
Yuta HIGUCHIc9d06ef2014-01-31 15:55:12 -080087 public static long[] getLinkTupleFromKey(byte[] key) {
88 return getLinkTupleFromKey(ByteBuffer.wrap(key));
89 }
90
91 public static long[] getLinkTupleFromKey(ByteBuffer keyBuf) {
92 long tuple[] = new long[4];
93 if (keyBuf.getChar() != 'L') {
94 throw new IllegalArgumentException("Invalid Link key");
95 }
96 long src_port_pair[] = RCPort.getPortPairFromKey(keyBuf.slice());
97 keyBuf.position(2 + RCPort.PORTID_BYTES);
98 long dst_port_pair[] = RCPort.getPortPairFromKey(keyBuf.slice());
99
100 tuple[0] = src_port_pair[0];
101 tuple[1] = src_port_pair[1];
102 tuple[2] = dst_port_pair[0];
103 tuple[3] = dst_port_pair[1];
104
105 return tuple;
106 }
107
Yuta HIGUCHI1ef85c42014-01-29 17:23:21 -0800108 public RCLink(Long src_dpid, Long src_port_no, Long dst_dpid,
109 Long dst_port_no) {
110 super(RCTable.getTable(GLOBAL_LINK_TABLE_NAME), getLinkID(src_dpid,
111 src_port_no, dst_dpid, dst_port_no));
112
113 src = new SwitchPort(src_dpid, src_port_no);
114 dst = new SwitchPort(dst_dpid, dst_port_no);
115 status = STATUS.INACTIVE;
116 }
117
Yuta HIGUCHI10eebea2014-02-03 10:41:41 -0800118 /**
119 * Get an instance from Key.
120 *
121 * @note You need to call `read()` to get the DB content.
122 * @param key
123 * @return RCLink instance
124 */
125 public static <L extends RCObject> L createFromKey(byte[] key) {
Yuta HIGUCHIc9d06ef2014-01-31 15:55:12 -0800126 long linkTuple[] = getLinkTupleFromKey(key);
Yuta HIGUCHI10eebea2014-02-03 10:41:41 -0800127 @SuppressWarnings("unchecked")
128 L l = (L) new RCLink(linkTuple[0], linkTuple[1], linkTuple[2],
Yuta HIGUCHIc9d06ef2014-01-31 15:55:12 -0800129 linkTuple[3]);
Yuta HIGUCHI10eebea2014-02-03 10:41:41 -0800130 return l;
131 }
132
133 public static Iterable<RCLink> getAllLinks() {
134 return new LinkEnumerator();
135 }
136
137 public static class LinkEnumerator implements Iterable<RCLink> {
138
139 @Override
140 public Iterator<RCLink> iterator() {
141 return new LinkIterator();
142 }
143 }
144
145 public static class LinkIterator extends ObjectIterator<RCLink> {
146
147 public LinkIterator() {
148 super(RCTable.getTable(GLOBAL_LINK_TABLE_NAME));
149 }
150
151 @Override
152 public RCLink next() {
153 JRamCloud.Object o = enumerator.next();
154 RCLink e = RCLink.createFromKey(o.key);
155 e.setValueAndDeserialize(o.value, o.version);
156 return e;
157 }
Yuta HIGUCHIc9d06ef2014-01-31 15:55:12 -0800158 }
159
Yuta HIGUCHI1ef85c42014-01-29 17:23:21 -0800160 public STATUS getStatus() {
161 return status;
162 }
163
164 public void setStatus(STATUS status) {
165 this.status = status;
166 getObjectMap().put(PROP_STATUS, status);
167 }
168
169 public SwitchPort getSrc() {
170 return src;
171 }
172
173 public SwitchPort getDst() {
174 return dst;
175 }
176
177 public byte[] getId() {
178 return getKey();
179 }
180
181 @Override
182 public void serializeAndSetValue() {
183 Map<Object, Object> map = getObjectMap();
184
185 map.put(PROP_SRC_SW_ID, src.getSwitchID());
186 map.put(PROP_SRC_PORT_ID, src.getPortID());
187 map.put(PROP_DST_SW_ID, dst.getSwitchID());
188 map.put(PROP_DST_PORT_ID, dst.getPortID());
189
190 serializeAndSetValue(linkKryo.get(), map);
191 }
192
193 @Override
194 public Map<Object, Object> deserializeObjectFromValue() {
195 Map<Object, Object> map = deserializeObjectFromValue(linkKryo.get());
196
197 this.status = (STATUS) map.get(PROP_STATUS);
198 return map;
199 }
200
Yuta HIGUCHIc9d06ef2014-01-31 15:55:12 -0800201 @Override
202 public String toString() {
203 return "[RCLink " + src + "->" + dst + " STATUS:" + status + "]";
204 }
205
Yuta HIGUCHI1ef85c42014-01-29 17:23:21 -0800206 public static void main(String[] args) {
207 // TODO Auto-generated method stub
208
209 }
210
211}