blob: b3e284e741703b17467775c3b97ee8d6866dbf82 [file] [log] [blame]
Brian O'Connorc67f9fa2014-08-07 18:17:46 -07001package net.floodlightcontroller.debugevent;
2
3import java.lang.ref.SoftReference;
4import java.lang.reflect.Field;
5import java.text.SimpleDateFormat;
6import java.util.HashMap;
7import java.util.List;
8import java.util.Map;
9
10import net.floodlightcontroller.debugevent.IDebugEventService.EventColumn;
11import net.onrc.onos.core.packet.IPv4;
12import net.onrc.onos.core.util.SwitchPort;
13
14import org.openflow.protocol.OFFlowMod;
15import org.openflow.util.HexString;
16
17public class Event {
18 long timestamp;
19 long threadId;
20 String threadName;
21 Object eventData;
22 private Map<String, String> returnMap;
23
24 public Event(long timestamp, long threadId, String threadName, Object eventData) {
25 super();
26 this.timestamp = timestamp;
27 this.threadId = threadId;
28 this.threadName = threadName;
29 this.eventData = eventData;
30 }
31
32 public long getTimestamp() {
33 return timestamp;
34 }
35
36 public void setTimestamp(long timestamp) {
37 this.timestamp = timestamp;
38 }
39
40 public long getThreadId() {
41 return threadId;
42 }
43
44 public void setThreadId(long threadId) {
45 this.threadId = threadId;
46 }
47
48 public String getThreadName() {
49 return threadName;
50 }
51
52 public void setThreadName(String threadName) {
53 this.threadName = threadName;
54 }
55
56 public Object geteventData() {
57 return eventData;
58 }
59
60 public void seteventData(Object eventData) {
61 this.eventData = eventData;
62 }
63
64 /**
65 * If an old event (eg. popped from a circular buffer) is being re-used for
66 * storing a new event, it is very important to clear the cached formatted
67 * event, so that the formatting can be redone with the new event data.
68 * Otherwise it will appear as if the circular buffer is not getting updated
69 * at all as old (cached) formatted event is delivered to the user.
70 */
71 public void nullifyCachedFormattedEvent() {
72 this.returnMap = null;
73 }
74
75 @Override
76 public String toString() {
77 return "Event [timestamp=" + timestamp + ", threadId=" + threadId
78 + ", eventData=" + eventData.toString() + "]";
79 }
80
81 public Map<String, String> getFormattedEvent(Class<?> eventClass, String moduleEventName) {
82 if (eventClass == null || !eventClass.equals(eventData.getClass())) {
83 returnMap = new HashMap<String, String>();
84 returnMap.put("Error", "null event data or event-class does not match event-data");
85 return returnMap;
86 }
87 // return cached value if there is one
88 if (returnMap != null)
89 return returnMap;
90
91 returnMap = new HashMap<String, String>();
92 returnMap.put("Timestamp", new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
93 .format(timestamp));
94 returnMap.put("Thread Id", String.valueOf(threadId));
95 returnMap.put("Thread Name", String.valueOf(threadName));
96 customFormat(eventClass, eventData, returnMap);
97 return returnMap;
98 }
99
100 private void customFormat(Class<?> clazz, Object eventData,
101 Map<String, String> retMap) {
102 for (Field f : clazz.getDeclaredFields()) {
103 EventColumn ec = f.getAnnotation(EventColumn.class);
104 if (ec == null) continue;
105 f.setAccessible(true);
106 try {
107 Object obj = f.get(eventData);
108
109 switch(ec.description()) {
110 case DPID:
111 retMap.put(ec.name(), HexString.toHexString((Long) obj));
112 break;
113 case MAC:
114 retMap.put(ec.name(), HexString.toHexString((Long) obj, 6));
115 break;
116 case IPv4:
117 retMap.put(ec.name(), net.onrc.onos.core.packet.IPv4.fromIPv4Address((Integer) obj));
118 break;
119 case FLOW_MOD_FLAGS:
120 int flags = (Integer)obj;
121 StringBuilder builder = new StringBuilder();
122 if (flags == 0) {
123 builder.append("None");
124 }
125 else {
126 if ((flags & OFFlowMod.OFPFF_SEND_FLOW_REM) != 0) {
127 builder.append("SEND_FLOW_REM ");
128 }
129 if ((flags & OFFlowMod.OFPFF_CHECK_OVERLAP) != 0) {
130 builder.append("CHECK_OVERLAP ");
131 }
132 if ((flags & OFFlowMod.OFPFF_EMERG) != 0) {
133 builder.append("EMERG ");
134 }
135 }
136 retMap.put(ec.name(), builder.toString());
137 break;
138 case LIST_IPV4:
139 @SuppressWarnings("unchecked")
140 List<Integer> ipv4Addresses = (List<Integer>)obj;
141 StringBuilder ipv4AddressesStr = new StringBuilder();
142 if (ipv4Addresses.size() == 0) {
143 ipv4AddressesStr.append("--");
144 } else {
145 for (Integer ipv4Addr : ipv4Addresses) {
146 ipv4AddressesStr.append(IPv4.fromIPv4Address(ipv4Addr.intValue()));
147 ipv4AddressesStr.append(" ");
148 }
149 }
150 retMap.put(ec.name(), ipv4AddressesStr.toString());
151 break;
152 case LIST_ATTACHMENT_POINT:
153 @SuppressWarnings("unchecked")
154 List<SwitchPort> aps = (List<SwitchPort>)obj;
155 StringBuilder apsStr = new StringBuilder();
156 if (aps.size() == 0) {
157 apsStr.append("--");
158 } else {
159 for (SwitchPort ap : aps) {
160 apsStr.append(HexString.toHexString(ap.dpid().value()));
161 apsStr.append("/");
162 apsStr.append(ap.port().value());
163 apsStr.append(" ");
164 }
165 }
166 retMap.put(ec.name(), apsStr.toString());
167 break;
168 case LIST_OBJECT:
169 @SuppressWarnings("unchecked")
170 List<Object> obl = (List<Object>)obj;
171 StringBuilder sbldr = new StringBuilder();
172 if (obl.size() == 0) {
173 sbldr.append("--");
174 } else {
175 for (Object o : obl) {
176 sbldr.append(o.toString());
177 sbldr.append(" ");
178 }
179 }
180 retMap.put(ec.name(), sbldr.toString());
181 break;
182 case SREF_LIST_OBJECT:
183 @SuppressWarnings("unchecked")
184 SoftReference<List<Object>> srefListObj =
185 (SoftReference<List<Object>>)obj;
186 List<Object> ol = srefListObj.get();
187 if (ol != null) {
188 StringBuilder sb = new StringBuilder();
189 if (ol.size() == 0) {
190 sb.append("--");
191 } else {
192 for (Object o : ol) {
193 sb.append(o.toString());
194 sb.append(" ");
195 }
196 }
197 retMap.put(ec.name(), sb.toString());
198 } else {
199 retMap.put(ec.name(), "-- reference not available --");
200 }
201 break;
202 case SREF_OBJECT:
203 @SuppressWarnings("unchecked")
204 SoftReference<Object> srefObj = (SoftReference<Object>)obj;
205 if (srefObj == null) {
206 retMap.put(ec.name(), "--");
207 } else {
208 Object o = srefObj.get();
209 if (o != null) {
210 retMap.put(ec.name(), o.toString());
211 } else {
212 retMap.put(ec.name(),
213 "-- reference not available --");
214 }
215 }
216 break;
217 case STRING:
218 case OBJECT:
219 case PRIMITIVE:
220 default:
221 retMap.put(ec.name(), obj.toString());
222 }
223 } catch (ClassCastException e) {
224 retMap.put("Error", e.getMessage());
225 } catch (IllegalArgumentException e) {
226 retMap.put("Error", e.getMessage());
227 } catch (IllegalAccessException e) {
228 retMap.put("Error", e.getMessage());
229 }
230 }
231 }
232
233}