Yuta HIGUCHI | 1ef85c4 | 2014-01-29 17:23:21 -0800 | [diff] [blame] | 1 | package net.onrc.onos.datastore.topology; |
| 2 | |
| 3 | import java.nio.ByteBuffer; |
| 4 | import java.util.HashMap; |
| 5 | import java.util.Map; |
| 6 | |
| 7 | import org.slf4j.Logger; |
| 8 | import org.slf4j.LoggerFactory; |
| 9 | |
| 10 | import com.esotericsoftware.kryo.Kryo; |
| 11 | |
| 12 | import net.onrc.onos.datastore.RCObject; |
| 13 | import net.onrc.onos.datastore.RCTable; |
| 14 | |
| 15 | public class RCLink extends RCObject { |
| 16 | @SuppressWarnings("unused") |
| 17 | private static final Logger log = LoggerFactory.getLogger(RCLink.class); |
| 18 | |
| 19 | private static final ThreadLocal<Kryo> linkKryo = new ThreadLocal<Kryo>() { |
| 20 | @Override |
| 21 | protected Kryo initialValue() { |
| 22 | Kryo kryo = new Kryo(); |
| 23 | kryo.setRegistrationRequired(true); |
| 24 | kryo.setReferences(false); |
| 25 | kryo.register(byte[].class); |
| 26 | kryo.register(byte[][].class); |
| 27 | kryo.register(HashMap.class); |
| 28 | // TODO check if we should explicitly specify EnumSerializer |
| 29 | kryo.register(STATUS.class); |
| 30 | return kryo; |
| 31 | } |
| 32 | }; |
| 33 | |
| 34 | public static class SwitchPort { |
| 35 | public final Long dpid; |
| 36 | public final Long number; |
| 37 | |
| 38 | public SwitchPort(Long dpid, Long number) { |
| 39 | this.dpid = dpid; |
| 40 | this.number = number; |
| 41 | } |
| 42 | |
| 43 | public byte[] getPortID() { |
| 44 | return RCPort.getPortID(dpid, number); |
| 45 | } |
| 46 | |
| 47 | public byte[] getSwitchID() { |
| 48 | return RCSwitch.getSwichID(dpid); |
| 49 | } |
Yuta HIGUCHI | c9d06ef | 2014-01-31 15:55:12 -0800 | [diff] [blame^] | 50 | |
| 51 | @Override |
| 52 | public String toString() { |
| 53 | return "(" + Long.toHexString(dpid) + "@" + number + ")"; |
| 54 | } |
| 55 | |
Yuta HIGUCHI | 1ef85c4 | 2014-01-29 17:23:21 -0800 | [diff] [blame] | 56 | } |
| 57 | |
| 58 | public static final String GLOBAL_LINK_TABLE_NAME = "G:Link"; |
| 59 | |
| 60 | // FIXME these should be Enum or some number, not String |
| 61 | private static final String PROP_STATUS = "status"; |
| 62 | private static final String PROP_SRC_SW_ID = "src-sw-id"; |
| 63 | private static final String PROP_SRC_PORT_ID = "src-port-id"; |
| 64 | private static final String PROP_DST_SW_ID = "dst-sw-id"; |
| 65 | private static final String PROP_DST_PORT_ID = "dst-port-id"; |
| 66 | |
| 67 | // must not re-order enum members, ordinal will be sent over wire |
| 68 | public enum STATUS { |
| 69 | INACTIVE, ACTIVE; |
| 70 | } |
| 71 | |
| 72 | private final SwitchPort src; |
| 73 | private final SwitchPort dst; |
| 74 | private STATUS status; |
| 75 | |
| 76 | public static final int LINKID_BYTES = 2 + RCPort.PORTID_BYTES * 2; |
| 77 | |
| 78 | public static byte[] getLinkID(Long src_dpid, Long src_port_no, |
| 79 | Long dst_dpid, Long dst_port_no) { |
| 80 | return ByteBuffer.allocate(LINKID_BYTES).putChar('L') |
| 81 | .put(RCPort.getPortID(src_dpid, src_port_no)) |
| 82 | .put(RCPort.getPortID(dst_dpid, dst_port_no)).array(); |
| 83 | } |
| 84 | |
Yuta HIGUCHI | c9d06ef | 2014-01-31 15:55:12 -0800 | [diff] [blame^] | 85 | public static long[] getLinkTupleFromKey(byte[] key) { |
| 86 | return getLinkTupleFromKey(ByteBuffer.wrap(key)); |
| 87 | } |
| 88 | |
| 89 | public static long[] getLinkTupleFromKey(ByteBuffer keyBuf) { |
| 90 | long tuple[] = new long[4]; |
| 91 | if (keyBuf.getChar() != 'L') { |
| 92 | throw new IllegalArgumentException("Invalid Link key"); |
| 93 | } |
| 94 | long src_port_pair[] = RCPort.getPortPairFromKey(keyBuf.slice()); |
| 95 | keyBuf.position(2 + RCPort.PORTID_BYTES); |
| 96 | long dst_port_pair[] = RCPort.getPortPairFromKey(keyBuf.slice()); |
| 97 | |
| 98 | tuple[0] = src_port_pair[0]; |
| 99 | tuple[1] = src_port_pair[1]; |
| 100 | tuple[2] = dst_port_pair[0]; |
| 101 | tuple[3] = dst_port_pair[1]; |
| 102 | |
| 103 | return tuple; |
| 104 | } |
| 105 | |
Yuta HIGUCHI | 1ef85c4 | 2014-01-29 17:23:21 -0800 | [diff] [blame] | 106 | public RCLink(Long src_dpid, Long src_port_no, Long dst_dpid, |
| 107 | Long dst_port_no) { |
| 108 | super(RCTable.getTable(GLOBAL_LINK_TABLE_NAME), getLinkID(src_dpid, |
| 109 | src_port_no, dst_dpid, dst_port_no)); |
| 110 | |
| 111 | src = new SwitchPort(src_dpid, src_port_no); |
| 112 | dst = new SwitchPort(dst_dpid, dst_port_no); |
| 113 | status = STATUS.INACTIVE; |
| 114 | } |
| 115 | |
Yuta HIGUCHI | c9d06ef | 2014-01-31 15:55:12 -0800 | [diff] [blame^] | 116 | public static RCLink createFromKey(byte[] key) { |
| 117 | long linkTuple[] = getLinkTupleFromKey(key); |
| 118 | return new RCLink(linkTuple[0], linkTuple[1], linkTuple[2], |
| 119 | linkTuple[3]); |
| 120 | } |
| 121 | |
Yuta HIGUCHI | 1ef85c4 | 2014-01-29 17:23:21 -0800 | [diff] [blame] | 122 | public STATUS getStatus() { |
| 123 | return status; |
| 124 | } |
| 125 | |
| 126 | public void setStatus(STATUS status) { |
| 127 | this.status = status; |
| 128 | getObjectMap().put(PROP_STATUS, status); |
| 129 | } |
| 130 | |
| 131 | public SwitchPort getSrc() { |
| 132 | return src; |
| 133 | } |
| 134 | |
| 135 | public SwitchPort getDst() { |
| 136 | return dst; |
| 137 | } |
| 138 | |
| 139 | public byte[] getId() { |
| 140 | return getKey(); |
| 141 | } |
| 142 | |
| 143 | @Override |
| 144 | public void serializeAndSetValue() { |
| 145 | Map<Object, Object> map = getObjectMap(); |
| 146 | |
| 147 | map.put(PROP_SRC_SW_ID, src.getSwitchID()); |
| 148 | map.put(PROP_SRC_PORT_ID, src.getPortID()); |
| 149 | map.put(PROP_DST_SW_ID, dst.getSwitchID()); |
| 150 | map.put(PROP_DST_PORT_ID, dst.getPortID()); |
| 151 | |
| 152 | serializeAndSetValue(linkKryo.get(), map); |
| 153 | } |
| 154 | |
| 155 | @Override |
| 156 | public Map<Object, Object> deserializeObjectFromValue() { |
| 157 | Map<Object, Object> map = deserializeObjectFromValue(linkKryo.get()); |
| 158 | |
| 159 | this.status = (STATUS) map.get(PROP_STATUS); |
| 160 | return map; |
| 161 | } |
| 162 | |
Yuta HIGUCHI | c9d06ef | 2014-01-31 15:55:12 -0800 | [diff] [blame^] | 163 | @Override |
| 164 | public String toString() { |
| 165 | return "[RCLink " + src + "->" + dst + " STATUS:" + status + "]"; |
| 166 | } |
| 167 | |
Yuta HIGUCHI | 1ef85c4 | 2014-01-29 17:23:21 -0800 | [diff] [blame] | 168 | public static void main(String[] args) { |
| 169 | // TODO Auto-generated method stub |
| 170 | |
| 171 | } |
| 172 | |
| 173 | } |