Skip to content

Commit 8e016f3

Browse files
committed
Include host information to snapshots.
Catch exception to be sure not to fail initialization.
1 parent 538932b commit 8e016f3

File tree

3 files changed

+165
-8
lines changed

3 files changed

+165
-8
lines changed

tmc-plugin/src/fi/helsinki/cs/tmc/spyware/LoggableEvent.java

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,32 @@
33
import fi.helsinki.cs.tmc.data.Course;
44
import fi.helsinki.cs.tmc.data.Exercise;
55
import fi.helsinki.cs.tmc.events.TmcEvent;
6+
import fi.helsinki.cs.tmc.utilities.JsonMaker;
7+
import java.net.NetworkInterface;
8+
import java.net.SocketException;
9+
import java.net.UnknownHostException;
10+
import java.util.ArrayList;
11+
import java.util.Enumeration;
12+
import java.util.List;
13+
import java.util.logging.Level;
14+
import java.util.logging.Logger;
615
import org.netbeans.api.annotations.common.NullAllowed;
716

817
public class LoggableEvent implements TmcEvent {
918

19+
private static final Logger log = Logger.getLogger(LoggableEvent.class.getName());
20+
21+
private static int GLOBAL_HOST_ID;
22+
1023
private String courseName;
1124
private String exerciseName;
1225
private String eventType;
26+
private int hostId;
27+
1328
private byte[] data;
14-
@NullAllowed private String metadata;
29+
30+
@NullAllowed
31+
private String metadata;
1532
private long happenedAt; // millis from epoch
1633
private long systemNanotime;
1734
private transient String key;
@@ -45,6 +62,7 @@ public LoggableEvent(String courseName, String exerciseName, String eventType, b
4562
this.happenedAt = System.currentTimeMillis();
4663
this.systemNanotime = System.nanoTime();
4764

65+
this.hostId = LoggableEvent.GLOBAL_HOST_ID;
4866
this.key = courseName + "|" + exerciseName + "|" + eventType;
4967
}
5068

@@ -64,6 +82,22 @@ public byte[] getData() {
6482
return data;
6583
}
6684

85+
public int getHostId() {
86+
return hostId;
87+
}
88+
89+
public void setHostId(int hostId) {
90+
this.hostId = hostId;
91+
}
92+
93+
public static void setGlobalHostId(int globalHostId) {
94+
LoggableEvent.GLOBAL_HOST_ID = globalHostId;
95+
}
96+
97+
public static int getGlobalHostId() {
98+
return GLOBAL_HOST_ID;
99+
}
100+
67101
/**
68102
* Optional JSON metadata.
69103
*/
@@ -90,8 +124,51 @@ public long getSystemNanotime() {
90124
return systemNanotime;
91125
}
92126

127+
128+
129+
93130
@Override
94131
public String toString() {
95132
return "LoggableEvent{" + "courseName=" + courseName + ", exerciseName=" + exerciseName + ", eventType=" + eventType + ", happenedAt=" + happenedAt + ", systemNanotime=" + systemNanotime + ", key=" + key + ", metadata=" + metadata + ", data=" + new String(data) + "}";
96133
}
134+
135+
/**
136+
* Generates information which should mostly be static throughout netbeans
137+
* session. However, the ip address sure could change.
138+
*/
139+
private static String getStaticHostInformation() {
140+
JsonMaker builder = JsonMaker.create();
141+
142+
try {
143+
java.net.InetAddress localMachine = java.net.InetAddress.getLocalHost();
144+
builder.add("hostAddress", localMachine.getHostAddress());
145+
builder.add("hostName", localMachine.getHostName());
146+
} catch (UnknownHostException ex) {
147+
log.log(Level.WARNING, "Exception while getting host name information: {0}", ex);
148+
}
149+
150+
try {
151+
Enumeration<NetworkInterface> iterator = NetworkInterface.getNetworkInterfaces();
152+
List<String> macs = new ArrayList<String>(2);
153+
while (iterator.hasMoreElements()) {
154+
NetworkInterface networkInterface = iterator.nextElement();
155+
if (networkInterface.isUp() && !networkInterface.isLoopback()) {
156+
byte[] mac = networkInterface.getHardwareAddress();
157+
StringBuilder sb = new StringBuilder();
158+
for (int i = 0; i < mac.length; i++) {
159+
sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? ":" : ""));
160+
}
161+
macs.add(sb.toString());
162+
}
163+
164+
}
165+
builder.add("mac", macs);
166+
167+
} catch (SocketException ex) {
168+
log.log(Level.WARNING, "Exception while getting host mac information: {0}", ex);
169+
}
170+
171+
builder.add("hostUsername", System.getProperty("user.name"));
172+
return builder.toString();
173+
}
97174
}

