1 package iotruntime.master;
4 import iotruntime.slave.IoTAddress;
5 import iotruntime.slave.IoTDeviceAddress;
6 import iotruntime.messages.*;
9 import org.objectweb.asm.ClassReader;
10 import org.objectweb.asm.ClassWriter;
11 import org.objectweb.asm.ClassVisitor;
16 import java.io.BufferedReader;
17 import java.io.InputStream;
18 import java.io.InputStreamReader;
20 import java.io.FileInputStream;
21 import java.io.FileOutputStream;
22 import java.io.OutputStream;
23 import java.io.ObjectInputStream;
24 import java.io.ObjectOutputStream;
25 import java.io.IOException;
26 import java.lang.ClassNotFoundException;
27 import java.lang.Class;
28 import java.lang.reflect.*;
29 import java.net.Socket;
30 import java.net.ServerSocket;
31 import java.nio.ByteBuffer;
33 import static java.lang.Math.toIntExact;
35 /** Class IoTMaster is responsible to use ClassRuntimeInstrumenterMaster
36 * to instrument the controller/device bytecode and starts multiple
37 * IoTSlave running on different JVM's in a distributed fashion.
39 * @author Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>
43 public final class IoTMaster {
46 * IoTMaster class properties
48 * CommunicationHandler maintains the data structure for hostnames and ports
49 * LoadBalancer assigns a job onto a host based on certain metrics
51 private CommunicationHandler commHan;
52 private LoadBalancer lbIoT;
53 private RouterConfig routerConfig;
54 private ProcessJailConfig processJailConfig;
55 private ObjectInitHandler objInitHand;
56 private ObjectAddressInitHandler objAddInitHand;
57 private String[] strObjectNames;
58 // Now this can be either ClassRuntimeInstrumenterMaster or CRuntimeInstrumenterMaster
59 private Map<String,Object> mapClassNameToCrim;
62 * These properties hold information of a certain object
65 private String strObjName;
66 private String strObjClassName;
67 private String strObjClassInterfaceName;
68 private String strObjStubClsIntfaceName;
69 private String strIoTMasterHostAdd;
70 private String strIoTSlaveControllerHostAdd;
71 private String strIoTSlaveObjectHostAdd;
72 private Class[] arrFieldClasses;
73 private Object[] arrFieldValues;
74 private Socket filesocket;
77 * For connection with C++ IoTSlave
79 private ServerSocket serverSocketCpp;
80 private Socket socketCpp;
81 private BufferedInputStream inputCpp;
82 private BufferedOutputStream outputCpp;
84 // Constants that are to be extracted from config file
85 private static String STR_MASTER_MAC_ADD;
86 private static String STR_IOT_CODE_PATH;
87 private static String STR_CONT_PATH;
88 private static String STR_RUNTIME_DIR;
89 private static String STR_SLAVE_DIR;
90 private static String STR_CLS_PATH;
91 private static String STR_RMI_PATH;
92 private static String STR_RMI_HOSTNAME;
93 private static String STR_LOG_FILE_PATH;
94 private static String STR_USERNAME;
95 private static String STR_ROUTER_ADD;
96 private static String STR_MONITORING_HOST;
97 private static String STR_ZB_GATEWAY_ADDRESS;
98 private static String STR_ZB_GATEWAY_PORT;
99 private static String STR_ZB_IOTMASTER_PORT;
100 private static String STR_JVM_INIT_HEAP_SIZE;
101 private static String STR_JVM_MAX_HEAP_SIZE;
102 private static String STR_LANGUAGE_CONTROLLER;
103 private static String STR_SKEL_CLASS_SUFFIX;
104 private static String STR_STUB_CLASS_SUFFIX;
105 private static String STR_ACTIVATE_SANDBOXING;
106 private static String STR_POLICY_ON;
107 private static String STR_MAC_TO_IP_TRANSLATION;
108 private static boolean BOOL_VERBOSE;
111 * IoTMaster class constants
113 * Name constants - not to be configured by users
115 private static final String STR_IOT_MASTER_NAME = "IoTMaster";
116 private static final String STR_CFG_FILE_EXT = ".config";
117 private static final String STR_CLS_FILE_EXT = ".class";
118 private static final String STR_JAR_FILE_EXT = ".jar";
119 private static final String STR_MAC_POLICY_EXT = ".tomoyo.pol";
120 private static final String STR_SHELL_FILE_EXT = ".sh";
121 private static final String STR_SO_FILE_EXT = ".so";
122 private static final String STR_ZIP_FILE_EXT = ".zip";
123 private static final String STR_TCP_PROTOCOL = "tcp";
124 private static final String STR_UDP_PROTOCOL = "udp";
125 private static final String STR_TCPGW_PROTOCOL = "tcpgw";
126 private static final String STR_NO_PROTOCOL = "nopro";
127 private static final String STR_SELF_MAC_ADD = "00:00:00:00:00:00";
128 private static final String STR_INTERFACE_CLS_CFG = "INTERFACE_CLASS";
129 private static final String STR_INT_STUB_CLS_CFG = "INTERFACE_STUB_CLASS";
130 private static final String STR_FILE_TRF_CFG = "ADDITIONAL_ZIP_FILE";
131 private static final String STR_LANGUAGE = "LANGUAGE";
132 private static final String STR_ADD_MAC_POL = "ADDITIONAL_MAC_POLICY";
133 private static final String STR_YES = "Yes";
134 private static final String STR_NO = "No";
135 private static final String STR_JAVA = "Java";
136 private static final String STR_CPP = "C++";
137 private static final String STR_SSH = "ssh";
138 private static final String STR_SCP = "scp";
139 private static final String STR_IOTSLAVE_CPP = "./IoTSlave.o";
140 private static final String STR_SHELL_HEADER = "#!/bin/sh";
141 private static final String STR_JAVA_PATH = "/usr/bin/java";
142 private static final String STR_MAC_POL_PATH = "tomoyo/";
143 private static final String STR_TMP = "tmp";
144 private static final String STR_ARP = "arp";
146 private static int INT_SIZE = 4; // send length in the size of integer (4 bytes)
147 private static final int INT_DNS_PORT = 53;
150 * Runtime class name constants - not to be configured by users
152 private static final String STR_REL_INSTRUMENTER_CLS = "iotruntime.master.RelationInstrumenter";
153 private static final String STR_SET_INSTRUMENTER_CLS = "iotruntime.master.SetInstrumenter";
154 private static final String STR_IOT_SLAVE_CLS = "iotruntime.slave.IoTSlave";
155 private static final String STR_IOT_DEV_ADD_CLS = "IoTDeviceAddress";
156 private static final String STR_IOT_ZB_ADD_CLS = "IoTZigbeeAddress";
157 private static final String STR_IOT_ADD_CLS = "IoTAddress";
163 public IoTMaster(String[] argObjNms) {
168 processJailConfig = null;
170 objAddInitHand = null;
171 strObjectNames = argObjNms;
173 strObjClassName = null;
174 strObjClassInterfaceName = null;
175 strObjStubClsIntfaceName = null;
176 strIoTMasterHostAdd = null;
177 strIoTSlaveControllerHostAdd = null;
178 strIoTSlaveObjectHostAdd = null;
179 arrFieldClasses = null;
180 arrFieldValues = null;
182 mapClassNameToCrim = null;
183 // Connection with C++ IoTSlave
184 serverSocketCpp = null;
189 STR_MASTER_MAC_ADD = null;
190 STR_IOT_CODE_PATH = null;
191 STR_CONT_PATH = null;
192 STR_RUNTIME_DIR = null;
193 STR_SLAVE_DIR = null;
196 STR_RMI_HOSTNAME = null;
197 STR_LOG_FILE_PATH = null;
199 STR_ROUTER_ADD = null;
200 STR_MONITORING_HOST = null;
201 STR_ZB_GATEWAY_ADDRESS = null;
202 STR_ZB_GATEWAY_PORT = null;
203 STR_ZB_IOTMASTER_PORT = null;
204 STR_JVM_INIT_HEAP_SIZE = null;
205 STR_JVM_MAX_HEAP_SIZE = null;
206 STR_LANGUAGE_CONTROLLER = null;
207 STR_ACTIVATE_SANDBOXING = null;
208 STR_POLICY_ON = null;
209 STR_MAC_TO_IP_TRANSLATION = null;
210 BOOL_VERBOSE = false;
214 * A method to initialize CommunicationHandler, LoadBalancer, RouterConfig and ObjectInitHandler
218 private void initLiveDataStructure() {
220 commHan = new CommunicationHandler(BOOL_VERBOSE);
221 lbIoT = new LoadBalancer(BOOL_VERBOSE);
222 lbIoT.setupLoadBalancer();
223 routerConfig = new RouterConfig();
224 // Get MAC to IP translation either from /tmp/dhcp.leases or arp command
225 if (STR_MAC_TO_IP_TRANSLATION.equals(STR_TMP))
226 routerConfig.getAddressListTmp(STR_ROUTER_ADD);
227 else if (STR_MAC_TO_IP_TRANSLATION.equals(STR_ARP))
228 routerConfig.getAddressListArp(STR_ROUTER_ADD);
230 throw new Error("IoTMaster: Unknown value for STR_MAC_TO_IP_TRANSLATION: " + STR_MAC_TO_IP_TRANSLATION);
231 processJailConfig = new ProcessJailConfig();
232 //processJailConfig.setAddressListObject(routerConfig.getAddressListObject());
233 objInitHand = new ObjectInitHandler(BOOL_VERBOSE);
234 objAddInitHand = new ObjectAddressInitHandler(BOOL_VERBOSE);
235 mapClassNameToCrim = new HashMap<String,Object>();
239 * getPrintWriter() gets a new PrintWriter for a new object
241 * @param strObjectName String object name
242 * @return PrintWriter
244 private PrintWriter getPrintWriter(String strObjectName) {
246 FileWriter fw = null;
248 fw = new FileWriter(strObjectName);
249 } catch (IOException ex) {
250 ex.printStackTrace();
252 PrintWriter printWriter = new PrintWriter(new BufferedWriter(fw));
257 * A method to initialize constants from config file
261 private void parseIoTMasterConfigFile() {
262 // Parse configuration file
263 Properties prop = new Properties();
264 String strCfgFileName = STR_IOT_MASTER_NAME + STR_CFG_FILE_EXT;
265 File file = new File(strCfgFileName);
266 FileInputStream fis = null;
268 fis = new FileInputStream(file);
271 } catch (IOException ex) {
272 System.out.println("IoTMaster: Error reading config file: " + strCfgFileName);
273 ex.printStackTrace();
275 // Initialize constants from config file
276 STR_MASTER_MAC_ADD = prop.getProperty("MAC_ADDRESS");
277 STR_IOT_CODE_PATH = prop.getProperty("IOT_CODE_PATH");
278 STR_CONT_PATH = prop.getProperty("CONTROLLERS_CODE_PATH");
279 STR_RUNTIME_DIR = prop.getProperty("RUNTIME_DIR");
280 STR_SLAVE_DIR = prop.getProperty("SLAVE_DIR");
281 STR_CLS_PATH = prop.getProperty("CLASS_PATH");
282 STR_RMI_PATH = prop.getProperty("RMI_PATH");
283 STR_RMI_HOSTNAME = prop.getProperty("RMI_HOSTNAME");
284 STR_LOG_FILE_PATH = prop.getProperty("LOG_FILE_PATH");
285 STR_USERNAME = prop.getProperty("USERNAME");
286 STR_ROUTER_ADD = prop.getProperty("ROUTER_ADD");
287 STR_MONITORING_HOST = prop.getProperty("MONITORING_HOST");
288 STR_ZB_GATEWAY_ADDRESS = prop.getProperty("ZIGBEE_GATEWAY_ADDRESS");
289 STR_ZB_GATEWAY_PORT = prop.getProperty("ZIGBEE_GATEWAY_PORT");
290 STR_ZB_IOTMASTER_PORT = prop.getProperty("ZIGBEE_IOTMASTER_PORT");
291 STR_JVM_INIT_HEAP_SIZE = prop.getProperty("JVM_INIT_HEAP_SIZE");
292 STR_JVM_MAX_HEAP_SIZE = prop.getProperty("JVM_MAX_HEAP_SIZE");
293 STR_SKEL_CLASS_SUFFIX = prop.getProperty("SKEL_CLASS_SUFFIX");
294 STR_STUB_CLASS_SUFFIX = prop.getProperty("STUB_CLASS_SUFFIX");
295 STR_ACTIVATE_SANDBOXING = prop.getProperty("ACTIVATE_SANDBOXING");
296 STR_POLICY_ON = prop.getProperty("POLICY_ON");
297 STR_MAC_TO_IP_TRANSLATION = prop.getProperty("MAC_TO_IP_TRANSLATION");
298 if(prop.getProperty("VERBOSE").equals(STR_YES)) {
302 RuntimeOutput.print("IoTMaster: Extracting information from config file: " + strCfgFileName, BOOL_VERBOSE);
303 RuntimeOutput.print("STR_MASTER_MAC_ADD=" + STR_MASTER_MAC_ADD, BOOL_VERBOSE);
304 RuntimeOutput.print("STR_IOT_CODE_PATH=" + STR_IOT_CODE_PATH, BOOL_VERBOSE);
305 RuntimeOutput.print("STR_CONT_PATH=" + STR_CONT_PATH, BOOL_VERBOSE);
306 RuntimeOutput.print("STR_RUNTIME_DIR=" + STR_RUNTIME_DIR, BOOL_VERBOSE);
307 RuntimeOutput.print("STR_SLAVE_DIR=" + STR_SLAVE_DIR, BOOL_VERBOSE);
308 RuntimeOutput.print("STR_CLS_PATH=" + STR_CLS_PATH, BOOL_VERBOSE);
309 RuntimeOutput.print("STR_RMI_PATH=" + STR_RMI_PATH, BOOL_VERBOSE);
310 RuntimeOutput.print("STR_RMI_HOSTNAME=" + STR_RMI_HOSTNAME, BOOL_VERBOSE);
311 RuntimeOutput.print("STR_LOG_FILE_PATH=" + STR_LOG_FILE_PATH, BOOL_VERBOSE);
312 RuntimeOutput.print("STR_USERNAME=" + STR_USERNAME, BOOL_VERBOSE);
313 RuntimeOutput.print("STR_ROUTER_ADD=" + STR_ROUTER_ADD, BOOL_VERBOSE);
314 RuntimeOutput.print("STR_MONITORING_HOST=" + STR_MONITORING_HOST, BOOL_VERBOSE);
315 RuntimeOutput.print("STR_ZB_GATEWAY_ADDRESS=" + STR_ZB_GATEWAY_ADDRESS, BOOL_VERBOSE);
316 RuntimeOutput.print("STR_ZB_GATEWAY_PORT=" + STR_ZB_GATEWAY_PORT, BOOL_VERBOSE);
317 RuntimeOutput.print("STR_ZB_IOTMASTER_PORT=" + STR_ZB_IOTMASTER_PORT, BOOL_VERBOSE);
318 RuntimeOutput.print("STR_JVM_INIT_HEAP_SIZE=" + STR_JVM_INIT_HEAP_SIZE, BOOL_VERBOSE);
319 RuntimeOutput.print("STR_JVM_MAX_HEAP_SIZE=" + STR_JVM_MAX_HEAP_SIZE, BOOL_VERBOSE);
320 RuntimeOutput.print("STR_SKEL_CLASS_SUFFIX=" + STR_SKEL_CLASS_SUFFIX, BOOL_VERBOSE);
321 RuntimeOutput.print("STR_STUB_CLASS_SUFFIX=" + STR_STUB_CLASS_SUFFIX, BOOL_VERBOSE);
322 RuntimeOutput.print("STR_ACTIVATE_SANDBOXING=" + STR_ACTIVATE_SANDBOXING, BOOL_VERBOSE);
323 RuntimeOutput.print("STR_POLICY_ON=" + STR_POLICY_ON, BOOL_VERBOSE);
324 RuntimeOutput.print("STR_MAC_TO_IP_TRANSLATION=" + STR_MAC_TO_IP_TRANSLATION, BOOL_VERBOSE);
325 RuntimeOutput.print("BOOL_VERBOSE=" + BOOL_VERBOSE, BOOL_VERBOSE);
326 RuntimeOutput.print("IoTMaster: Information extracted successfully!", BOOL_VERBOSE);
330 * A method to parse information from a config file
332 * @param strCfgFileName Config file name
333 * @param strCfgField Config file field name
336 private String parseConfigFile(String strCfgFileName, String strCfgField) {
337 // Parse configuration file
338 Properties prop = new Properties();
339 File file = new File(strCfgFileName);
340 FileInputStream fis = null;
342 fis = new FileInputStream(file);
345 } catch (IOException ex) {
346 System.out.println("IoTMaster: Error reading config file: " + strCfgFileName);
347 ex.printStackTrace();
349 System.out.println("IoTMaster: Reading " + strCfgField +
350 " from config file: " + strCfgFileName + " with value: " +
351 prop.getProperty(strCfgField, null));
352 // NULL is returned if the property isn't found
353 return prop.getProperty(strCfgField, null);
357 * A method to send files from IoTMaster
359 * @param filesocket File socket object
360 * @param sFileName File name
361 * @param lFLength File length
364 private void sendFile(Socket filesocket, String sFileName, long lFLength) throws IOException {
366 File file = new File(sFileName);
367 byte[] bytFile = new byte[toIntExact(lFLength)];
368 InputStream inFileStream = new FileInputStream(file);
370 OutputStream outFileStream = filesocket.getOutputStream();
372 while ((iCount = inFileStream.read(bytFile)) > 0) {
373 outFileStream.write(bytFile, 0, iCount);
376 RuntimeOutput.print("IoTMaster: File sent!", BOOL_VERBOSE);
380 * A method to create a thread
382 * @param sSSHCmd SSH command
385 private void createThread(String sSSHCmd) throws IOException {
387 // Start a new thread to start a new JVM
389 Runtime runtime = Runtime.getRuntime();
390 Process process = runtime.exec(sSSHCmd);
392 RuntimeOutput.print("Executing: " + sSSHCmd, BOOL_VERBOSE);
396 * A method to send command from master and receive reply from slave
398 * @params msgSend Message object
399 * @params strPurpose String that prints purpose message
400 * @params inStream Input stream
401 * @params outStream Output stream
404 private void commMasterToSlave(Message msgSend, String strPurpose,
405 InputStream _inStream, OutputStream _outStream)
406 throws IOException, ClassNotFoundException {
408 // Send message/command from master
409 ObjectOutputStream outStream = (ObjectOutputStream) _outStream;
410 outStream.writeObject(msgSend);
411 RuntimeOutput.print("IoTMaster: Send message: " + strPurpose, BOOL_VERBOSE);
413 // Get reply from slave as acknowledgment
414 ObjectInputStream inStream = (ObjectInputStream) _inStream;
415 Message msgReply = (Message) inStream.readObject();
416 RuntimeOutput.print("IoTMaster: Reply message: " + msgReply.getMessage(), BOOL_VERBOSE);
420 * A private method to instrument IoTSet device
422 * @params strFieldIdentifier String field name + object ID
423 * @params strFieldName String field name
424 * @params strIoTSlaveObjectHostAdd String slave host address
425 * @params inStream ObjectInputStream communication
426 * @params inStream ObjectOutputStream communication
427 * @params strLanguage String language
430 private void instrumentIoTSetDevice(String strFieldIdentifier, String strObjName, String strFieldName, String strIoTSlaveObjectHostAdd,
431 InputStream inStream, OutputStream outStream, String strLanguage)
432 throws IOException, ClassNotFoundException, InterruptedException {
434 // Get information from the set
435 List<Object[]> listObject = objAddInitHand.getFields(strFieldIdentifier);
436 RuntimeOutput.print("IoTMaster: DEBUG: Getting into instrumentIoTSetDevice!", BOOL_VERBOSE);
437 // Create a new IoTSet
438 if(strLanguage.equals(STR_JAVA)) {
439 Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, strFieldName);
440 commMasterToSlave(msgCrtIoTSet, "Create new IoTSet for IoTDeviceAddress!", inStream, outStream);
442 createNewIoTSetCpp(strFieldName, outStream, inStream);
443 int iRows = listObject.size();
444 RuntimeOutput.print("IoTMaster: Number of rows for IoTDeviceAddress: " + iRows, BOOL_VERBOSE);
445 // Transfer the address
446 for(int iRow=0; iRow<iRows; iRow++) {
447 arrFieldValues = listObject.get(iRow);
448 // Get device address - if 00:00:00:00:00:00 that means it needs the driver object address (self)
449 String strDeviceAddress = null;
450 String strDeviceAddressKey = null;
451 if (arrFieldValues[0].equals(STR_SELF_MAC_ADD)) {
452 strDeviceAddress = strIoTSlaveObjectHostAdd;
453 strDeviceAddressKey = strObjName + "-" + strIoTSlaveObjectHostAdd;
455 strDeviceAddress = routerConfig.getIPFromMACAddress((String) arrFieldValues[0]);
456 strDeviceAddressKey = strObjName + "-" + strDeviceAddress;
458 int iDestDeviceDriverPort = (int) arrFieldValues[1];
459 String strProtocol = (String) arrFieldValues[2];
460 // Check for wildcard feature
461 boolean bSrcPortWildCard = false;
462 boolean bDstPortWildCard = false;
463 if (arrFieldValues.length > 3) {
464 bSrcPortWildCard = (boolean) arrFieldValues[3];
465 bDstPortWildCard = (boolean) arrFieldValues[4];
467 // Add the port connection into communication handler - if it's not assigned yet
468 if (commHan.getComPort(strDeviceAddressKey) == null) {
469 commHan.addPortConnection(strIoTSlaveObjectHostAdd, strDeviceAddressKey);
473 System.out.println("\n\n DEBUG: InstrumentSetDevice: Object Name: " + strObjName);
474 System.out.println("DEBUG: InstrumentSetDevice: Port number: " + commHan.getComPort(strDeviceAddressKey));
475 System.out.println("DEBUG: InstrumentSetDevice: Device address: " + strDeviceAddressKey + "\n\n");
477 // Send address one by one
478 if(strLanguage.equals(STR_JAVA)) {
479 Message msgGetIoTSetObj = null;
480 if (bDstPortWildCard) {
481 String strUniqueDev = strDeviceAddressKey + ":" + iRow;
482 msgGetIoTSetObj = new MessageGetDeviceObject(IoTCommCode.GET_DEVICE_IOTSET_OBJECT,
483 strDeviceAddress, commHan.getAdditionalPort(strUniqueDev), iDestDeviceDriverPort, bSrcPortWildCard, bDstPortWildCard);
485 msgGetIoTSetObj = new MessageGetDeviceObject(IoTCommCode.GET_DEVICE_IOTSET_OBJECT,
486 strDeviceAddress, commHan.getComPort(strDeviceAddressKey), iDestDeviceDriverPort, bSrcPortWildCard, bDstPortWildCard);
487 commMasterToSlave(msgGetIoTSetObj, "Get IoTSet objects!", inStream, outStream);
489 getDeviceIoTSetObjectCpp(outStream, inStream, strDeviceAddress, commHan.getComPort(strDeviceAddressKey), iDestDeviceDriverPort,
490 bSrcPortWildCard, bDstPortWildCard);
492 // Reinitialize IoTSet on device object
493 if(strLanguage.equals(STR_JAVA))
494 commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTSET_FIELD), "Reinitialize IoTSet fields!", inStream, outStream);
496 reinitializeIoTSetFieldCpp(outStream, inStream);
501 * A private method to instrument IoTSet Zigbee device
503 * @params Map.Entry<String,Object> Entry of map IoTSet instrumentation
504 * @params strFieldName String field name
505 * @params strIoTSlaveObjectHostAdd String slave host address
506 * @params inStream ObjectInputStream communication
507 * @params inStream ObjectOutputStream communication
508 * @params strLanguage String language
511 private void instrumentIoTSetZBDevice(Map.Entry<String,Object> map, String strObjName, String strFieldName, String strIoTSlaveObjectHostAdd,
512 InputStream inStream, OutputStream outStream, String strLanguage)
513 throws IOException, ClassNotFoundException, InterruptedException {
515 // Get information from the set
516 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
517 // Create a new IoTSet
518 if(strLanguage.equals(STR_JAVA)) {
519 Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, strFieldName);
520 commMasterToSlave(msgCrtIoTSet, "Create new IoTSet for IoTZigbeeAddress!", inStream, outStream);
521 } else // TODO: will need to implement IoTSet Zigbee for C++ later
523 // Prepare ZigbeeConfig
524 String strZigbeeGWAddress = routerConfig.getIPFromMACAddress(STR_ZB_GATEWAY_ADDRESS);
525 String strZigbeeGWAddressKey = strObjName + "-" + strZigbeeGWAddress;
526 int iZigbeeGWPort = Integer.parseInt(STR_ZB_GATEWAY_PORT);
527 int iZigbeeIoTMasterPort = Integer.parseInt(STR_ZB_IOTMASTER_PORT);
528 commHan.addDevicePort(iZigbeeIoTMasterPort);
529 ZigbeeConfig zbConfig = new ZigbeeConfig(strZigbeeGWAddress, iZigbeeGWPort, iZigbeeIoTMasterPort,
531 // Add the port connection into communication handler - if it's not assigned yet
532 if (commHan.getComPort(strZigbeeGWAddressKey) == null) {
533 commHan.addPortConnection(strIoTSlaveObjectHostAdd, strZigbeeGWAddressKey);
535 int iRows = setInstrumenter.numberOfRows();
536 RuntimeOutput.print("IoTMaster: Number of rows for IoTZigbeeAddress: " + iRows, BOOL_VERBOSE);
539 System.out.println("\n\nDEBUG: InstrumentZigbeeDevice: Object Name: " + strObjName);
540 System.out.println("DEBUG: InstrumentZigbeeDevice: Port number: " + commHan.getComPort(strZigbeeGWAddressKey));
541 System.out.println("DEBUG: InstrumentZigbeeDevice: Device address: " + strZigbeeGWAddress + "\n\n");
543 // Transfer the address
544 for(int iRow=0; iRow<iRows; iRow++) {
545 arrFieldValues = setInstrumenter.fieldValues(iRow);
546 // Get device address
547 String strZBDevAddress = (String) arrFieldValues[0];
548 // Send policy to Zigbee gateway - TODO: Need to clear policy first?
549 zbConfig.setPolicy(strIoTSlaveObjectHostAdd, commHan.getComPort(strZigbeeGWAddressKey), strZBDevAddress);
550 // Send address one by one
551 if(strLanguage.equals(STR_JAVA)) {
552 Message msgGetIoTSetZBObj = new MessageGetSimpleDeviceObject(IoTCommCode.GET_ZB_DEV_IOTSET_OBJECT, strZBDevAddress);
553 commMasterToSlave(msgGetIoTSetZBObj, "Get IoTSet objects!", inStream, outStream);
554 } else // TODO: Implement IoTSet Zigbee for C++
557 zbConfig.closeConnection();
558 // Reinitialize IoTSet on device object
559 commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTSET_FIELD), "Reinitialize IoTSet fields!", inStream, outStream);
564 * A private method to instrument IoTSet of addresses
566 * @params strFieldIdentifier String field name + object ID
567 * @params strFieldName String field name
568 * @params inStream ObjectInputStream communication
569 * @params inStream ObjectOutputStream communication
570 * @params strLanguage String language
573 private void instrumentIoTSetAddress(String strFieldIdentifier, String strFieldName,
574 InputStream inStream, OutputStream outStream, String strLanguage)
575 throws IOException, ClassNotFoundException, InterruptedException {
577 // Get information from the set
578 List<Object[]> listObject = objAddInitHand.getFields(strFieldIdentifier);
579 // Create a new IoTSet
580 if(strLanguage.equals(STR_JAVA)) {
581 Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, strFieldName);
582 commMasterToSlave(msgCrtIoTSet, "Create new IoTSet for IoTAddress!", inStream, outStream);
585 int iRows = listObject.size();
586 RuntimeOutput.print("IoTMaster: Number of rows for IoTAddress: " + iRows, BOOL_VERBOSE);
587 // Transfer the address
588 for(int iRow=0; iRow<iRows; iRow++) {
589 arrFieldValues = listObject.get(iRow);
590 // Get device address
591 String strAddress = (String) arrFieldValues[0];
592 // Send address one by one
593 if(strLanguage.equals(STR_JAVA)) {
594 Message msgGetIoTSetAddObj = new MessageGetSimpleDeviceObject(IoTCommCode.GET_ADD_IOTSET_OBJECT, strAddress);
595 commMasterToSlave(msgGetIoTSetAddObj, "Get IoTSet objects!", inStream, outStream);
596 } else // TODO: Implement IoTSet Address for C++
599 // Reinitialize IoTSet on device object
600 commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTSET_FIELD),
601 "Reinitialize IoTSet fields!", inStream, outStream);
606 * A private method to instrument an object on a specific machine and setting up policies
608 * @params strFieldObjectID String field object ID
609 * @params strObjControllerName String object controller name
610 * @params strLanguage String language
613 private void instrumentObject(String strFieldObjectID, String strObjControllerName, String strLanguage) throws IOException {
615 // Extract the interface name for RMI
616 // e.g. ProximitySensorInterface, TempSensorInterface, etc.
618 String strObjCfgFile = STR_IOT_CODE_PATH + strObjClassName + "/" + strObjClassName + STR_CFG_FILE_EXT;
619 strObjClassInterfaceName = parseConfigFile(strObjCfgFile, STR_INTERFACE_CLS_CFG);
620 strObjStubClsIntfaceName = parseConfigFile(strObjCfgFile, STR_INT_STUB_CLS_CFG);
621 // Create an object name, e.g. ProximitySensorImplPS1
622 strObjName = strObjClassName + strFieldObjectID;
623 // Check first if host exists
624 if(commHan.objectExists(strObjName)) {
625 // If this object exists already ...
626 // Re-read IoTSlave object hostname for further reference
627 strIoTSlaveObjectHostAdd = commHan.getHostAddress(strObjName);
628 RuntimeOutput.print("IoTMaster: Object with name: " + strObjName + " has existed!", BOOL_VERBOSE);
630 // If this is a new object ... then create one
631 // Get host address for IoTSlave from LoadBalancer
632 //strIoTSlaveObjectHostAdd = lbIoT.selectHost();
633 strIoTSlaveObjectHostAdd = routerConfig.getIPFromMACAddress(lbIoT.selectHost());
634 if (strIoTSlaveControllerHostAdd == null)
635 throw new Error("IoTMaster: Could not translate MAC to IP address! Please check the router's /tmp/dhcp.leases!");
636 RuntimeOutput.print("IoTMaster: Object name: " + strObjName, BOOL_VERBOSE);
637 // Add port connection and get port numbers
638 // Naming for objects ProximitySensor becomes ProximitySensor0, ProximitySensor1, etc.
639 commHan.addPortConnection(strIoTSlaveObjectHostAdd, strObjName);
640 commHan.addActiveControllerObject(strFieldObjectID, strObjName, strObjClassName, strObjClassInterfaceName,
641 strObjStubClsIntfaceName, strIoTSlaveObjectHostAdd, arrFieldValues, arrFieldClasses);
642 // ROUTING POLICY: IoTMaster and device/controller object
643 // Master-slave communication
644 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTMasterHostAdd,
645 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjName));
646 // ROUTING POLICY: Send the same routing policy to both the hosts
647 routerConfig.configureHostMainPolicies(strIoTMasterHostAdd, strIoTMasterHostAdd,
648 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjName));
649 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTMasterHostAdd,
650 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjName));
651 // Need to accommodate callback functions here - open ports for TCP
652 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveControllerHostAdd,
653 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
654 routerConfig.configureHostMainPolicies(strIoTSlaveControllerHostAdd, strIoTSlaveControllerHostAdd,
655 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
656 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveControllerHostAdd,
657 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
658 // Configure MAC policies for objects
659 //String strFileName = STR_MAC_POL_PATH + strObjClassName + STR_MAC_POLICY_EXT;
660 String strFileName = STR_MAC_POL_PATH + STR_JAVA + STR_MAC_POLICY_EXT;
661 if (STR_ACTIVATE_SANDBOXING.equals("Yes")) {
662 processJailConfig.configureProcessJailDeviceDriverPolicies(strIoTSlaveObjectHostAdd, strObjName, strObjClassName,
663 strFileName, strIoTMasterHostAdd, commHan.getComPort(strObjName), commHan.getRMIRegPort(strObjName),
664 commHan.getRMIStubPort(strObjName));
665 // Check for additional MAC policy
666 String strMACConfigPath = STR_IOT_CODE_PATH + strObjClassName + "/";
667 String strCfgFile = strMACConfigPath + strObjClassName + STR_CFG_FILE_EXT;
668 String strAddMACPolicy = parseConfigFile(strCfgFile, STR_ADD_MAC_POL);
669 if (strAddMACPolicy != null && strAddMACPolicy.equals("Yes"))
670 processJailConfig.combineAdditionalMACPolicy(strMACConfigPath, strObjClassName, strIoTSlaveObjectHostAdd);
671 processJailConfig.configureProcessJailContRMIPolicies(strObjControllerName, strIoTSlaveObjectHostAdd,
672 commHan.getRMIRegPort(strObjName), commHan.getRMIStubPort(strObjName));
674 // Instrument the IoTSet declarations inside the class file
675 instrumentObjectIoTSet(strFieldObjectID, strLanguage);
677 // Send routing policy to router for controller object
678 // ROUTING POLICY: RMI communication - RMI registry and stub ports
679 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
680 STR_TCP_PROTOCOL, commHan.getRMIRegPort(strObjName));
681 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
682 STR_TCP_PROTOCOL, commHan.getRMIStubPort(strObjName));
683 // Send the same set of routing policies to compute nodes
684 routerConfig.configureHostMainPolicies(strIoTSlaveControllerHostAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
685 STR_TCP_PROTOCOL, commHan.getRMIRegPort(strObjName));
686 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
687 STR_TCP_PROTOCOL, commHan.getRMIRegPort(strObjName));
688 routerConfig.configureHostMainPolicies(strIoTSlaveControllerHostAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
689 STR_TCP_PROTOCOL, commHan.getRMIStubPort(strObjName));
690 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
691 STR_TCP_PROTOCOL, commHan.getRMIStubPort(strObjName));
696 * A private method to set router policies for IoTDeviceAddress objects
698 * @params strFieldIdentifier String field name + object ID
699 * @params Map.Entry<String,Object> Entry of map IoTSet instrumentation
700 * @params strIoTSlaveObjectHostAdd String slave host address
703 private void setRouterPolicyIoTSetDevice(String strFieldIdentifier, Map.Entry<String,Object> map,
704 String strIoTSlaveObjectHostAdd) {
706 // Get information from the set
707 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
708 int iRows = setInstrumenter.numberOfRows();
709 RuntimeOutput.print("IoTMaster: Number of rows for IoTDeviceAddress: " + iRows, BOOL_VERBOSE);
710 // Transfer the address
711 for(int iRow=0; iRow<iRows; iRow++) {
712 arrFieldValues = setInstrumenter.fieldValues(iRow);
713 objAddInitHand.addField(strFieldIdentifier, arrFieldValues); // Save this for object instantiation
714 // Get device address - if 00:00:00:00:00:00 that means it needs the driver object address (self)
715 String strDeviceAddress = null;
716 String strDeviceAddressKey = null;
717 if (arrFieldValues[0].equals(STR_SELF_MAC_ADD)) {
718 strDeviceAddress = strIoTSlaveObjectHostAdd;
719 strDeviceAddressKey = strObjName + "-" + strIoTSlaveObjectHostAdd;
720 } else { // Concatenate object name and IP address to give unique key - for a case where there is one device for multiple drivers
721 strDeviceAddress = routerConfig.getIPFromMACAddress((String) arrFieldValues[0]);
722 strDeviceAddressKey = strObjName + "-" + strDeviceAddress;
724 int iDestDeviceDriverPort = (int) arrFieldValues[1];
725 String strProtocol = (String) arrFieldValues[2];
726 // Add the port connection into communication handler - if it's not assigned yet
727 if (commHan.getComPort(strDeviceAddressKey) == null)
728 commHan.addPortConnection(strIoTSlaveObjectHostAdd, strDeviceAddressKey);
729 boolean bDstPortWildCard = false;
730 // Recognize this and allocate different ports for it
731 if (arrFieldValues.length > 3) {
732 bDstPortWildCard = (boolean) arrFieldValues[4];
733 if (bDstPortWildCard) { // This needs a unique source port
734 String strUniqueDev = strDeviceAddressKey + ":" + iRow;
735 commHan.addAdditionalPort(strUniqueDev);
740 System.out.println("\n\n DEBUG: InstrumentPolicySetDevice: Object Name: " + strObjName);
741 System.out.println("DEBUG: InstrumentPolicySetDevice: Port number: " + commHan.getComPort(strDeviceAddressKey));
742 System.out.println("DEBUG: InstrumentPolicySetDevice: Device address: " + strDeviceAddressKey + "\n\n");
744 // Send routing policy to router for device drivers and devices
745 // ROUTING POLICY: RMI communication - RMI registry and stub ports
746 if((iDestDeviceDriverPort == -1) && (!strProtocol.equals(STR_NO_PROTOCOL))) {
747 // Port number -1 means that we don't set the policy strictly to port number level
748 // "nopro" = no protocol specified for just TCP or just UDP (can be both used as well)
749 // ROUTING POLICY: Device driver and device
750 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveObjectHostAdd, strDeviceAddress, strProtocol);
751 // ROUTING POLICY: Send to the compute node where the device driver is
752 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress, strProtocol);
753 } else if((iDestDeviceDriverPort == -1) && (strProtocol.equals(STR_NO_PROTOCOL))) {
754 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveObjectHostAdd, strDeviceAddress);
755 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress);
756 } else if(strProtocol.equals(STR_TCPGW_PROTOCOL)) {
757 // This is a TCP protocol that connects, e.g. a phone to our runtime system
758 // that provides a gateway access (accessed through destination port number)
759 commHan.addDevicePort(iDestDeviceDriverPort);
760 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveObjectHostAdd, strDeviceAddress, STR_TCP_PROTOCOL, iDestDeviceDriverPort);
761 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress, STR_TCP_PROTOCOL, iDestDeviceDriverPort);
762 routerConfig.configureRouterHTTPPolicies(STR_ROUTER_ADD, strIoTSlaveObjectHostAdd, strDeviceAddress);
763 routerConfig.configureHostHTTPPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress);
764 // Configure MAC policies
765 if (STR_ACTIVATE_SANDBOXING.equals("Yes"))
766 processJailConfig.configureProcessJailGWDevicePolicies(strIoTSlaveObjectHostAdd, STR_ROUTER_ADD, strDeviceAddress, INT_DNS_PORT);
768 // Other port numbers...
769 commHan.addDevicePort(iDestDeviceDriverPort);
770 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveObjectHostAdd, strDeviceAddress, strProtocol,
771 commHan.getComPort(strDeviceAddressKey), iDestDeviceDriverPort);
772 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress, strProtocol,
773 commHan.getComPort(strDeviceAddressKey), iDestDeviceDriverPort);
774 // Configure MAC policies
775 if (STR_ACTIVATE_SANDBOXING.equals("Yes"))
776 processJailConfig.configureProcessJailDevicePolicies(strIoTSlaveObjectHostAdd, strProtocol,
777 commHan.getComPort(strDeviceAddressKey), strDeviceAddress, iDestDeviceDriverPort);
783 * A private method to set router policies for IoTAddress objects
785 * @params strFieldIdentifier String field name + object ID
786 * @params Map.Entry<String,Object> Entry of map IoTSet instrumentation
787 * @params strHostAddress String host address
790 private void setRouterPolicyIoTSetAddress(String strFieldIdentifier, Map.Entry<String,Object> map,
791 String strHostAddress, String strControllerName) {
793 // Get information from the set
794 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
795 int iRows = setInstrumenter.numberOfRows();
796 RuntimeOutput.print("IoTMaster: Number of rows for IoTAddress: " + iRows, BOOL_VERBOSE);
797 // Transfer the address
798 for(int iRow=0; iRow<iRows; iRow++) {
799 arrFieldValues = setInstrumenter.fieldValues(iRow);
800 objAddInitHand.addField(strFieldIdentifier, arrFieldValues); // Save this for object instantiation
801 // Get device address
802 String strAddress = (String) arrFieldValues[0];
803 // Setting up router policies for HTTP/HTTPs
804 if (STR_ACTIVATE_SANDBOXING.equals("Yes")) {
805 if (strControllerName != null) {
806 processJailConfig.configureProcessJailInetAddressPolicies(strControllerName, STR_ROUTER_ADD, strAddress);
808 processJailConfig.configureProcessJailInetAddressPolicies(strHostAddress, STR_ROUTER_ADD, strAddress);
811 routerConfig.configureRouterHTTPPolicies(STR_ROUTER_ADD, strHostAddress, strAddress);
812 routerConfig.configureHostHTTPPolicies(strHostAddress, strHostAddress, strAddress);
817 * A private method to instrument an object's IoTSet and IoTRelation field to up policies
819 * Mostly the IoTSet fields would contain IoTDeviceAddress objects
821 * @params strFieldObjectID String field object ID
822 * @params strLanguage String language
825 private void instrumentObjectIoTSet(String strFieldObjectID, String strLanguage) throws IOException {
827 // If this is a new object ... then create one
828 // Instrument the class source code and look for IoTSet for device addresses
829 // e.g. @config private IoTSet<IoTDeviceAddress> lb_addresses;
830 HashMap<String,Object> hmObjectFieldObjects = null;
831 if(strLanguage.equals(STR_JAVA)) {
832 String strObjectClassNamePath = STR_IOT_CODE_PATH + strObjClassName + "/" + strObjClassName + STR_CLS_FILE_EXT;
833 FileInputStream fis = new FileInputStream(strObjectClassNamePath);
834 ClassReader cr = new ClassReader(fis);
835 ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
836 // We need Object ID to instrument IoTDeviceAddress
837 ClassRuntimeInstrumenterMaster crim = new ClassRuntimeInstrumenterMaster(cw, strFieldObjectID, BOOL_VERBOSE);
840 mapClassNameToCrim.put(strObjClassName + strFieldObjectID, crim);
841 hmObjectFieldObjects = crim.getFieldObjects();
843 String strObjectClassNamePath = STR_IOT_CODE_PATH + strObjClassName + "/" + strObjClassName + STR_CFG_FILE_EXT;
844 CRuntimeInstrumenterMaster crim = new CRuntimeInstrumenterMaster(strObjectClassNamePath, strFieldObjectID, BOOL_VERBOSE);
845 mapClassNameToCrim.put(strObjClassName + strFieldObjectID, crim);
846 hmObjectFieldObjects = crim.getFieldObjects();
848 // Get the object and the class names
849 // Build objects for IoTSet and IoTRelation fields in the device object classes
850 RuntimeOutput.print("IoTMaster: Going to instrument for " + strObjClassName + " with objectID " +
851 strFieldObjectID, BOOL_VERBOSE);
852 for(Map.Entry<String,Object> map : hmObjectFieldObjects.entrySet()) {
853 RuntimeOutput.print("IoTMaster: Object name: " + map.getValue().getClass().getName(), BOOL_VERBOSE);
854 // Iterate over HashMap and choose between processing
855 String strFieldName = map.getKey();
856 String strClassName = map.getValue().getClass().getName();
857 String strFieldIdentifier = strFieldName + strFieldObjectID;
858 if(strClassName.equals(STR_SET_INSTRUMENTER_CLS)) {
859 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
860 if(setInstrumenter.getObjTableName().equals(STR_IOT_DEV_ADD_CLS)) {
861 // Instrument the normal IoTDeviceAddress
862 setRouterPolicyIoTSetDevice(strFieldIdentifier, map, strIoTSlaveObjectHostAdd);
863 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ADD_CLS)) {
864 // Instrument the IoTAddress
865 setRouterPolicyIoTSetAddress(strFieldIdentifier, map, strIoTSlaveObjectHostAdd, null);
866 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ZB_ADD_CLS)) {
867 // Instrument the IoTZigbeeAddress - special feature for Zigbee device support
868 RuntimeOutput.print("IoTMaster: IoTZigbeeAddress found! No router policy is set here..",
871 String strErrMsg = "IoTMaster: Device driver object" +
872 " can only have IoTSet<IoTAddress>, IoTSet<IoTDeviceAddress>," +
873 " or IoTSet<IoTZigbeeAddress>!";
874 throw new Error(strErrMsg);
877 String strErrMsg = "IoTMaster: Device driver object can only have IoTSet for addresses!";
878 throw new Error(strErrMsg);
885 * A private method to send files to a Java slave driver
887 * @params serverSocket ServerSocket
888 * @params _inStream InputStream
889 * @params _outStream OutputStream
890 * @params strObjName String
891 * @params strObjClassName String
892 * @params strObjClassInterfaceName String
893 * @params strObjStubClsIntfaceName String
894 * @params strIoTSlaveObjectHostAdd String
895 * @params strFieldObjectID String
896 * @params arrFieldValues Object[]
897 * @params arrFieldClasses Class[]
900 private void sendFileToJavaSlaveDriver(ServerSocket serverSocket, InputStream _inStream, OutputStream _outStream,
901 String strObjName, String strObjClassName, String strObjClassInterfaceName, String strObjStubClsIntfaceName,
902 String strIoTSlaveObjectHostAdd, String strFieldObjectID, Object[] arrFieldValues, Class[] arrFieldClasses)
903 throws IOException, ClassNotFoundException {
905 ObjectInputStream inStream = (ObjectInputStream) _inStream;
906 ObjectOutputStream outStream = (ObjectOutputStream) _outStream;
907 // Create message to transfer file first
908 String sFileName = strObjClassName + STR_JAR_FILE_EXT;
909 String sPath = STR_IOT_CODE_PATH + strObjClassName + "/" + sFileName;
910 File file = new File(sPath);
911 commMasterToSlave(new MessageSendFile(IoTCommCode.TRANSFER_FILE, sFileName, file.length()),
912 "Sending file!", inStream, outStream);
913 // Send file - JAR file for object creation
914 sendFile(serverSocket.accept(), sPath, file.length());
915 Message msgReply = (Message) inStream.readObject();
916 RuntimeOutput.print("IoTMaster: Reply message: " + msgReply.getMessage(), BOOL_VERBOSE);
917 // Pack object information to create object on a IoTSlave
918 Message msgObjIoTSlave = new MessageCreateObject(IoTCommCode.CREATE_OBJECT, strIoTSlaveObjectHostAdd,
919 strObjClassName, strObjName, strObjClassInterfaceName, strObjStubClsIntfaceName, commHan.getRMIRegPort(strObjName),
920 commHan.getRMIStubPort(strObjName), arrFieldValues, arrFieldClasses);
922 commMasterToSlave(msgObjIoTSlave, "Sending object information", inStream, outStream);
927 * A private method to send files to a Java slave driver
931 private void sendFileToCppSlaveDriver(String strObjClassName, String strIoTSlaveObjectHostAdd)
932 throws IOException, ClassNotFoundException {
934 // Create message to transfer file first
935 String sFileName = strObjClassName + STR_ZIP_FILE_EXT;
936 String sFile = STR_IOT_CODE_PATH + strObjClassName + "/" + sFileName;
937 String strCmdSend = STR_SCP + " " + sFile + " " + STR_USERNAME + strIoTSlaveObjectHostAdd + ":" + STR_SLAVE_DIR;
938 runCommand(strCmdSend);
939 RuntimeOutput.print("IoTMaster: Executing: " + strCmdSend, BOOL_VERBOSE);
941 String strCmdUnzip = STR_SSH + " " + STR_USERNAME + strIoTSlaveObjectHostAdd + " cd " +
942 STR_SLAVE_DIR + " sudo unzip -o " + sFileName + ";";
943 runCommand(strCmdUnzip);
944 RuntimeOutput.print("IoTMaster: Executing: " + strCmdUnzip, BOOL_VERBOSE);
950 * Construct command line for Java IoTSlave
954 private String getCmdJavaDriverIoTSlave(String strIoTMasterHostAdd, String strIoTSlaveObjectHostAdd, String strObjName) {
956 // Create an Shell executable
957 String strJavaCommand = STR_SHELL_HEADER + "\nexec sudo " + STR_JAVA_PATH + " " + STR_CLS_PATH + " " + STR_RMI_PATH + " " +
958 STR_RMI_HOSTNAME + strIoTSlaveObjectHostAdd + " " + STR_IOT_SLAVE_CLS + " " + strIoTMasterHostAdd + " " +
959 commHan.getComPort(strObjName) + " " + commHan.getRMIRegPort(strObjName) + " " +
960 commHan.getRMIStubPort(strObjName) + " > " + STR_LOG_FILE_PATH + strObjName + ".log &";
961 String shellFile = "./" + strObjName + STR_SHELL_FILE_EXT;
962 createWrapperShellScript(strJavaCommand, shellFile);
963 // Send the file to the compute node
964 String strCmdSend = "scp " + shellFile + " " + STR_USERNAME + strIoTSlaveObjectHostAdd + ":" + STR_RUNTIME_DIR;
965 runCommand(strCmdSend);
966 System.out.println("IoTMaster: Sending shell file: " + strCmdSend);
967 return STR_SSH + " " + STR_USERNAME + strIoTSlaveObjectHostAdd + " cd " + STR_RUNTIME_DIR + " " + shellFile;
972 * Construct command line for C++ IoTSlave
976 private String getCmdCppDriverIoTSlave(String strIoTMasterHostAdd, String strIoTSlaveObjectHostAdd, String strObjName) {
978 return STR_SSH + " " + STR_USERNAME + strIoTSlaveObjectHostAdd + " cd " +
979 STR_SLAVE_DIR + " sudo " + STR_IOTSLAVE_CPP + " " + strIoTMasterHostAdd + " " +
980 commHan.getComPort(strObjName) + " " + strObjName;
985 * createWrapperShellScript() gets a wrapper shell script
987 * @param strCommand String command
988 * @param strObjectName String object name
989 * @return PrintWriter
991 private void createWrapperShellScript(String strCommand, String strFileName) {
993 PrintWriter printWriter = getPrintWriter(strFileName);
994 printWriter.println(strCommand);
996 runCommand("chmod 755 " + strFileName);
1001 * A private method to create an object on a specific machine
1003 * @params strObjName String object name
1004 * @params strObjClassName String object class name
1005 * @params strObjClassInterfaceName String object class interface name
1006 * @params strIoTSlaveObjectHostAdd String IoTSlave host address
1007 * @params strFieldObjectID String field object ID
1008 * @params arrFieldValues Array of field values
1009 * @params arrFieldClasses Array of field classes
1012 private void createObject(String strObjName, String strObjClassName, String strObjClassInterfaceName, String strObjStubClsIntfaceName,
1013 String strIoTSlaveObjectHostAdd, String strFieldObjectID, Object[] arrFieldValues, Class[] arrFieldClasses)
1014 throws IOException, FileNotFoundException, ClassNotFoundException, InterruptedException {
1017 String sCfgFile = STR_IOT_CODE_PATH + strObjClassName + "/" + strObjClassName + STR_CFG_FILE_EXT;
1018 String strLanguageDriver = parseConfigFile(sCfgFile, STR_LANGUAGE + "_" + strObjName);
1019 if(strLanguageDriver == null) // Read just the field LANGUAGE if the first read is null
1020 strLanguageDriver = parseConfigFile(sCfgFile, STR_LANGUAGE);
1021 if(strLanguageDriver == null) // Check nullness for the second time - report if it is still null
1022 throw new Error("IoTMaster: Language specification missing in config file: " + sCfgFile);
1027 start = System.currentTimeMillis();
1029 // Construct ssh command line
1030 // e.g. ssh rtrimana@dw-2.eecs.uci.edu cd <path>;
1031 // java -cp $CLASSPATH:./*.jar
1032 // -Djava.rmi.server.codebase=file:./*.jar
1033 // iotruntime.IoTSlave dw-1.eecs.uci.edu 46151 23829 42874 &
1034 // The In-Port for IoTMaster is the Out-Port for IoTSlave and vice versa
1035 String strSSHCommand = null;
1036 if(strLanguageDriver.equals(STR_JAVA))
1037 strSSHCommand = getCmdJavaDriverIoTSlave(strIoTMasterHostAdd, strIoTSlaveObjectHostAdd, strObjName);
1038 else if(strLanguageDriver.equals(STR_CPP))
1039 strSSHCommand = getCmdCppDriverIoTSlave(strIoTMasterHostAdd, strIoTSlaveObjectHostAdd, strObjName);
1041 throw new Error("IoTMaster: Language specification not recognized: " + strLanguageDriver);
1042 RuntimeOutput.print("IoTMaster: Language for " + strObjName + " is " + strLanguageDriver, BOOL_VERBOSE);
1044 RuntimeOutput.print(strSSHCommand, BOOL_VERBOSE);
1045 // Start a new thread to start a new JVM
1046 createThread(strSSHCommand);
1047 ServerSocket serverSocket = new ServerSocket(commHan.getComPort(strObjName));
1048 Socket socket = serverSocket.accept();
1049 //InputStream inStream = new ObjectInputStream(socket.getInputStream());
1050 //OutputStream outStream = new ObjectOutputStream(socket.getOutputStream());
1051 InputStream inStream = null;
1052 OutputStream outStream = null;
1053 if(strLanguageDriver.equals(STR_JAVA)) {
1054 inStream = new ObjectInputStream(socket.getInputStream());
1055 outStream = new ObjectOutputStream(socket.getOutputStream());
1056 } else { // At this point the language is certainly C++, otherwise would've complained above
1057 inStream = new BufferedInputStream(socket.getInputStream());
1058 outStream = new BufferedOutputStream(socket.getOutputStream());
1063 result = System.currentTimeMillis()-start;
1064 System.out.println("\n\n ==> Time needed to start JVM for " + strObjName + ": " + result + "\n\n");
1067 start = System.currentTimeMillis();
1069 if(strLanguageDriver.equals(STR_JAVA)) {
1070 sendFileToJavaSlaveDriver(serverSocket, inStream, outStream, strObjName,
1071 strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName,
1072 strIoTSlaveObjectHostAdd, strFieldObjectID, arrFieldValues, arrFieldClasses);
1074 sendFileToCppSlaveDriver(strObjClassName, strIoTSlaveObjectHostAdd);
1075 createObjectCpp(strObjName, strObjClassName, strObjClassInterfaceName, strIoTSlaveObjectHostAdd,
1076 commHan.getRMIRegPort(strObjName), commHan.getRMIStubPort(strObjName), arrFieldValues, arrFieldClasses,
1077 outStream, inStream);
1081 result = System.currentTimeMillis()-start;
1082 System.out.println("\n\n ==> Time needed to send JAR file for " + strObjName + ": " + result + "\n\n");
1085 start = System.currentTimeMillis();
1087 // Instrument the class source code and look for IoTSet for device addresses
1088 // e.g. @config private IoTSet<IoTDeviceAddress> lb_addresses;
1089 RuntimeOutput.print("IoTMaster: Instantiating for " + strObjClassName + " with objectID " + strFieldObjectID, BOOL_VERBOSE);
1090 // Get the object and the class names
1091 // Build objects for IoTSet and IoTRelation fields in the device object classes
1092 Object crimObj = mapClassNameToCrim.get(strObjClassName + strFieldObjectID);
1093 HashMap<String,Object> hmObjectFieldObjects = null;
1094 if (crimObj instanceof ClassRuntimeInstrumenterMaster) {
1095 ClassRuntimeInstrumenterMaster crim = (ClassRuntimeInstrumenterMaster) crimObj;
1096 hmObjectFieldObjects = crim.getFieldObjects();
1097 } else if (crimObj instanceof CRuntimeInstrumenterMaster) {
1098 CRuntimeInstrumenterMaster crim = (CRuntimeInstrumenterMaster) crimObj;
1099 hmObjectFieldObjects = crim.getFieldObjects();
1101 for(Map.Entry<String,Object> map : hmObjectFieldObjects.entrySet()) {
1102 RuntimeOutput.print("IoTMaster: Object name: " + map.getValue().getClass().getName(), BOOL_VERBOSE);
1103 // Iterate over HashMap and choose between processing
1104 String strFieldName = map.getKey();
1105 String strClassName = map.getValue().getClass().getName();
1106 String strFieldIdentifier = strFieldName + strFieldObjectID;
1107 if(strClassName.equals(STR_SET_INSTRUMENTER_CLS)) {
1108 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
1109 if(setInstrumenter.getObjTableName().equals(STR_IOT_DEV_ADD_CLS)) {
1110 // Instrument the normal IoTDeviceAddress
1111 synchronized(this) {
1112 //RuntimeOutput.print("IoTMaster: DEBUG: Processing " + STR_IOT_DEV_ADD_CLS + "!", BOOL_VERBOSE);
1113 instrumentIoTSetDevice(strFieldIdentifier, strObjName, strFieldName, strIoTSlaveObjectHostAdd, inStream, outStream, strLanguageDriver);
1115 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ZB_ADD_CLS)) {
1116 // Instrument the IoTZigbeeAddress - special feature for Zigbee device support
1117 synchronized(this) {
1118 instrumentIoTSetZBDevice(map, strObjName, strFieldName, strIoTSlaveObjectHostAdd, inStream, outStream, strLanguageDriver);
1120 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ADD_CLS)) {
1121 // Instrument the IoTAddress
1122 synchronized(this) {
1123 instrumentIoTSetAddress(strFieldIdentifier, strFieldName, inStream, outStream, strLanguageDriver);
1126 String strErrMsg = "IoTMaster: Device driver object can only have IoTSet<IoTAddress>, IoTSet<IoTDeviceAddress>," +
1127 " or IoTSet<IoTZigbeeAddress>!";
1128 throw new Error(strErrMsg);
1131 String strErrMsg = "IoTMaster: Device driver object can only have IoTSet for addresses!";
1132 throw new Error(strErrMsg);
1136 // TODO: Change this later
1137 if(strLanguageDriver.equals(STR_JAVA)) {
1138 ObjectOutputStream oStream = (ObjectOutputStream) outStream;
1139 oStream.writeObject(new MessageSimple(IoTCommCode.END_SESSION));
1140 } else { // C++ side for now will be running continuously because it's an infinite loop (not in a separate thread)
1141 createDriverObjectCpp(outStream, inStream);
1142 //endSessionCpp(outStream);
1146 result = System.currentTimeMillis()-start;
1147 System.out.println("\n\n ==> Time needed to create object " + strObjName + " and instrument IoTDeviceAddress: " + result + "\n\n");
1153 serverSocket.close();
1158 * A private method to create controller objects
1162 private void createDriverObjects() throws InterruptedException {
1164 // Create a list of threads
1165 List<Thread> threads = new ArrayList<Thread>();
1166 // Get the list of active controller objects and loop it
1167 List<String> listActiveControllerObject = commHan.getActiveControllerObjectList();
1168 for(String strObjName : listActiveControllerObject) {
1170 ObjectCreationInfo objCrtInfo = commHan.getObjectCreationInfo(strObjName);
1171 Thread objectThread = new Thread(new Runnable() {
1173 synchronized(this) {
1175 createObject(strObjName, objCrtInfo.getObjectClassName(), objCrtInfo.getObjectClassInterfaceName(),
1176 objCrtInfo.getObjectStubClassInterfaceName(), objCrtInfo.getIoTSlaveObjectHostAdd(),
1177 commHan.getFieldObjectID(strObjName), commHan.getArrayFieldValues(strObjName),
1178 commHan.getArrayFieldClasses(strObjName));
1179 } catch (IOException |
1180 ClassNotFoundException |
1181 InterruptedException ex) {
1182 ex.printStackTrace();
1187 threads.add(objectThread);
1188 objectThread.start();
1191 for (Thread thread : threads) {
1194 } catch (InterruptedException ex) {
1195 ex.printStackTrace();
1202 * A private method to instrument IoTSet
1204 * @params Map.Entry<String,Object> Entry of map IoTSet instrumentation
1205 * @params strFieldName String field name
1206 * @params strLanguage String language
1209 private void instrumentIoTSet(Map.Entry<String,Object> map, String strFieldName, String strObjControllerName, String strLanguage)
1210 throws IOException, ClassNotFoundException, InterruptedException {
1212 // Get information from the set
1213 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
1214 objInitHand.addField(strFieldName, IoTCommCode.CREATE_NEW_IOTSET);
1216 int iRows = setInstrumenter.numberOfRows();
1217 for(int iRow=0; iRow<iRows; iRow++) {
1218 // Get field classes and values
1219 arrFieldClasses = setInstrumenter.fieldClasses(iRow);
1220 arrFieldValues = setInstrumenter.fieldValues(iRow);
1221 // Get object ID and class name
1222 String strObjID = setInstrumenter.fieldObjectID(iRow);
1223 strObjClassName = setInstrumenter.fieldEntryType(strObjID);
1224 // Call the method to create an object
1225 instrumentObject(strObjID, strObjControllerName, strLanguage);
1226 objInitHand.addObjectIntoField(strFieldName, strIoTSlaveObjectHostAdd, strObjName,
1227 strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName, commHan.getRMIRegPort(strObjName),
1228 commHan.getRMIStubPort(strObjName));
1234 * A private method to instrument IoTRelation
1236 * @params Map.Entry<String,Object> Entry of map IoTRelation instrumentation
1237 * @params strFieldName String field name
1238 * @params strLanguage String language
1241 private void instrumentIoTRelation(Map.Entry<String,Object> map, String strFieldName, String strObjControllerName, String strLanguage)
1242 throws IOException, ClassNotFoundException, InterruptedException {
1244 // Get information from the set
1245 RelationInstrumenter relationInstrumenter = (RelationInstrumenter) map.getValue();
1246 int iRows = relationInstrumenter.numberOfRows();
1247 objInitHand.addField(strFieldName, IoTCommCode.CREATE_NEW_IOTRELATION);
1249 for(int iRow=0; iRow<iRows; iRow++) {
1250 // Operate on the first set first
1251 arrFieldClasses = relationInstrumenter.firstFieldClasses(iRow);
1252 arrFieldValues = relationInstrumenter.firstFieldValues(iRow);
1253 String strObjID = relationInstrumenter.firstFieldObjectID(iRow);
1254 strObjClassName = relationInstrumenter.firstEntryFieldType(strObjID);
1255 // Call the method to create an object
1256 instrumentObject(strObjID, strObjControllerName, strLanguage);
1257 // Get the first object controller host address
1258 String strFirstIoTSlaveObjectHostAdd = strIoTSlaveObjectHostAdd;
1259 objInitHand.addObjectIntoField(strFieldName, strIoTSlaveObjectHostAdd, strObjName,
1260 strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName,
1261 commHan.getRMIRegPort(strObjName), commHan.getRMIStubPort(strObjName));
1262 // Operate on the second set
1263 arrFieldClasses = relationInstrumenter.secondFieldClasses(iRow);
1264 arrFieldValues = relationInstrumenter.secondFieldValues(iRow);
1265 strObjID = relationInstrumenter.secondFieldObjectID(iRow);
1266 strObjClassName = relationInstrumenter.secondEntryFieldType(strObjID);
1267 // Call the method to create an object
1268 instrumentObject(strObjID, strObjControllerName, strLanguage);
1269 // Get the second object controller host address
1270 String strSecondIoTSlaveObjectHostAdd = strIoTSlaveObjectHostAdd;
1271 objInitHand.addSecondObjectIntoField(strFieldName, strIoTSlaveObjectHostAdd, strObjName,
1272 strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName,
1273 commHan.getRMIRegPort(strObjName), commHan.getRMIStubPort(strObjName));
1274 // ROUTING POLICY: first and second controller objects in IoTRelation
1275 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strFirstIoTSlaveObjectHostAdd,
1276 strSecondIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
1277 // ROUTING POLICY: Send the same routing policy to both the hosts
1278 routerConfig.configureHostMainPolicies(strFirstIoTSlaveObjectHostAdd, strFirstIoTSlaveObjectHostAdd,
1279 strSecondIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
1280 routerConfig.configureHostMainPolicies(strSecondIoTSlaveObjectHostAdd, strFirstIoTSlaveObjectHostAdd,
1281 strSecondIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
1286 * A method to reinitialize IoTSet and IoTRelation in the code based on ObjectInitHandler information
1288 * @params inStream ObjectInputStream communication
1289 * @params outStream ObjectOutputStream communication
1292 private void initializeSetsAndRelationsJava(InputStream inStream, OutputStream outStream)
1293 throws IOException, ClassNotFoundException {
1294 // Get list of fields
1295 List<String> strFields = objInitHand.getListOfFields();
1296 // Iterate on HostAddress
1297 for(String str : strFields) {
1298 IoTCommCode iotcommMsg = objInitHand.getFieldMessage(str);
1299 if (iotcommMsg == IoTCommCode.CREATE_NEW_IOTSET) {
1300 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO CREATE IOTSET
1301 Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, str);
1302 commMasterToSlave(msgCrtIoTSet, "Create new IoTSet!", inStream, outStream);
1303 List<ObjectInitInfo> listObject = objInitHand.getListObjectInitInfo(str);
1304 for (ObjectInitInfo objInitInfo : listObject) {
1305 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTSET
1306 commMasterToSlave(new MessageGetObject(IoTCommCode.GET_IOTSET_OBJECT, objInitInfo.getIoTSlaveObjectHostAdd(),
1307 objInitInfo.getObjectName(), objInitInfo.getObjectClassName(), objInitInfo.getObjectClassInterfaceName(),
1308 objInitInfo.getObjectStubClassInterfaceName(), objInitInfo.getRMIRegistryPort(), objInitInfo.getRMIStubPort()),
1309 "Get IoTSet object!", inStream, outStream);
1312 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO REINITIALIZE IOTSET FIELD
1313 commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTSET_FIELD),
1314 "Renitialize IoTSet field!", inStream, outStream);
1315 } else if (iotcommMsg == IoTCommCode.CREATE_NEW_IOTRELATION) {
1316 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO CREATE IOTRELATION
1317 Message msgCrtIoTRel = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTRELATION, str);
1318 commMasterToSlave(msgCrtIoTRel, "Create new IoTRelation!", inStream, outStream);
1319 List<ObjectInitInfo> listObject = objInitHand.getListObjectInitInfo(str);
1320 List<ObjectInitInfo> listSecondObject = objInitHand.getSecondObjectInitInfo(str);
1321 Iterator it = listSecondObject.iterator();
1322 for (ObjectInitInfo objInitInfo : listObject) {
1323 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTRELATION (FIRST OBJECT)
1324 commMasterToSlave(new MessageGetObject(IoTCommCode.GET_IOTRELATION_FIRST_OBJECT,
1325 objInitInfo.getIoTSlaveObjectHostAdd(), objInitInfo.getObjectName(), objInitInfo.getObjectClassName(),
1326 objInitInfo.getObjectClassInterfaceName(), objInitInfo.getObjectStubClassInterfaceName(),
1327 objInitInfo.getRMIRegistryPort(), objInitInfo.getRMIStubPort()),
1328 "Get IoTRelation first object!", inStream, outStream);
1329 ObjectInitInfo objSecObj = (ObjectInitInfo) it.next();
1330 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTRELATION (SECOND OBJECT)
1331 commMasterToSlave(new MessageGetObject(IoTCommCode.GET_IOTRELATION_SECOND_OBJECT,
1332 objSecObj.getIoTSlaveObjectHostAdd(), objSecObj.getObjectName(), objSecObj.getObjectClassName(),
1333 objSecObj.getObjectClassInterfaceName(), objSecObj.getObjectStubClassInterfaceName(),
1334 objSecObj.getRMIRegistryPort(), objSecObj.getRMIStubPort()),
1335 "Get IoTRelation second object!", inStream, outStream);
1337 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO REINITIALIZE IOTRELATION FIELD
1338 commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTRELATION_FIELD),
1339 "Renitialize IoTRelation field!", inStream, outStream);
1345 * A method to reinitialize IoTSet and IoTRelation in the code based on ObjectInitHandler information
1347 * @params inStream ObjectInputStream communication
1348 * @params outStream ObjectOutputStream communication
1351 private void initializeSetsAndRelationsCpp(InputStream inStream, OutputStream outStream)
1352 throws IOException, ClassNotFoundException {
1353 // Get list of fields
1354 List<String> strFields = objInitHand.getListOfFields();
1355 // Iterate on HostAddress
1356 for(String str : strFields) {
1357 IoTCommCode iotcommMsg = objInitHand.getFieldMessage(str);
1358 if (iotcommMsg == IoTCommCode.CREATE_NEW_IOTSET) {
1359 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO CREATE IOTSET
1360 createNewIoTSetCpp(str, outStream, inStream);
1361 List<ObjectInitInfo> listObject = objInitHand.getListObjectInitInfo(str);
1362 for (ObjectInitInfo objInitInfo : listObject) {
1363 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTSET
1364 getIoTSetRelationObjectCpp(IoTCommCode.GET_IOTSET_OBJECT, objInitInfo.getIoTSlaveObjectHostAdd(), objInitInfo.getObjectName(),
1365 objInitInfo.getObjectClassName(), objInitInfo.getObjectClassInterfaceName(), objInitInfo.getObjectStubClassInterfaceName(),
1366 objInitInfo.getRMIRegistryPort(), objInitInfo.getRMIStubPort(), outStream, inStream);
1368 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO REINITIALIZE IOTSET FIELD
1369 reinitializeIoTSetFieldCpp(outStream, inStream);
1370 } else if (iotcommMsg == IoTCommCode.CREATE_NEW_IOTRELATION) {
1371 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO CREATE IOTRELATION
1372 // TODO: createNewIoTRelation needs to be created here!
1373 createNewIoTRelationCpp(str, outStream, inStream);
1374 List<ObjectInitInfo> listObject = objInitHand.getListObjectInitInfo(str);
1375 List<ObjectInitInfo> listSecondObject = objInitHand.getSecondObjectInitInfo(str);
1376 Iterator it = listSecondObject.iterator();
1377 for (ObjectInitInfo objInitInfo : listObject) {
1378 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTRELATION (FIRST OBJECT)
1379 getIoTSetRelationObjectCpp(IoTCommCode.GET_IOTRELATION_FIRST_OBJECT, objInitInfo.getIoTSlaveObjectHostAdd(), objInitInfo.getObjectName(),
1380 objInitInfo.getObjectClassName(), objInitInfo.getObjectClassInterfaceName(), objInitInfo.getObjectStubClassInterfaceName(),
1381 objInitInfo.getRMIRegistryPort(), objInitInfo.getRMIStubPort(), outStream, inStream);
1382 ObjectInitInfo objSecObj = (ObjectInitInfo) it.next();
1383 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTRELATION (SECOND OBJECT)
1384 getIoTSetRelationObjectCpp(IoTCommCode.GET_IOTRELATION_SECOND_OBJECT, objSecObj.getIoTSlaveObjectHostAdd(), objSecObj.getObjectName(),
1385 objSecObj.getObjectClassName(), objSecObj.getObjectClassInterfaceName(), objSecObj.getObjectStubClassInterfaceName(),
1386 objSecObj.getRMIRegistryPort(), objSecObj.getRMIStubPort(), outStream, inStream);
1388 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO REINITIALIZE IOTRELATION FIELD
1389 reinitializeIoTRelationFieldCpp(outStream, inStream);
1395 * A method to set router basic policies at once
1397 * @param strRouter String router name
1400 private void setRouterBasicPolicies(String strRouter) {
1402 String strMonitorHost = routerConfig.getIPFromMACAddress(STR_MONITORING_HOST);
1403 routerConfig.initMainPolicy(strRouter);
1404 routerConfig.combineRouterPolicies(strRouter);
1405 routerConfig.configureRouterICMPPolicies(strRouter, strMonitorHost);
1406 routerConfig.configureRouterDHCPPolicies(strRouter);
1407 routerConfig.configureRouterDNSPolicies(strRouter);
1408 routerConfig.configureRouterSSHPolicies(strRouter, strMonitorHost);
1409 routerConfig.configureRejectPolicies(strRouter);
1413 * A method to set host basic policies at once
1415 * @param strHost String host name
1418 private void setHostBasicPolicies(String strHost) {
1420 String strMonitorHost = routerConfig.getIPFromMACAddress(STR_MONITORING_HOST);
1421 routerConfig.initMainPolicy(strHost);
1422 routerConfig.combineRouterPolicies(strHost);
1423 routerConfig.configureHostDHCPPolicies(strHost);
1424 routerConfig.configureHostDNSPolicies(strHost);
1425 if (strHost.equals(strMonitorHost)) {
1426 // Check if this is the monitoring host
1427 routerConfig.configureHostICMPPolicies(strHost);
1428 routerConfig.configureHostSSHPolicies(strHost);
1430 routerConfig.configureHostICMPPolicies(strHost, strMonitorHost);
1431 routerConfig.configureHostSSHPolicies(strHost, strMonitorHost);
1433 // Apply SQL allowance policies to master host
1434 if (strHost.equals(strIoTMasterHostAdd)) {
1435 routerConfig.configureHostSQLPolicies(strHost);
1437 routerConfig.configureRejectPolicies(strHost);
1441 * A method to create a thread for policy deployment
1443 * @param strRouterAddress String router address to configure
1444 * @param setHostAddresses Set of strings for host addresses to configure
1447 private void createPolicyThreads(String strRouterAddress, Set<String> setHostAddresses) throws IOException {
1449 // Create a list of threads
1450 List<Thread> threads = new ArrayList<Thread>();
1451 // Start threads for hosts
1452 for(String strAddress : setHostAddresses) {
1453 Thread policyThread = new Thread(new Runnable() {
1455 synchronized(this) {
1456 routerConfig.sendHostPolicies(strAddress);
1460 threads.add(policyThread);
1461 policyThread.start();
1462 RuntimeOutput.print("Deploying policies for: " + strAddress, BOOL_VERBOSE);
1464 // A thread for router
1465 Thread policyThread = new Thread(new Runnable() {
1467 synchronized(this) {
1468 routerConfig.sendRouterPolicies(strRouterAddress);
1472 threads.add(policyThread);
1473 policyThread.start();
1474 RuntimeOutput.print("Deploying policies on router: " + strRouterAddress, BOOL_VERBOSE);
1476 for (Thread thread : threads) {
1479 } catch (InterruptedException ex) {
1480 ex.printStackTrace();
1486 * A method to create a thread for policy deployment
1488 * @param setHostAddresses Set of strings for host addresses to configure
1491 private void createMACPolicyThreads(Set<String> setHostAddresses) throws IOException {
1493 // Create a list of threads
1494 List<Thread> threads = new ArrayList<Thread>();
1495 // Start threads for hosts
1496 for(String strAddress : setHostAddresses) {
1497 Thread policyThread = new Thread(new Runnable() {
1499 synchronized(this) {
1500 processJailConfig.sendMACPolicies(strAddress);
1504 threads.add(policyThread);
1505 policyThread.start();
1506 RuntimeOutput.print("Deploying MAC policies for: " + strAddress, BOOL_VERBOSE);
1509 for (Thread thread : threads) {
1512 } catch (InterruptedException ex) {
1513 ex.printStackTrace();
1520 * A method to send files to Java IoTSlave
1522 * @params strObjControllerName String
1523 * @params serverSocket ServerSocket
1524 * @params inStream ObjectInputStream communication
1525 * @params outStream ObjectOutputStream communication
1528 private void sendFileToJavaSlave(String strObjControllerName, ServerSocket serverSocket,
1529 InputStream _inStream, OutputStream _outStream) throws IOException, ClassNotFoundException {
1531 ObjectInputStream inStream = (ObjectInputStream) _inStream;
1532 ObjectOutputStream outStream = (ObjectOutputStream) _outStream;
1534 String strControllerJarName = strObjControllerName + STR_JAR_FILE_EXT;
1535 String strControllerJarNamePath = STR_CONT_PATH + strObjControllerName + "/" +
1536 strControllerJarName;
1537 File file = new File(strControllerJarNamePath);
1538 commMasterToSlave(new MessageSendFile(IoTCommCode.TRANSFER_FILE, strControllerJarName, file.length()),
1539 "Sending file!", inStream, outStream);
1540 // Send file - Class file for object creation
1541 sendFile(serverSocket.accept(), strControllerJarNamePath, file.length());
1542 Message msgReply = (Message) inStream.readObject();
1543 RuntimeOutput.print("IoTMaster: Reply message: " + msgReply.getMessage(), BOOL_VERBOSE);
1544 // Send .zip file if additional zip file is specified
1545 String strObjCfgFile = strObjControllerName + STR_CFG_FILE_EXT;
1546 String strObjCfgFilePath = STR_CONT_PATH + strObjControllerName + "/" + strObjCfgFile;
1547 String strAdditionalFile = parseConfigFile(strObjCfgFilePath, STR_FILE_TRF_CFG);
1548 if (strAdditionalFile.equals(STR_YES)) {
1549 String strControllerCmpName = strObjControllerName + STR_ZIP_FILE_EXT;
1550 String strControllerCmpNamePath = STR_CONT_PATH + strObjControllerName + "/" +
1551 strControllerCmpName;
1552 file = new File(strControllerCmpNamePath);
1553 commMasterToSlave(new MessageSendFile(IoTCommCode.TRANSFER_FILE, strControllerCmpName, file.length()),
1554 "Sending file!", inStream, outStream);
1555 // Send file - Class file for object creation
1556 sendFile(serverSocket.accept(), strControllerCmpNamePath, file.length());
1557 msgReply = (Message) inStream.readObject();
1558 RuntimeOutput.print("IoTMaster: Reply message: " + msgReply.getMessage(), BOOL_VERBOSE);
1564 * A method to send files to C++ IoTSlave
1567 * TODO: Need to look into this (as of now, file transferred retains the "data" format,
1568 * hence it is unreadable from outside world
1570 private void sendFileToCppSlave(String sFilePath, String sFileName, Socket fileSocket,
1571 InputStream inStream, OutputStream outStream) throws IOException {
1573 sendCommCode(IoTCommCode.TRANSFER_FILE, outStream, inStream);
1575 sendString(sFileName, outStream); recvAck(inStream);
1576 File file = new File(sFilePath + sFileName);
1577 int iFileLen = toIntExact(file.length());
1578 RuntimeOutput.print("IoTMaster: Sending file " + sFileName + " with length " + iFileLen + " bytes...", BOOL_VERBOSE);
1580 sendInteger(iFileLen, outStream); recvAck(inStream);
1581 RuntimeOutput.print("IoTMaster: Sent file size!", BOOL_VERBOSE);
1582 byte[] bytFile = new byte[iFileLen];
1583 InputStream inFileStream = new FileInputStream(file);
1584 RuntimeOutput.print("IoTMaster: Opened file!", BOOL_VERBOSE);
1586 OutputStream outFileStream = fileSocket.getOutputStream();
1587 RuntimeOutput.print("IoTMaster: Got output stream!", BOOL_VERBOSE);
1589 while ((iCount = inFileStream.read(bytFile)) > 0) {
1590 outFileStream.write(bytFile, 0, iCount);
1592 RuntimeOutput.print("IoTMaster: File sent!", BOOL_VERBOSE);
1598 * A method to send files to C++ IoTSlave (now master using Process() to start
1599 * file transfer using scp)
1603 private void sendFileToCppSlave(String sFilePath, String sFileName) throws IOException {
1605 // Construct shell command to transfer file
1606 String sFile = sFilePath + sFileName;
1607 String strCmdSend = STR_SCP + " " + sFile + " " + STR_USERNAME + strIoTSlaveControllerHostAdd + ":" + STR_SLAVE_DIR;
1608 runCommand(strCmdSend);
1609 RuntimeOutput.print("IoTMaster: Executing: " + strCmdSend, BOOL_VERBOSE);
1611 String strCmdUnzip = STR_SSH + " " + STR_USERNAME + strIoTSlaveControllerHostAdd + " cd " +
1612 STR_SLAVE_DIR + " sudo unzip -o " + sFileName + ";";
1613 runCommand(strCmdUnzip);
1614 RuntimeOutput.print("IoTMaster: Executing: " + strCmdUnzip, BOOL_VERBOSE);
1619 * runCommand() method runs shell command
1621 * @param strCommand String that contains command line
1624 private void runCommand(String strCommand) {
1627 Runtime runtime = Runtime.getRuntime();
1628 Process process = runtime.exec(strCommand);
1630 } catch (IOException ex) {
1631 System.out.println("RouterConfig: IOException: " + ex.getMessage());
1632 ex.printStackTrace();
1633 } catch (InterruptedException ex) {
1634 System.out.println("RouterConfig: InterruptException: " + ex.getMessage());
1635 ex.printStackTrace();
1641 * Construct command line for Java IoTSlave
1645 private String getCmdJavaIoTSlave(String strObjControllerName) {
1647 // Create an Shell executable
1648 String strJavaCommand = STR_SHELL_HEADER + "\nexec " + STR_JAVA_PATH + " " + STR_JVM_INIT_HEAP_SIZE + " " +
1649 STR_JVM_MAX_HEAP_SIZE + " " + STR_CLS_PATH + " " + STR_RMI_PATH + " " + STR_IOT_SLAVE_CLS + " " +
1650 strIoTMasterHostAdd + " " + commHan.getComPort(strObjControllerName) + " " +
1651 commHan.getRMIRegPort(strObjControllerName) + " " + commHan.getRMIStubPort(strObjControllerName) +
1652 " > " + STR_LOG_FILE_PATH + strObjControllerName + ".log &";
1653 String shellFile = "./" + strObjControllerName + STR_SHELL_FILE_EXT;
1654 createWrapperShellScript(strJavaCommand, shellFile);
1655 // Send the file to the compute node
1656 String strCmdSend = "scp " + shellFile + " " + STR_USERNAME + strIoTSlaveControllerHostAdd + ":" + STR_RUNTIME_DIR;
1657 runCommand(strCmdSend);
1658 System.out.println("IoTMaster: Sending main controller shell file: " + strCmdSend);
1659 return STR_SSH + " " + STR_USERNAME + strIoTSlaveControllerHostAdd + " cd " + STR_RUNTIME_DIR + " " + shellFile;
1664 * Construct command line for C++ IoTSlave
1668 private String getCmdCppIoTSlave(String strObjControllerName) {
1670 return STR_SSH + " " + STR_USERNAME + strIoTSlaveControllerHostAdd + " cd " +
1671 STR_SLAVE_DIR + " sudo " + STR_IOTSLAVE_CPP + " " + strIoTMasterHostAdd + " " +
1672 commHan.getComPort(strObjControllerName) + " " + strObjControllerName;
1677 * sendInteger() sends an integer in bytes
1679 public void sendInteger(int intSend, OutputStream outStream) throws IOException {
1681 BufferedOutputStream output = (BufferedOutputStream) outStream;
1682 // Transform integer into bytes
1683 ByteBuffer bb = ByteBuffer.allocate(INT_SIZE);
1685 // Send the byte array
1686 output.write(bb.array(), 0, INT_SIZE);
1692 * recvInteger() receives integer in bytes
1694 public int recvInteger(InputStream inStream) throws IOException {
1696 BufferedInputStream input = (BufferedInputStream) inStream;
1697 // Wait until input is available
1698 while(input.available() == 0);
1699 // Read integer - 4 bytes
1700 byte[] recvInt = new byte[INT_SIZE];
1701 input.read(recvInt, 0, INT_SIZE);
1702 int retVal = ByteBuffer.wrap(recvInt).getInt();
1709 * recvString() receives String in bytes
1711 public String recvString(InputStream inStream) throws IOException {
1713 BufferedInputStream input = (BufferedInputStream) inStream;
1714 int strLen = recvInteger(inStream);
1715 // Wait until input is available
1716 while(input.available() == 0);
1717 // Read String per strLen
1718 byte[] recvStr = new byte[strLen];
1719 input.read(recvStr, 0, strLen);
1720 String retVal = new String(recvStr);
1727 * sendString() sends a String in bytes
1729 public void sendString(String strSend, OutputStream outStream) throws IOException {
1731 BufferedOutputStream output = (BufferedOutputStream) outStream;
1732 // Transform String into bytes
1733 byte[] strSendBytes = strSend.getBytes();
1734 int strLen = strSend.length();
1735 // Send the string length first
1736 sendInteger(strLen, outStream);
1737 // Send the byte array
1738 output.write(strSendBytes, 0, strLen);
1744 * Convert integer to enum
1746 public IoTCommCode getCode(int intCode) throws IOException {
1748 IoTCommCode[] commCode = IoTCommCode.values();
1749 IoTCommCode retCode = commCode[intCode];
1758 public synchronized boolean recvAck(InputStream inStream) throws IOException {
1760 int intAck = recvInteger(inStream);
1761 IoTCommCode codeAck = getCode(intAck);
1762 if (codeAck == IoTCommCode.ACKNOWLEDGED)
1772 public void sendEndTransfer(OutputStream outStream) throws IOException {
1774 int endCode = IoTCommCode.END_TRANSFER.ordinal();
1775 sendInteger(endCode, outStream);
1780 * Send communication code to C++
1782 public void sendCommCode(IoTCommCode inpCommCode, OutputStream outStream, InputStream inStream) throws IOException {
1785 IoTCommCode commCode = inpCommCode;
1786 int intCode = commCode.ordinal();
1787 // TODO: delete this later
1788 System.out.println("DEBUG: Sending " + commCode + " with ordinal: " + intCode);
1789 sendInteger(intCode, outStream); recvAck(inStream);
1794 * Create a main controller object for C++
1796 public void createMainObjectCpp(String strObjControllerName, OutputStream outStream, InputStream inStream) throws IOException {
1798 sendCommCode(IoTCommCode.CREATE_MAIN_OBJECT, outStream, inStream);
1799 String strMainObjName = strObjControllerName;
1800 sendString(strMainObjName, outStream); recvAck(inStream);
1801 RuntimeOutput.print("IoTMaster: Create a main object: " + strMainObjName, BOOL_VERBOSE);
1806 * A helper function that converts Class into String
1808 * @param strDataType String MySQL data type
1811 public String getClassConverted(Class<?> cls) {
1813 if (cls == String.class) {
1815 } else if (cls == int.class) {
1824 * A helper function that converts Object into String for transfer to C++ slave
1826 * @param obj Object to be converted
1827 * @param strClassType String Java Class type
1830 public String getObjectConverted(Object obj) {
1832 if (obj instanceof String) {
1833 return (String) obj;
1834 } else if (obj instanceof Integer) {
1835 return Integer.toString((Integer) obj);
1843 * Create a driver object for C++
1845 public void createObjectCpp(String strObjName, String strObjClassName, String strObjClassInterfaceName, String strIoTSlaveObjectHostAdd,
1846 Integer iRMIRegistryPort, Integer iRMIStubPort, Object[] arrFieldValues, Class[] arrFieldClasses,
1847 OutputStream outStream, InputStream inStream) throws IOException {
1849 sendCommCode(IoTCommCode.CREATE_OBJECT, outStream, inStream);
1850 RuntimeOutput.print("IoTMaster: Send request to create a driver object... ", BOOL_VERBOSE);
1851 RuntimeOutput.print("IoTMaster: Driver object name: " + strObjName, BOOL_VERBOSE);
1852 sendString(strObjName, outStream); recvAck(inStream);
1853 RuntimeOutput.print("IoTMaster: Driver object class name: " + strObjClassName, BOOL_VERBOSE);
1854 sendString(strObjClassName, outStream); recvAck(inStream);
1855 RuntimeOutput.print("IoTMaster: Driver object interface name: " + strObjClassInterfaceName, BOOL_VERBOSE);
1856 sendString(strObjStubClsIntfaceName, outStream); recvAck(inStream);
1857 RuntimeOutput.print("IoTMaster: Driver object skeleton class name: " + strObjClassInterfaceName + STR_SKEL_CLASS_SUFFIX, BOOL_VERBOSE);
1858 sendString(strObjClassInterfaceName + STR_SKEL_CLASS_SUFFIX, outStream); recvAck(inStream);
1859 RuntimeOutput.print("IoTMaster: Driver object registry port: " + iRMIRegistryPort, BOOL_VERBOSE);
1860 sendInteger(iRMIRegistryPort, outStream); recvAck(inStream);
1861 RuntimeOutput.print("IoTMaster: Driver object stub port: " + iRMIStubPort, BOOL_VERBOSE);
1862 sendInteger(iRMIStubPort, outStream); recvAck(inStream);
1863 int numOfArgs = arrFieldValues.length;
1864 RuntimeOutput.print("IoTMaster: Send constructor arguments! Number of arguments: " + numOfArgs, BOOL_VERBOSE);
1865 sendInteger(numOfArgs, outStream); recvAck(inStream);
1866 for(Object obj : arrFieldValues) {
1867 String str = getObjectConverted(obj);
1868 sendString(str, outStream); recvAck(inStream);
1870 RuntimeOutput.print("IoTMaster: Send constructor argument classes!", BOOL_VERBOSE);
1871 for(Class cls : arrFieldClasses) {
1872 String str = getClassConverted(cls);
1873 sendString(str, outStream); recvAck(inStream);
1879 * Create new IoTSet for C++
1881 public void createNewIoTSetCpp(String strObjFieldName, OutputStream outStream, InputStream inStream) throws IOException {
1883 sendCommCode(IoTCommCode.CREATE_NEW_IOTSET, outStream, inStream);
1884 RuntimeOutput.print("IoTMaster: Creating new IoTSet...", BOOL_VERBOSE);
1885 RuntimeOutput.print("IoTMaster: Send object field name: " + strObjFieldName, BOOL_VERBOSE);
1886 sendString(strObjFieldName, outStream); recvAck(inStream);
1891 * Create new IoTRelation for C++
1893 public void createNewIoTRelationCpp(String strObjFieldName, OutputStream outStream, InputStream inStream) throws IOException {
1895 sendCommCode(IoTCommCode.CREATE_NEW_IOTRELATION, outStream, inStream);
1896 RuntimeOutput.print("IoTMaster: Creating new IoTRelation...", BOOL_VERBOSE);
1897 RuntimeOutput.print("IoTMaster: Send object field name: " + strObjFieldName, BOOL_VERBOSE);
1898 sendString(strObjFieldName, outStream); recvAck(inStream);
1903 * Get a IoTDeviceAddress object for C++
1905 public void getDeviceIoTSetObjectCpp(OutputStream outStream, InputStream inStream,
1906 String strDeviceAddress, int iSourcePort, int iDestPort, boolean bSourceWildCard, boolean bDestWildCard) throws IOException {
1908 sendCommCode(IoTCommCode.GET_DEVICE_IOTSET_OBJECT, outStream, inStream);
1909 RuntimeOutput.print("IoTMaster: Getting IoTDeviceAddress...", BOOL_VERBOSE);
1910 sendString(strDeviceAddress, outStream); recvAck(inStream);
1911 sendInteger(iSourcePort, outStream); recvAck(inStream);
1912 sendInteger(iDestPort, outStream); recvAck(inStream);
1913 int iSourceWildCard = (bSourceWildCard ? 1 : 0);
1914 sendInteger(iSourceWildCard, outStream); recvAck(inStream);
1915 int iDestWildCard = (bDestWildCard ? 1 : 0);
1916 sendInteger(iDestWildCard, outStream); recvAck(inStream);
1917 RuntimeOutput.print("IoTMaster: Send device address: " + strDeviceAddress, BOOL_VERBOSE);
1922 * Get a IoTSet content object for C++
1924 public void getIoTSetRelationObjectCpp(IoTCommCode iotCommCode, String strIoTSlaveHostAddress, String strObjectName, String strObjectClassName,
1925 String strObjectClassInterfaceName, String strObjectStubClassInterfaceName, int iRMIRegistryPort, int iRMIStubPort,
1926 OutputStream outStream, InputStream inStream) throws IOException {
1928 sendCommCode(iotCommCode, outStream, inStream);
1929 RuntimeOutput.print("IoTMaster: Getting IoTSet object content...", BOOL_VERBOSE);
1931 RuntimeOutput.print("IoTMaster: Send host address: " + strIoTSlaveHostAddress, BOOL_VERBOSE);
1932 sendString(strIoTSlaveHostAddress, outStream); recvAck(inStream);
1933 RuntimeOutput.print("IoTMaster: Driver object name: " + strObjectName, BOOL_VERBOSE);
1934 sendString(strObjectName, outStream); recvAck(inStream);
1935 RuntimeOutput.print("IoTMaster: Driver object class name: " + strObjectClassName, BOOL_VERBOSE);
1936 sendString(strObjectClassName, outStream); recvAck(inStream);
1937 RuntimeOutput.print("IoTMaster: Driver object interface name: " + strObjectClassInterfaceName, BOOL_VERBOSE);
1938 sendString(strObjectClassInterfaceName, outStream); recvAck(inStream);
1939 RuntimeOutput.print("IoTMaster: Driver object stub class name: " + strObjectStubClassInterfaceName + STR_STUB_CLASS_SUFFIX, BOOL_VERBOSE);
1940 sendString(strObjectStubClassInterfaceName + STR_STUB_CLASS_SUFFIX, outStream); recvAck(inStream);
1941 RuntimeOutput.print("IoTMaster: Driver object registry port: " + iRMIRegistryPort, BOOL_VERBOSE);
1942 sendInteger(iRMIRegistryPort, outStream); recvAck(inStream);
1943 RuntimeOutput.print("IoTMaster: Driver object stub port: " + iRMIStubPort, BOOL_VERBOSE);
1944 sendInteger(iRMIStubPort, outStream); recvAck(inStream);
1949 * Reinitialize IoTRelation field for C++
1951 private void reinitializeIoTRelationFieldCpp(OutputStream outStream, InputStream inStream) throws IOException {
1953 RuntimeOutput.print("IoTMaster: About to Reinitialize IoTRelation field!", BOOL_VERBOSE);
1954 sendCommCode(IoTCommCode.REINITIALIZE_IOTRELATION_FIELD, outStream, inStream);
1955 RuntimeOutput.print("IoTMaster: Reinitialize IoTRelation field!", BOOL_VERBOSE);
1960 * Reinitialize IoTSet field for C++
1962 private void reinitializeIoTSetFieldCpp(OutputStream outStream, InputStream inStream) throws IOException {
1964 RuntimeOutput.print("IoTMaster: About to Reinitialize IoTSet field!", BOOL_VERBOSE);
1965 sendCommCode(IoTCommCode.REINITIALIZE_IOTSET_FIELD, outStream, inStream);
1966 RuntimeOutput.print("IoTMaster: Reinitialize IoTSet field!", BOOL_VERBOSE);
1971 * Create driver object for C++
1973 private void createDriverObjectCpp(OutputStream outStream, InputStream inStream) throws IOException {
1975 sendCommCode(IoTCommCode.CREATE_DRIVER_OBJECT, outStream, inStream);
1976 RuntimeOutput.print("IoTMaster: Send command to create driver object!", BOOL_VERBOSE);
1981 * Invoke init() for C++
1983 private void invokeInitMethodCpp(OutputStream outStream, InputStream inStream) throws IOException {
1985 sendCommCode(IoTCommCode.INVOKE_INIT_METHOD, outStream, inStream);
1986 RuntimeOutput.print("IoTMaster: Invoke init method!", BOOL_VERBOSE);
1991 * End session for C++
1993 public void endSessionCpp(OutputStream outStream) throws IOException {
1995 // Send message to end session
1996 IoTCommCode endSessionCode = IoTCommCode.END_SESSION;
1997 int intCode = endSessionCode.ordinal();
1998 sendInteger(intCode, outStream);
1999 //RuntimeOutput.print("IoTMaster: Send request to create a main object: " + strObjName, BOOL_VERBOSE);
2000 RuntimeOutput.print("IoTMaster: Send request to end session!", BOOL_VERBOSE);
2005 * A method to assign objects to multiple JVMs, including
2006 * the controller/device object that uses other objects
2007 * in IoTSet and IoTRelation
2011 private void createObjects() {
2018 // Extract hostname for this IoTMaster from MySQL DB
2019 strIoTMasterHostAdd = routerConfig.getIPFromMACAddress(STR_MASTER_MAC_ADD);
2020 // Assign a new list of PrintWriter objects
2021 routerConfig.renewPrintWriter();
2022 HashSet<String> setAddresses = null;
2023 // Loop as we can still find controller/device classes
2024 for(int i=0; i<strObjectNames.length; i++) {
2026 start = System.currentTimeMillis();
2027 // Assign a new list of main PrintWriter objects
2028 routerConfig.renewMainPrintWriter();
2029 // Get controller names one by one
2030 String strObjControllerName = strObjectNames[i];
2031 // Use LoadBalancer to assign a host address
2032 //strIoTSlaveControllerHostAdd = lbIoT.selectHost();
2033 strIoTSlaveControllerHostAdd = routerConfig.getIPFromMACAddress(lbIoT.selectHost());
2034 if (strIoTSlaveControllerHostAdd == null)
2035 throw new Error("IoTMaster: Could not translate MAC to IP address! Please check the router's /tmp/dhcp.leases!");
2036 // == START INITIALIZING CONTROLLER/DEVICE IOTSLAVE ==
2037 // Add port connection and get port numbers
2038 // Naming for objects ProximitySensor becomes ProximitySensor0, ProximitySensor1, etc.
2039 commHan.addPortConnection(strIoTSlaveControllerHostAdd, strObjControllerName);
2040 // ROUTING POLICY: IoTMaster and main controller object
2041 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTMasterHostAdd,
2042 strIoTSlaveControllerHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjControllerName));
2043 // ROUTING POLICY: Send the same routing policy to both the hosts
2044 routerConfig.configureHostMainPolicies(strIoTMasterHostAdd, strIoTMasterHostAdd,
2045 strIoTSlaveControllerHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjControllerName));
2046 routerConfig.configureHostMainPolicies(strIoTSlaveControllerHostAdd, strIoTMasterHostAdd,
2047 strIoTSlaveControllerHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjControllerName));
2049 String strControllerCfg = STR_CONT_PATH + strObjControllerName + "/" + strObjControllerName + STR_CFG_FILE_EXT;
2050 STR_LANGUAGE_CONTROLLER = parseConfigFile(strControllerCfg, STR_LANGUAGE);
2051 if(STR_LANGUAGE_CONTROLLER == null)
2052 throw new Error("IoTMaster: Language specification missing in config file: " + strControllerCfg);
2053 // Construct ssh command line and create a controller thread for e.g. AcmeProximity
2054 String strSSHCommand = null;
2055 if(STR_LANGUAGE_CONTROLLER.equals(STR_JAVA))
2056 strSSHCommand = getCmdJavaIoTSlave(strObjControllerName);
2057 else if(STR_LANGUAGE_CONTROLLER.equals(STR_CPP))
2058 strSSHCommand = getCmdCppIoTSlave(strObjControllerName);
2060 throw new Error("IoTMaster: Language specification not recognized: " + STR_LANGUAGE_CONTROLLER);
2061 RuntimeOutput.print(strSSHCommand, BOOL_VERBOSE);
2062 createThread(strSSHCommand);
2063 // Wait for connection
2064 // Create a new socket for communication
2065 ServerSocket serverSocket = new ServerSocket(commHan.getComPort(strObjControllerName));
2066 Socket socket = serverSocket.accept();
2067 InputStream inStream = null;
2068 OutputStream outStream = null;
2069 if(STR_LANGUAGE_CONTROLLER.equals(STR_JAVA)) {
2070 inStream = new ObjectInputStream(socket.getInputStream());
2071 outStream = new ObjectOutputStream(socket.getOutputStream());
2072 } else { // At this point the language is certainly C++, otherwise would've complained above
2073 inStream = new BufferedInputStream(socket.getInputStream());
2074 outStream = new BufferedOutputStream(socket.getOutputStream());
2077 RuntimeOutput.print("IoTMaster: Communication established!", BOOL_VERBOSE);
2080 result = System.currentTimeMillis()-start;
2081 System.out.println("\n\n ==> From start until after SSH for main controller: " + result);
2083 start = System.currentTimeMillis();
2085 // Send files for every controller class
2086 // e.g. AcmeProximity.jar and AcmeProximity.zip
2087 String strControllerClassName = strObjControllerName + STR_CLS_FILE_EXT;
2088 String strControllerClassNamePath = STR_CONT_PATH + strObjControllerName + "/" +
2089 strControllerClassName;
2091 if(STR_LANGUAGE_CONTROLLER.equals(STR_JAVA)) {
2092 sendFileToJavaSlave(strObjControllerName, serverSocket, inStream, outStream);
2093 // Create main controller/device object
2094 commMasterToSlave(new MessageCreateMainObject(IoTCommCode.CREATE_MAIN_OBJECT, strObjControllerName),
2095 "Create main object!", inStream, outStream);
2097 String strControllerZipFile = strObjControllerName + STR_ZIP_FILE_EXT;
2098 String strControllerFilePath = STR_CONT_PATH + strObjControllerName + "/";
2099 sendFileToCppSlave(strControllerFilePath, strControllerZipFile);
2100 createMainObjectCpp(strObjControllerName, outStream, inStream);
2102 // Write basic MAC policies for controller
2103 //String strFileName = STR_MAC_POL_PATH + strObjControllerName + STR_MAC_POLICY_EXT;
2104 if (STR_ACTIVATE_SANDBOXING.equals("Yes")) {
2105 String strFileName = STR_MAC_POL_PATH + STR_JAVA + STR_MAC_POLICY_EXT;
2106 processJailConfig.configureProcessJailControllerPolicies(strObjControllerName, strFileName,
2107 strIoTMasterHostAdd, commHan.getComPort(strObjControllerName));
2108 // Whether or not we need additional Tomoyo policy?
2109 String strAddMACPolicy = parseConfigFile(strControllerCfg, STR_ADD_MAC_POL);
2110 if (strAddMACPolicy != null && strAddMACPolicy.equals("Yes")) {
2111 String strContMACCfg = STR_CONT_PATH + strObjControllerName + "/";
2112 processJailConfig.combineAdditionalMACPolicy(strContMACCfg, strObjControllerName, strObjControllerName);
2116 result = System.currentTimeMillis()-start;
2117 System.out.println("\n\n ==> From IoTSlave start until main controller object is created: " + result);
2118 System.out.println(" ==> Including file transfer times!\n\n");
2120 start = System.currentTimeMillis();
2122 // == END INITIALIZING CONTROLLER/DEVICE IOTSLAVE ==
2123 // Instrumenting one file
2124 RuntimeOutput.print("IoTMaster: Opening class file: " + strControllerClassName, BOOL_VERBOSE);
2125 RuntimeOutput.print("IoTMaster: Class file path: " + strControllerClassNamePath, BOOL_VERBOSE);
2126 HashMap<String,Object> hmControllerFieldObjects = null;
2127 if(STR_LANGUAGE_CONTROLLER.equals(STR_JAVA)) {
2128 FileInputStream fis = new FileInputStream(strControllerClassNamePath);
2129 ClassReader cr = new ClassReader(fis);
2130 ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
2131 ClassRuntimeInstrumenterMaster crim = new ClassRuntimeInstrumenterMaster(cw, null, BOOL_VERBOSE);
2134 hmControllerFieldObjects = crim.getFieldObjects();
2136 String strControllerConfigFile = STR_CONT_PATH + strObjControllerName + "/" + strObjControllerName + STR_CFG_FILE_EXT;
2137 CRuntimeInstrumenterMaster crim = new CRuntimeInstrumenterMaster(strControllerConfigFile, null, BOOL_VERBOSE);
2138 hmControllerFieldObjects = crim.getFieldObjects();
2140 // Get the object and the class names
2141 // Build objects for IoTSet and IoTRelation fields in the controller/device classes
2142 //HashMap<String,Object> hmControllerFieldObjects = crim.getFieldObjects();
2143 for(Map.Entry<String,Object> map : hmControllerFieldObjects.entrySet()) {
2144 RuntimeOutput.print("IoTMaster: Object name: " + map.getValue().getClass().getName(), BOOL_VERBOSE);
2145 // Iterate over HashMap and choose between processing
2146 // SetInstrumenter vs. RelationInstrumenter
2147 String strFieldName = map.getKey();
2148 String strClassName = map.getValue().getClass().getName();
2150 System.out.println("\n\nDEBUG: Instrumenting IoTSet and IoTRelation objects!!!");
2151 System.out.println("DEBUG: Field name: " + strFieldName);
2152 System.out.println("DEBUG: Class name: " + strFieldName + "\n\n");
2154 if(strClassName.equals(STR_SET_INSTRUMENTER_CLS)) {
2155 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
2156 if(setInstrumenter.getObjTableName().equals(STR_IOT_DEV_ADD_CLS)) {
2157 String strErrMsg = "IoTMaster: Controller object" +
2158 " cannot have IoTSet<IoTDeviceAddress>!";
2159 throw new Error(strErrMsg);
2160 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ZB_ADD_CLS)) {
2161 String strErrMsg = "IoTMaster: Controller object" +
2162 " cannot have IoTSet<ZigbeeAddress>!";
2163 throw new Error(strErrMsg);
2164 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ADD_CLS)) {
2165 // Instrument the IoTAddress
2166 setRouterPolicyIoTSetAddress(strFieldName, map, strIoTSlaveControllerHostAdd, strObjControllerName);
2167 instrumentIoTSetAddress(strFieldName, strFieldName, inStream, outStream, STR_LANGUAGE_CONTROLLER);
2170 instrumentIoTSet(map, strFieldName, strObjControllerName, STR_LANGUAGE_CONTROLLER);
2172 } else if (strClassName.equals(STR_REL_INSTRUMENTER_CLS)) {
2173 instrumentIoTRelation(map, strFieldName, strObjControllerName, STR_LANGUAGE_CONTROLLER);
2176 // Combine controller MAC policies with the main policy file for the host
2177 String strTempFileName = "./" + strObjControllerName + STR_MAC_POLICY_EXT;
2178 processJailConfig.combineControllerMACPolicies(strIoTSlaveControllerHostAdd, strObjControllerName, strTempFileName);
2179 processJailConfig.flush();
2182 result = System.currentTimeMillis()-start;
2183 System.out.println("\n\n ==> Time needed to instrument device driver objects: " + result + "\n\n");
2184 System.out.println(" ==> #Objects: " + commHan.getActiveControllerObjectList().size() + "\n\n");
2187 start = System.currentTimeMillis();
2189 // ROUTING POLICY: implement basic policies to reject all other irrelevant traffics
2190 for(String s: commHan.getHosts()) {
2191 setHostBasicPolicies(s);
2193 // We retain all the basic policies for router,
2194 // but we delete the initial allowance policies for internal all TCP and UDP communications
2195 setRouterBasicPolicies(STR_ROUTER_ADD);
2196 routerConfig.closeMain();
2197 // Deploy the policy
2198 setAddresses = new HashSet<String>(commHan.getHosts());
2199 setAddresses.add(strIoTMasterHostAdd);
2200 // See if firewall policy is configured to be "on" or "off"
2201 if (STR_POLICY_ON.equals(STR_YES))
2202 createPolicyThreads(STR_ROUTER_ADD, setAddresses);
2205 result = System.currentTimeMillis()-start;
2206 System.out.println("\n\n ==> Time needed to send policy files and deploy them : " + result + "\n\n");
2209 start = System.currentTimeMillis();
2211 // Separating object creations and Set/Relation initializations
2212 createDriverObjects();
2215 result = System.currentTimeMillis()-start;
2216 System.out.println("\n\n ==> Time needed to instantiate objects: " + result + "\n\n");
2218 start = System.currentTimeMillis();
2220 // Sets and relations initializations
2221 if(STR_LANGUAGE_CONTROLLER.equals(STR_JAVA))
2222 initializeSetsAndRelationsJava(inStream, outStream);
2224 initializeSetsAndRelationsCpp(inStream, outStream);;
2227 result = System.currentTimeMillis()-start;
2228 System.out.println("\n\n ==> Time needed to initialize sets and relations: " + result + "\n\n");
2230 if(STR_LANGUAGE_CONTROLLER.equals(STR_JAVA))
2231 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO EXECUTE INIT METHOD
2232 commMasterToSlave(new MessageSimple(IoTCommCode.INVOKE_INIT_METHOD), "Invoke init() method!", inStream, outStream);
2234 invokeInitMethodCpp(outStream, inStream);
2235 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO END PROCESS
2236 if(STR_LANGUAGE_CONTROLLER.equals(STR_JAVA)) {
2237 ObjectOutputStream oStream = (ObjectOutputStream) outStream;
2238 oStream.writeObject(new MessageSimple(IoTCommCode.END_SESSION));
2239 } else // C++ side will wait until the program finishes, it's not generating a separate thread for now
2240 //endSessionCpp(outStream);
2244 serverSocket.close();
2245 objInitHand.clearObjectInitHandler();
2246 commHan.printLists();
2247 commHan.clearCommunicationHandler();
2248 lbIoT.printHostInfo();
2250 // Close access to policy files and deploy policies
2251 routerConfig.close();
2252 processJailConfig.close();
2253 if (STR_ACTIVATE_SANDBOXING.equals("Yes"))
2254 createMACPolicyThreads(setAddresses);
2256 } catch (IOException |
2257 InterruptedException |
2258 ClassNotFoundException ex) {
2259 System.out.println("IoTMaster: Exception: "
2261 ex.printStackTrace();
2265 public static void main(String args[]) {
2267 // Detect the available controller/device classes
2268 // Input args[] should be used to list the controllers/devices
2269 // e.g. java IoTMaster AcmeProximity AcmeThermostat AcmeVentController
2270 IoTMaster iotMaster = new IoTMaster(args);
2272 iotMaster.parseIoTMasterConfigFile();
2273 // Initialize CommunicationHandler, LoadBalancer, and RouterConfig
2274 iotMaster.initLiveDataStructure();
2276 iotMaster.createObjects();