tmc-plugin/src/fi/helsinki/cs/tmc/spyware/SpywareFacade.java

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,23 @@
66
import fi.helsinki.cs.tmc.events.TmcEventBus;
77
import fi.helsinki.cs.tmc.model.CourseDb;
88
import fi.helsinki.cs.tmc.model.ServerAccess;
9+
import fi.helsinki.cs.tmc.model.TmcProjectInfo;
910
import fi.helsinki.cs.tmc.model.TmcSettings;
1011
import fi.helsinki.cs.tmc.spyware.eventsources.TextInsertEventSource;
1112
import fi.helsinki.cs.tmc.spyware.eventsources.ProjectActionCaptor;
1213
import fi.helsinki.cs.tmc.spyware.eventsources.ProjectActionEventSource;
1314
import fi.helsinki.cs.tmc.spyware.eventsources.SourceSnapshotEventSource;
1415
import fi.helsinki.cs.tmc.spyware.eventsources.TmcEventBusEventSource;
16+
import fi.helsinki.cs.tmc.utilities.JsonMaker;
1517
import fi.helsinki.cs.tmc.utilities.TmcSwingUtilities;
18+
import java.net.NetworkInterface;
19+
import java.net.SocketException;
20+
import java.net.UnknownHostException;
21+
import java.nio.charset.Charset;
22+
import java.util.ArrayList;
23+
import java.util.Enumeration;
24+
import java.util.List;
25+
import java.util.logging.Level;
1626
import java.util.logging.Logger;
1727

1828
public class SpywareFacade implements SpywareSettings {
@@ -27,6 +37,8 @@ public static void start() {
2737
}
2838
instance = new SpywareFacade();
2939
TmcEventBus.getDefault().post(new InvokedEvent("spyware_loaded"));
40+
41+
updateHostInformation();
3042
}
3143

3244
public static void close() {
@@ -126,4 +138,59 @@ public InvokedEvent(String message) {
126138
this.message = message;
127139
}
128140
}
141+
142+
private static void updateHostInformation() {
143+
JsonMaker data = getStaticHostInformation();
144+
// Should be unique enough not to collapse among singe users machines.
145+
int hostId = data.toString().hashCode();
146+
LoggableEvent.setGlobalHostId(hostId);
147+
148+
data.add("hostId", hostId);
149+
150+
LoggableEvent event = new LoggableEvent("host_information_update", data.toString().getBytes(Charset.forName("UTF-8")));
151+
TmcEventBus.getDefault().post(event);
152+
}
153+
154+
private static JsonMaker getStaticHostInformation() {
155+
JsonMaker builder = JsonMaker.create();
156+
157+
try {
158+
java.net.InetAddress localMachine = java.net.InetAddress.getLocalHost();
159+
builder.add("hostAddress", localMachine.getHostAddress());
160+
builder.add("hostName", localMachine.getHostName());
161+
} catch (Exception ex) {
162+
log.log(Level.WARNING, "Exception while getting host name information: {0}", ex);
163+
}
164+
165+
try {
166+
Enumeration<NetworkInterface> iterator = NetworkInterface.getNetworkInterfaces();
167+
List<String> macs = new ArrayList<String>(2);
168+
while (iterator.hasMoreElements()) {
169+
NetworkInterface networkInterface = iterator.nextElement();
170+
if (networkInterface.isUp() && !networkInterface.isLoopback()) {
171+
byte[] mac = networkInterface.getHardwareAddress();
172+
StringBuilder sb = new StringBuilder();
173+
for (int i = 0; i < mac.length; i++) {
174+
sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? ":" : ""));
175+
}
176+
macs.add(sb.toString());
177+
}
178+
}
179+
builder.add("mac_addresses", macs);
180+
181+
} catch (Exception ex) {
182+
log.log(Level.WARNING, "Exception while getting host mac information: {0}", ex);
183+
}
184+
185+
try {
186+
builder.add("user.name", System.getProperty("user.name"));
187+
builder.add("java.runtime.version", System.getProperty("java.runtime.version"));
188+
builder.add("os.name", System.getProperty("os.name"));
189+
builder.add("os.version", System.getProperty("os.version"));
190+
} catch (Exception e) {
191+
log.log(Level.WARNING, "Exception while getting basic host information: {0}", e);
192+
}
193+
194+
return builder;
195+
}
129196
}

tmc-plugin/src/fi/helsinki/cs/tmc/utilities/JsonMaker.java

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package fi.helsinki.cs.tmc.utilities;
22

3+
import com.google.gson.JsonArray;
4+
import com.google.gson.JsonElement;
35
import com.google.gson.JsonObject;
6+
import com.google.gson.JsonPrimitive;
7+
import java.util.List;
48

59
/**
610
* A convenient way to build ad-hoc JSON objects.
@@ -9,34 +13,43 @@ public class JsonMaker {
913
public static JsonMaker create() {
1014
return new JsonMaker();
1115
}
12-
16+
1317
private JsonObject toplevel;
1418

1519
public JsonMaker() {
1620
this(new JsonObject());
1721
}
18-
22+
1923
public JsonMaker(JsonObject toplevel) {
2024
this.toplevel = toplevel;
2125
}
22-
26+
2327
public JsonMaker add(String name, String value) {
2428
toplevel.addProperty(name, value);
2529
return this;
2630
}
27-
31+
2832
public JsonMaker add(String name, long value) {
2933
toplevel.addProperty(name, value);
3034
return this;
3135
}
32-
36+
3337
public JsonMaker add(String name, boolean value) {
3438
toplevel.addProperty(name, value);
3539
return this;
3640
}
37-
41+
42+
public JsonMaker add(String name, List<String> values) {
43+
JsonArray ary = new JsonArray();
44+
for (String value : values) {
45+
ary.add(new JsonPrimitive(value));
46+
}
47+
toplevel.add(name, ary);
48+
return this;
49+
}
50+
3851
// Will add more methods as needed
39-
52+
4053
/**
4154
* Returns the JSON text.
4255
*/

0 commit comments

Comments
 (0)