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 boolean BOOL_VERBOSE;
109 * IoTMaster class constants
111 * Name constants - not to be configured by users
113 private static final String STR_IOT_MASTER_NAME = "IoTMaster";
114 private static final String STR_CFG_FILE_EXT = ".config";
115 private static final String STR_CLS_FILE_EXT = ".class";
116 private static final String STR_JAR_FILE_EXT = ".jar";
117 private static final String STR_MAC_POLICY_EXT = ".tomoyo.pol";
118 private static final String STR_SHELL_FILE_EXT = ".sh";
119 private static final String STR_SO_FILE_EXT = ".so";
120 private static final String STR_ZIP_FILE_EXT = ".zip";
121 private static final String STR_TCP_PROTOCOL = "tcp";
122 private static final String STR_UDP_PROTOCOL = "udp";
123 private static final String STR_TCPGW_PROTOCOL = "tcpgw";
124 private static final String STR_NO_PROTOCOL = "nopro";
125 private static final String STR_SELF_MAC_ADD = "00:00:00:00:00:00";
126 private static final String STR_INTERFACE_CLS_CFG = "INTERFACE_CLASS";
127 private static final String STR_INT_STUB_CLS_CFG = "INTERFACE_STUB_CLASS";
128 private static final String STR_FILE_TRF_CFG = "ADDITIONAL_ZIP_FILE";
129 private static final String STR_LANGUAGE = "LANGUAGE";
130 private static final String STR_YES = "Yes";
131 private static final String STR_NO = "No";
132 private static final String STR_JAVA = "Java";
133 private static final String STR_CPP = "C++";
134 private static final String STR_SSH = "ssh";
135 private static final String STR_SCP = "scp";
136 private static final String STR_IOTSLAVE_CPP = "./IoTSlave.o";
137 private static final String STR_SHELL_HEADER = "#!/bin/sh";
138 private static final String STR_JAVA_PATH = "/usr/bin/java";
139 private static final String STR_MAC_POL_PATH = "tomoyo/";
141 private static int INT_SIZE = 4; // send length in the size of integer (4 bytes)
142 private static final int INT_DNS_PORT = 53;
145 * Runtime class name constants - not to be configured by users
147 private static final String STR_REL_INSTRUMENTER_CLS = "iotruntime.master.RelationInstrumenter";
148 private static final String STR_SET_INSTRUMENTER_CLS = "iotruntime.master.SetInstrumenter";
149 private static final String STR_IOT_SLAVE_CLS = "iotruntime.slave.IoTSlave";
150 private static final String STR_IOT_DEV_ADD_CLS = "IoTDeviceAddress";
151 private static final String STR_IOT_ZB_ADD_CLS = "IoTZigbeeAddress";
152 private static final String STR_IOT_ADD_CLS = "IoTAddress";
158 public IoTMaster(String[] argObjNms) {
163 processJailConfig = null;
165 objAddInitHand = null;
166 strObjectNames = argObjNms;
168 strObjClassName = null;
169 strObjClassInterfaceName = null;
170 strObjStubClsIntfaceName = null;
171 strIoTMasterHostAdd = null;
172 strIoTSlaveControllerHostAdd = null;
173 strIoTSlaveObjectHostAdd = null;
174 arrFieldClasses = null;
175 arrFieldValues = null;
177 mapClassNameToCrim = null;
178 // Connection with C++ IoTSlave
179 serverSocketCpp = null;
184 STR_MASTER_MAC_ADD = null;
185 STR_IOT_CODE_PATH = null;
186 STR_CONT_PATH = null;
187 STR_RUNTIME_DIR = null;
188 STR_SLAVE_DIR = null;
191 STR_RMI_HOSTNAME = null;
192 STR_LOG_FILE_PATH = null;
194 STR_ROUTER_ADD = null;
195 STR_MONITORING_HOST = null;
196 STR_ZB_GATEWAY_ADDRESS = null;
197 STR_ZB_GATEWAY_PORT = null;
198 STR_ZB_IOTMASTER_PORT = null;
199 STR_JVM_INIT_HEAP_SIZE = null;
200 STR_JVM_MAX_HEAP_SIZE = null;
201 STR_LANGUAGE_CONTROLLER = null;
202 STR_ACTIVATE_SANDBOXING = null;
203 BOOL_VERBOSE = false;
207 * A method to initialize CommunicationHandler, LoadBalancer, RouterConfig and ObjectInitHandler
211 private void initLiveDataStructure() {
213 commHan = new CommunicationHandler(BOOL_VERBOSE);
214 lbIoT = new LoadBalancer(BOOL_VERBOSE);
215 lbIoT.setupLoadBalancer();
216 routerConfig = new RouterConfig();
217 routerConfig.getAddressList(STR_ROUTER_ADD);
218 processJailConfig = new ProcessJailConfig();
219 //processJailConfig.setAddressListObject(routerConfig.getAddressListObject());
220 objInitHand = new ObjectInitHandler(BOOL_VERBOSE);
221 objAddInitHand = new ObjectAddressInitHandler(BOOL_VERBOSE);
222 mapClassNameToCrim = new HashMap<String,Object>();
226 * getPrintWriter() gets a new PrintWriter for a new object
228 * @param strObjectName String object name
229 * @return PrintWriter
231 private PrintWriter getPrintWriter(String strObjectName) {
233 FileWriter fw = null;
235 fw = new FileWriter(strObjectName);
236 } catch (IOException ex) {
237 ex.printStackTrace();
239 PrintWriter printWriter = new PrintWriter(new BufferedWriter(fw));
244 * A method to initialize constants from config file
248 private void parseIoTMasterConfigFile() {
249 // Parse configuration file
250 Properties prop = new Properties();
251 String strCfgFileName = STR_IOT_MASTER_NAME + STR_CFG_FILE_EXT;
252 File file = new File(strCfgFileName);
253 FileInputStream fis = null;
255 fis = new FileInputStream(file);
258 } catch (IOException ex) {
259 System.out.println("IoTMaster: Error reading config file: " + strCfgFileName);
260 ex.printStackTrace();
262 // Initialize constants from config file
263 STR_MASTER_MAC_ADD = prop.getProperty("MAC_ADDRESS");
264 STR_IOT_CODE_PATH = prop.getProperty("IOT_CODE_PATH");
265 STR_CONT_PATH = prop.getProperty("CONTROLLERS_CODE_PATH");
266 STR_RUNTIME_DIR = prop.getProperty("RUNTIME_DIR");
267 STR_SLAVE_DIR = prop.getProperty("SLAVE_DIR");
268 STR_CLS_PATH = prop.getProperty("CLASS_PATH");
269 STR_RMI_PATH = prop.getProperty("RMI_PATH");
270 STR_RMI_HOSTNAME = prop.getProperty("RMI_HOSTNAME");
271 STR_LOG_FILE_PATH = prop.getProperty("LOG_FILE_PATH");
272 STR_USERNAME = prop.getProperty("USERNAME");
273 STR_ROUTER_ADD = prop.getProperty("ROUTER_ADD");
274 STR_MONITORING_HOST = prop.getProperty("MONITORING_HOST");
275 STR_ZB_GATEWAY_ADDRESS = prop.getProperty("ZIGBEE_GATEWAY_ADDRESS");
276 STR_ZB_GATEWAY_PORT = prop.getProperty("ZIGBEE_GATEWAY_PORT");
277 STR_ZB_IOTMASTER_PORT = prop.getProperty("ZIGBEE_IOTMASTER_PORT");
278 STR_JVM_INIT_HEAP_SIZE = prop.getProperty("JVM_INIT_HEAP_SIZE");
279 STR_JVM_MAX_HEAP_SIZE = prop.getProperty("JVM_MAX_HEAP_SIZE");
280 STR_SKEL_CLASS_SUFFIX = prop.getProperty("SKEL_CLASS_SUFFIX");
281 STR_STUB_CLASS_SUFFIX = prop.getProperty("STUB_CLASS_SUFFIX");
282 STR_ACTIVATE_SANDBOXING = prop.getProperty("ACTIVATE_SANDBOXING");
283 if(prop.getProperty("VERBOSE").equals(STR_YES)) {
287 RuntimeOutput.print("IoTMaster: Extracting information from config file: " + strCfgFileName, BOOL_VERBOSE);
288 RuntimeOutput.print("STR_MASTER_MAC_ADD=" + STR_MASTER_MAC_ADD, BOOL_VERBOSE);
289 RuntimeOutput.print("STR_IOT_CODE_PATH=" + STR_IOT_CODE_PATH, BOOL_VERBOSE);
290 RuntimeOutput.print("STR_CONT_PATH=" + STR_CONT_PATH, BOOL_VERBOSE);
291 RuntimeOutput.print("STR_RUNTIME_DIR=" + STR_RUNTIME_DIR, BOOL_VERBOSE);
292 RuntimeOutput.print("STR_SLAVE_DIR=" + STR_SLAVE_DIR, BOOL_VERBOSE);
293 RuntimeOutput.print("STR_CLS_PATH=" + STR_CLS_PATH, BOOL_VERBOSE);
294 RuntimeOutput.print("STR_RMI_PATH=" + STR_RMI_PATH, BOOL_VERBOSE);
295 RuntimeOutput.print("STR_RMI_HOSTNAME=" + STR_RMI_HOSTNAME, BOOL_VERBOSE);
296 RuntimeOutput.print("STR_LOG_FILE_PATH=" + STR_LOG_FILE_PATH, BOOL_VERBOSE);
297 RuntimeOutput.print("STR_USERNAME=" + STR_USERNAME, BOOL_VERBOSE);
298 RuntimeOutput.print("STR_ROUTER_ADD=" + STR_ROUTER_ADD, BOOL_VERBOSE);
299 RuntimeOutput.print("STR_MONITORING_HOST=" + STR_MONITORING_HOST, BOOL_VERBOSE);
300 RuntimeOutput.print("STR_ZB_GATEWAY_ADDRESS=" + STR_ZB_GATEWAY_ADDRESS, BOOL_VERBOSE);
301 RuntimeOutput.print("STR_ZB_GATEWAY_PORT=" + STR_ZB_GATEWAY_PORT, BOOL_VERBOSE);
302 RuntimeOutput.print("STR_ZB_IOTMASTER_PORT=" + STR_ZB_IOTMASTER_PORT, BOOL_VERBOSE);
303 RuntimeOutput.print("STR_JVM_INIT_HEAP_SIZE=" + STR_JVM_INIT_HEAP_SIZE, BOOL_VERBOSE);
304 RuntimeOutput.print("STR_JVM_MAX_HEAP_SIZE=" + STR_JVM_MAX_HEAP_SIZE, BOOL_VERBOSE);
305 RuntimeOutput.print("STR_SKEL_CLASS_SUFFIX=" + STR_SKEL_CLASS_SUFFIX, BOOL_VERBOSE);
306 RuntimeOutput.print("STR_STUB_CLASS_SUFFIX=" + STR_STUB_CLASS_SUFFIX, BOOL_VERBOSE);
307 RuntimeOutput.print("STR_ACTIVATE_SANDBOXING=" + STR_ACTIVATE_SANDBOXING, BOOL_VERBOSE);
308 RuntimeOutput.print("BOOL_VERBOSE=" + BOOL_VERBOSE, BOOL_VERBOSE);
309 RuntimeOutput.print("IoTMaster: Information extracted successfully!", BOOL_VERBOSE);
313 * A method to parse information from a config file
315 * @param strCfgFileName Config file name
316 * @param strCfgField Config file field name
319 private String parseConfigFile(String strCfgFileName, String strCfgField) {
320 // Parse configuration file
321 Properties prop = new Properties();
322 File file = new File(strCfgFileName);
323 FileInputStream fis = null;
325 fis = new FileInputStream(file);
328 } catch (IOException ex) {
329 System.out.println("IoTMaster: Error reading config file: " + strCfgFileName);
330 ex.printStackTrace();
332 System.out.println("IoTMaster: Reading " + strCfgField +
333 " from config file: " + strCfgFileName + " with value: " +
334 prop.getProperty(strCfgField, null));
335 // NULL is returned if the property isn't found
336 return prop.getProperty(strCfgField, null);
340 * A method to send files from IoTMaster
342 * @param filesocket File socket object
343 * @param sFileName File name
344 * @param lFLength File length
347 private void sendFile(Socket filesocket, String sFileName, long lFLength) throws IOException {
349 File file = new File(sFileName);
350 byte[] bytFile = new byte[toIntExact(lFLength)];
351 InputStream inFileStream = new FileInputStream(file);
353 OutputStream outFileStream = filesocket.getOutputStream();
355 while ((iCount = inFileStream.read(bytFile)) > 0) {
356 outFileStream.write(bytFile, 0, iCount);
359 RuntimeOutput.print("IoTMaster: File sent!", BOOL_VERBOSE);
363 * A method to create a thread
365 * @param sSSHCmd SSH command
368 private void createThread(String sSSHCmd) throws IOException {
370 // Start a new thread to start a new JVM
372 Runtime runtime = Runtime.getRuntime();
373 Process process = runtime.exec(sSSHCmd);
375 RuntimeOutput.print("Executing: " + sSSHCmd, BOOL_VERBOSE);
379 * A method to send command from master and receive reply from slave
381 * @params msgSend Message object
382 * @params strPurpose String that prints purpose message
383 * @params inStream Input stream
384 * @params outStream Output stream
387 private void commMasterToSlave(Message msgSend, String strPurpose,
388 InputStream _inStream, OutputStream _outStream)
389 throws IOException, ClassNotFoundException {
391 // Send message/command from master
392 ObjectOutputStream outStream = (ObjectOutputStream) _outStream;
393 outStream.writeObject(msgSend);
394 RuntimeOutput.print("IoTMaster: Send message: " + strPurpose, BOOL_VERBOSE);
396 // Get reply from slave as acknowledgment
397 ObjectInputStream inStream = (ObjectInputStream) _inStream;
398 Message msgReply = (Message) inStream.readObject();
399 RuntimeOutput.print("IoTMaster: Reply message: " + msgReply.getMessage(), BOOL_VERBOSE);
403 * A private method to instrument IoTSet device
405 * @params strFieldIdentifier String field name + object ID
406 * @params strFieldName String field name
407 * @params strIoTSlaveObjectHostAdd String slave host address
408 * @params inStream ObjectInputStream communication
409 * @params inStream ObjectOutputStream communication
410 * @params strLanguage String language
413 private void instrumentIoTSetDevice(String strFieldIdentifier, String strObjName, String strFieldName, String strIoTSlaveObjectHostAdd,
414 InputStream inStream, OutputStream outStream, String strLanguage)
415 throws IOException, ClassNotFoundException, InterruptedException {
417 // Get information from the set
418 List<Object[]> listObject = objAddInitHand.getFields(strFieldIdentifier);
419 // Create a new IoTSet
420 if(strLanguage.equals(STR_JAVA)) {
421 Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, strFieldName);
422 commMasterToSlave(msgCrtIoTSet, "Create new IoTSet for IoTDeviceAddress!", inStream, outStream);
424 createNewIoTSetCpp(strFieldName, outStream, inStream);
425 int iRows = listObject.size();
426 RuntimeOutput.print("IoTMaster: Number of rows for IoTDeviceAddress: " + iRows, BOOL_VERBOSE);
427 // Transfer the address
428 for(int iRow=0; iRow<iRows; iRow++) {
429 arrFieldValues = listObject.get(iRow);
430 // Get device address - if 00:00:00:00:00:00 that means it needs the driver object address (self)
431 String strDeviceAddress = null;
432 String strDeviceAddressKey = null;
433 if (arrFieldValues[0].equals(STR_SELF_MAC_ADD)) {
434 strDeviceAddress = strIoTSlaveObjectHostAdd;
435 strDeviceAddressKey = strObjName + "-" + strIoTSlaveObjectHostAdd;
437 strDeviceAddress = routerConfig.getIPFromMACAddress((String) arrFieldValues[0]);
438 strDeviceAddressKey = strObjName + "-" + strDeviceAddress;
440 int iDestDeviceDriverPort = (int) arrFieldValues[1];
441 String strProtocol = (String) arrFieldValues[2];
442 // Check for wildcard feature
443 boolean bSrcPortWildCard = false;
444 boolean bDstPortWildCard = false;
445 if (arrFieldValues.length > 3) {
446 bSrcPortWildCard = (boolean) arrFieldValues[3];
447 bDstPortWildCard = (boolean) arrFieldValues[4];
449 // Add the port connection into communication handler - if it's not assigned yet
450 if (commHan.getComPort(strDeviceAddressKey) == null) {
451 commHan.addPortConnection(strIoTSlaveObjectHostAdd, strDeviceAddressKey);
455 System.out.println("\n\n DEBUG: InstrumentSetDevice: Object Name: " + strObjName);
456 System.out.println("DEBUG: InstrumentSetDevice: Port number: " + commHan.getComPort(strDeviceAddressKey));
457 System.out.println("DEBUG: InstrumentSetDevice: Device address: " + strDeviceAddressKey + "\n\n");
459 // Send address one by one
460 if(strLanguage.equals(STR_JAVA)) {
461 Message msgGetIoTSetObj = null;
462 if (bDstPortWildCard) {
463 String strUniqueDev = strDeviceAddressKey + ":" + iRow;
464 msgGetIoTSetObj = new MessageGetDeviceObject(IoTCommCode.GET_DEVICE_IOTSET_OBJECT,
465 strDeviceAddress, commHan.getAdditionalPort(strUniqueDev), iDestDeviceDriverPort, bSrcPortWildCard, bDstPortWildCard);
467 msgGetIoTSetObj = new MessageGetDeviceObject(IoTCommCode.GET_DEVICE_IOTSET_OBJECT,
468 strDeviceAddress, commHan.getComPort(strDeviceAddressKey), iDestDeviceDriverPort, bSrcPortWildCard, bDstPortWildCard);
469 commMasterToSlave(msgGetIoTSetObj, "Get IoTSet objects!", inStream, outStream);
471 getDeviceIoTSetObjectCpp(outStream, inStream, strDeviceAddress, commHan.getComPort(strDeviceAddressKey), iDestDeviceDriverPort,
472 bSrcPortWildCard, bDstPortWildCard);
474 // Reinitialize IoTSet on device object
475 if(strLanguage.equals(STR_JAVA))
476 commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTSET_FIELD), "Reinitialize IoTSet fields!", inStream, outStream);
478 reinitializeIoTSetFieldCpp(outStream, inStream);
483 * A private method to instrument IoTSet Zigbee device
485 * @params Map.Entry<String,Object> Entry of map IoTSet instrumentation
486 * @params strFieldName String field name
487 * @params strIoTSlaveObjectHostAdd String slave host address
488 * @params inStream ObjectInputStream communication
489 * @params inStream ObjectOutputStream communication
490 * @params strLanguage String language
493 private void instrumentIoTSetZBDevice(Map.Entry<String,Object> map, String strObjName, String strFieldName, String strIoTSlaveObjectHostAdd,
494 InputStream inStream, OutputStream outStream, String strLanguage)
495 throws IOException, ClassNotFoundException, InterruptedException {
497 // Get information from the set
498 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
499 // Create a new IoTSet
500 if(strLanguage.equals(STR_JAVA)) {
501 Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, strFieldName);
502 commMasterToSlave(msgCrtIoTSet, "Create new IoTSet for IoTZigbeeAddress!", inStream, outStream);
503 } else // TODO: will need to implement IoTSet Zigbee for C++ later
505 // Prepare ZigbeeConfig
506 String strZigbeeGWAddress = routerConfig.getIPFromMACAddress(STR_ZB_GATEWAY_ADDRESS);
507 String strZigbeeGWAddressKey = strObjName + "-" + strZigbeeGWAddress;
508 int iZigbeeGWPort = Integer.parseInt(STR_ZB_GATEWAY_PORT);
509 int iZigbeeIoTMasterPort = Integer.parseInt(STR_ZB_IOTMASTER_PORT);
510 commHan.addDevicePort(iZigbeeIoTMasterPort);
511 ZigbeeConfig zbConfig = new ZigbeeConfig(strZigbeeGWAddress, iZigbeeGWPort, iZigbeeIoTMasterPort,
513 // Add the port connection into communication handler - if it's not assigned yet
514 if (commHan.getComPort(strZigbeeGWAddressKey) == null) {
515 commHan.addPortConnection(strIoTSlaveObjectHostAdd, strZigbeeGWAddressKey);
517 int iRows = setInstrumenter.numberOfRows();
518 RuntimeOutput.print("IoTMaster: Number of rows for IoTZigbeeAddress: " + iRows, BOOL_VERBOSE);
521 System.out.println("\n\nDEBUG: InstrumentZigbeeDevice: Object Name: " + strObjName);
522 System.out.println("DEBUG: InstrumentZigbeeDevice: Port number: " + commHan.getComPort(strZigbeeGWAddressKey));
523 System.out.println("DEBUG: InstrumentZigbeeDevice: Device address: " + strZigbeeGWAddress + "\n\n");
525 // Transfer the address
526 for(int iRow=0; iRow<iRows; iRow++) {
527 arrFieldValues = setInstrumenter.fieldValues(iRow);
528 // Get device address
529 String strZBDevAddress = (String) arrFieldValues[0];
530 // Send policy to Zigbee gateway - TODO: Need to clear policy first?
531 zbConfig.setPolicy(strIoTSlaveObjectHostAdd, commHan.getComPort(strZigbeeGWAddressKey), strZBDevAddress);
532 // Send address one by one
533 if(strLanguage.equals(STR_JAVA)) {
534 Message msgGetIoTSetZBObj = new MessageGetSimpleDeviceObject(IoTCommCode.GET_ZB_DEV_IOTSET_OBJECT, strZBDevAddress);
535 commMasterToSlave(msgGetIoTSetZBObj, "Get IoTSet objects!", inStream, outStream);
536 } else // TODO: Implement IoTSet Zigbee for C++
539 zbConfig.closeConnection();
540 // Reinitialize IoTSet on device object
541 commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTSET_FIELD), "Reinitialize IoTSet fields!", inStream, outStream);
546 * A private method to instrument IoTSet of addresses
548 * @params strFieldIdentifier String field name + object ID
549 * @params strFieldName String field name
550 * @params inStream ObjectInputStream communication
551 * @params inStream ObjectOutputStream communication
552 * @params strLanguage String language
555 private void instrumentIoTSetAddress(String strFieldIdentifier, String strFieldName,
556 InputStream inStream, OutputStream outStream, String strLanguage)
557 throws IOException, ClassNotFoundException, InterruptedException {
559 // Get information from the set
560 List<Object[]> listObject = objAddInitHand.getFields(strFieldIdentifier);
561 // Create a new IoTSet
562 if(strLanguage.equals(STR_JAVA)) {
563 Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, strFieldName);
564 commMasterToSlave(msgCrtIoTSet, "Create new IoTSet for IoTAddress!", inStream, outStream);
567 int iRows = listObject.size();
568 RuntimeOutput.print("IoTMaster: Number of rows for IoTAddress: " + iRows, BOOL_VERBOSE);
569 // Transfer the address
570 for(int iRow=0; iRow<iRows; iRow++) {
571 arrFieldValues = listObject.get(iRow);
572 // Get device address
573 String strAddress = (String) arrFieldValues[0];
574 // Send address one by one
575 if(strLanguage.equals(STR_JAVA)) {
576 Message msgGetIoTSetAddObj = new MessageGetSimpleDeviceObject(IoTCommCode.GET_ADD_IOTSET_OBJECT, strAddress);
577 commMasterToSlave(msgGetIoTSetAddObj, "Get IoTSet objects!", inStream, outStream);
578 } else // TODO: Implement IoTSet Address for C++
581 // Reinitialize IoTSet on device object
582 commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTSET_FIELD),
583 "Reinitialize IoTSet fields!", inStream, outStream);
588 * A private method to instrument an object on a specific machine and setting up policies
590 * @params strFieldObjectID String field object ID
591 * @params strObjControllerName String object controller name
592 * @params strLanguage String language
595 private void instrumentObject(String strFieldObjectID, String strObjControllerName, String strLanguage) throws IOException {
597 // Extract the interface name for RMI
598 // e.g. ProximitySensorInterface, TempSensorInterface, etc.
600 String strObjCfgFile = STR_IOT_CODE_PATH + strObjClassName + "/" + strObjClassName + STR_CFG_FILE_EXT;
601 strObjClassInterfaceName = parseConfigFile(strObjCfgFile, STR_INTERFACE_CLS_CFG);
602 strObjStubClsIntfaceName = parseConfigFile(strObjCfgFile, STR_INT_STUB_CLS_CFG);
603 // Create an object name, e.g. ProximitySensorImplPS1
604 strObjName = strObjClassName + strFieldObjectID;
605 // Check first if host exists
606 if(commHan.objectExists(strObjName)) {
607 // If this object exists already ...
608 // Re-read IoTSlave object hostname for further reference
609 strIoTSlaveObjectHostAdd = commHan.getHostAddress(strObjName);
610 RuntimeOutput.print("IoTMaster: Object with name: " + strObjName + " has existed!", BOOL_VERBOSE);
612 // If this is a new object ... then create one
613 // Get host address for IoTSlave from LoadBalancer
614 //strIoTSlaveObjectHostAdd = lbIoT.selectHost();
615 strIoTSlaveObjectHostAdd = routerConfig.getIPFromMACAddress(lbIoT.selectHost());
616 if (strIoTSlaveControllerHostAdd == null)
617 throw new Error("IoTMaster: Could not translate MAC to IP address! Please check the router's /tmp/dhcp.leases!");
618 RuntimeOutput.print("IoTMaster: Object name: " + strObjName, BOOL_VERBOSE);
619 // Add port connection and get port numbers
620 // Naming for objects ProximitySensor becomes ProximitySensor0, ProximitySensor1, etc.
621 commHan.addPortConnection(strIoTSlaveObjectHostAdd, strObjName);
622 commHan.addActiveControllerObject(strFieldObjectID, strObjName, strObjClassName, strObjClassInterfaceName,
623 strObjStubClsIntfaceName, strIoTSlaveObjectHostAdd, arrFieldValues, arrFieldClasses);
624 // ROUTING POLICY: IoTMaster and device/controller object
625 // Master-slave communication
626 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTMasterHostAdd,
627 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjName));
628 // ROUTING POLICY: Send the same routing policy to both the hosts
629 routerConfig.configureHostMainPolicies(strIoTMasterHostAdd, strIoTMasterHostAdd,
630 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjName));
631 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTMasterHostAdd,
632 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjName));
633 // Need to accommodate callback functions here - open ports for TCP
634 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveControllerHostAdd,
635 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
636 routerConfig.configureHostMainPolicies(strIoTSlaveControllerHostAdd, strIoTSlaveControllerHostAdd,
637 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
638 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveControllerHostAdd,
639 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
640 // Configure MAC policies for objects
641 //String strFileName = STR_MAC_POL_PATH + strObjClassName + STR_MAC_POLICY_EXT;
642 String strFileName = STR_MAC_POL_PATH + STR_JAVA + STR_MAC_POLICY_EXT;
643 if (STR_ACTIVATE_SANDBOXING.equals("Yes")) {
644 processJailConfig.configureProcessJailDeviceDriverPolicies(strIoTSlaveObjectHostAdd, strObjName, strObjClassName,
645 strFileName, strIoTMasterHostAdd, commHan.getComPort(strObjName), commHan.getRMIRegPort(strObjName),
646 commHan.getRMIStubPort(strObjName));
647 processJailConfig.configureProcessJailContRMIPolicies(strObjControllerName, strIoTSlaveObjectHostAdd,
648 commHan.getRMIRegPort(strObjName), commHan.getRMIStubPort(strObjName));
650 // Instrument the IoTSet declarations inside the class file
651 instrumentObjectIoTSet(strFieldObjectID, strLanguage);
653 // Send routing policy to router for controller object
654 // ROUTING POLICY: RMI communication - RMI registry and stub ports
655 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
656 STR_TCP_PROTOCOL, commHan.getRMIRegPort(strObjName));
657 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
658 STR_TCP_PROTOCOL, commHan.getRMIStubPort(strObjName));
659 // Send the same set of routing policies to compute nodes
660 routerConfig.configureHostMainPolicies(strIoTSlaveControllerHostAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
661 STR_TCP_PROTOCOL, commHan.getRMIRegPort(strObjName));
662 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
663 STR_TCP_PROTOCOL, commHan.getRMIRegPort(strObjName));
664 routerConfig.configureHostMainPolicies(strIoTSlaveControllerHostAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
665 STR_TCP_PROTOCOL, commHan.getRMIStubPort(strObjName));
666 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
667 STR_TCP_PROTOCOL, commHan.getRMIStubPort(strObjName));
672 * A private method to set router policies for IoTDeviceAddress objects
674 * @params strFieldIdentifier String field name + object ID
675 * @params Map.Entry<String,Object> Entry of map IoTSet instrumentation
676 * @params strIoTSlaveObjectHostAdd String slave host address
679 private void setRouterPolicyIoTSetDevice(String strFieldIdentifier, Map.Entry<String,Object> map,
680 String strIoTSlaveObjectHostAdd) {
682 // Get information from the set
683 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
684 int iRows = setInstrumenter.numberOfRows();
685 RuntimeOutput.print("IoTMaster: Number of rows for IoTDeviceAddress: " + iRows, BOOL_VERBOSE);
686 // Transfer the address
687 for(int iRow=0; iRow<iRows; iRow++) {
688 arrFieldValues = setInstrumenter.fieldValues(iRow);
689 objAddInitHand.addField(strFieldIdentifier, arrFieldValues); // Save this for object instantiation
690 // Get device address - if 00:00:00:00:00:00 that means it needs the driver object address (self)
691 String strDeviceAddress = null;
692 String strDeviceAddressKey = null;
693 if (arrFieldValues[0].equals(STR_SELF_MAC_ADD)) {
694 strDeviceAddress = strIoTSlaveObjectHostAdd;
695 strDeviceAddressKey = strObjName + "-" + strIoTSlaveObjectHostAdd;
696 } else { // Concatenate object name and IP address to give unique key - for a case where there is one device for multiple drivers
697 strDeviceAddress = routerConfig.getIPFromMACAddress((String) arrFieldValues[0]);
698 strDeviceAddressKey = strObjName + "-" + strDeviceAddress;
700 int iDestDeviceDriverPort = (int) arrFieldValues[1];
701 String strProtocol = (String) arrFieldValues[2];
702 // Add the port connection into communication handler - if it's not assigned yet
703 if (commHan.getComPort(strDeviceAddressKey) == null)
704 commHan.addPortConnection(strIoTSlaveObjectHostAdd, strDeviceAddressKey);
705 boolean bDstPortWildCard = false;
706 // Recognize this and allocate different ports for it
707 if (arrFieldValues.length > 3) {
708 bDstPortWildCard = (boolean) arrFieldValues[4];
709 if (bDstPortWildCard) { // This needs a unique source port
710 String strUniqueDev = strDeviceAddressKey + ":" + iRow;
711 commHan.addAdditionalPort(strUniqueDev);
716 System.out.println("\n\n DEBUG: InstrumentPolicySetDevice: Object Name: " + strObjName);
717 System.out.println("DEBUG: InstrumentPolicySetDevice: Port number: " + commHan.getComPort(strDeviceAddressKey));
718 System.out.println("DEBUG: InstrumentPolicySetDevice: Device address: " + strDeviceAddressKey + "\n\n");
720 // Send routing policy to router for device drivers and devices
721 // ROUTING POLICY: RMI communication - RMI registry and stub ports
722 if((iDestDeviceDriverPort == -1) && (!strProtocol.equals(STR_NO_PROTOCOL))) {
723 // Port number -1 means that we don't set the policy strictly to port number level
724 // "nopro" = no protocol specified for just TCP or just UDP (can be both used as well)
725 // ROUTING POLICY: Device driver and device
726 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveObjectHostAdd, strDeviceAddress, strProtocol);
727 // ROUTING POLICY: Send to the compute node where the device driver is
728 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress, strProtocol);
729 } else if((iDestDeviceDriverPort == -1) && (strProtocol.equals(STR_NO_PROTOCOL))) {
730 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveObjectHostAdd, strDeviceAddress);
731 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress);
732 } else if(strProtocol.equals(STR_TCPGW_PROTOCOL)) {
733 // This is a TCP protocol that connects, e.g. a phone to our runtime system
734 // that provides a gateway access (accessed through destination port number)
735 commHan.addDevicePort(iDestDeviceDriverPort);
736 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveObjectHostAdd, strDeviceAddress, STR_TCP_PROTOCOL, iDestDeviceDriverPort);
737 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress, STR_TCP_PROTOCOL, iDestDeviceDriverPort);
738 routerConfig.configureRouterHTTPPolicies(STR_ROUTER_ADD, strIoTSlaveObjectHostAdd, strDeviceAddress);
739 routerConfig.configureHostHTTPPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress);
740 // Configure MAC policies
741 if (STR_ACTIVATE_SANDBOXING.equals("Yes"))
742 processJailConfig.configureProcessJailGWDevicePolicies(strIoTSlaveObjectHostAdd, STR_ROUTER_ADD, INT_DNS_PORT);
744 // Other port numbers...
745 commHan.addDevicePort(iDestDeviceDriverPort);
746 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveObjectHostAdd, strDeviceAddress, strProtocol,
747 commHan.getComPort(strDeviceAddressKey), iDestDeviceDriverPort);
748 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress, strProtocol,
749 commHan.getComPort(strDeviceAddressKey), iDestDeviceDriverPort);
750 // Configure MAC policies
751 if (STR_ACTIVATE_SANDBOXING.equals("Yes"))
752 processJailConfig.configureProcessJailDevicePolicies(strIoTSlaveObjectHostAdd, strProtocol,
753 commHan.getComPort(strDeviceAddressKey), strDeviceAddress, iDestDeviceDriverPort);
759 * A private method to set router policies for IoTAddress objects
761 * @params strFieldIdentifier String field name + object ID
762 * @params Map.Entry<String,Object> Entry of map IoTSet instrumentation
763 * @params strHostAddress String host address
766 private void setRouterPolicyIoTSetAddress(String strFieldIdentifier, Map.Entry<String,Object> map,
767 String strHostAddress, String strControllerName) {
769 // Get information from the set
770 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
771 int iRows = setInstrumenter.numberOfRows();
772 RuntimeOutput.print("IoTMaster: Number of rows for IoTAddress: " + iRows, BOOL_VERBOSE);
773 // Transfer the address
774 for(int iRow=0; iRow<iRows; iRow++) {
775 arrFieldValues = setInstrumenter.fieldValues(iRow);
776 objAddInitHand.addField(strFieldIdentifier, arrFieldValues); // Save this for object instantiation
777 // Get device address
778 String strAddress = (String) arrFieldValues[0];
779 // Setting up router policies for HTTP/HTTPs
780 if (STR_ACTIVATE_SANDBOXING.equals("Yes")) {
781 if (strControllerName != null) {
782 processJailConfig.configureProcessJailInetAddressPolicies(strControllerName, STR_ROUTER_ADD, strAddress);
784 processJailConfig.configureProcessJailInetAddressPolicies(strHostAddress, STR_ROUTER_ADD, strAddress);
787 routerConfig.configureRouterHTTPPolicies(STR_ROUTER_ADD, strHostAddress, strAddress);
788 routerConfig.configureHostHTTPPolicies(strHostAddress, strHostAddress, strAddress);
793 * A private method to instrument an object's IoTSet and IoTRelation field to up policies
795 * Mostly the IoTSet fields would contain IoTDeviceAddress objects
797 * @params strFieldObjectID String field object ID
798 * @params strLanguage String language
801 private void instrumentObjectIoTSet(String strFieldObjectID, String strLanguage) throws IOException {
803 // If this is a new object ... then create one
804 // Instrument the class source code and look for IoTSet for device addresses
805 // e.g. @config private IoTSet<IoTDeviceAddress> lb_addresses;
806 HashMap<String,Object> hmObjectFieldObjects = null;
807 if(strLanguage.equals(STR_JAVA)) {
808 String strObjectClassNamePath = STR_IOT_CODE_PATH + strObjClassName + "/" + strObjClassName + STR_CLS_FILE_EXT;
809 FileInputStream fis = new FileInputStream(strObjectClassNamePath);
810 ClassReader cr = new ClassReader(fis);
811 ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
812 // We need Object ID to instrument IoTDeviceAddress
813 ClassRuntimeInstrumenterMaster crim = new ClassRuntimeInstrumenterMaster(cw, strFieldObjectID, BOOL_VERBOSE);
816 mapClassNameToCrim.put(strObjClassName + strFieldObjectID, crim);
817 hmObjectFieldObjects = crim.getFieldObjects();
819 String strObjectClassNamePath = STR_IOT_CODE_PATH + strObjClassName + "/" + strObjClassName + STR_CFG_FILE_EXT;
820 CRuntimeInstrumenterMaster crim = new CRuntimeInstrumenterMaster(strObjectClassNamePath, strFieldObjectID, BOOL_VERBOSE);
821 mapClassNameToCrim.put(strObjClassName + strFieldObjectID, crim);
822 hmObjectFieldObjects = crim.getFieldObjects();
824 // Get the object and the class names
825 // Build objects for IoTSet and IoTRelation fields in the device object classes
826 RuntimeOutput.print("IoTMaster: Going to instrument for " + strObjClassName + " with objectID " +
827 strFieldObjectID, BOOL_VERBOSE);
828 for(Map.Entry<String,Object> map : hmObjectFieldObjects.entrySet()) {
829 RuntimeOutput.print("IoTMaster: Object name: " + map.getValue().getClass().getName(), BOOL_VERBOSE);
830 // Iterate over HashMap and choose between processing
831 String strFieldName = map.getKey();
832 String strClassName = map.getValue().getClass().getName();
833 String strFieldIdentifier = strFieldName + strFieldObjectID;
834 if(strClassName.equals(STR_SET_INSTRUMENTER_CLS)) {
835 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
836 if(setInstrumenter.getObjTableName().equals(STR_IOT_DEV_ADD_CLS)) {
837 // Instrument the normal IoTDeviceAddress
838 setRouterPolicyIoTSetDevice(strFieldIdentifier, map, strIoTSlaveObjectHostAdd);
839 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ADD_CLS)) {
840 // Instrument the IoTAddress
841 setRouterPolicyIoTSetAddress(strFieldIdentifier, map, strIoTSlaveObjectHostAdd, null);
842 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ZB_ADD_CLS)) {
843 // Instrument the IoTZigbeeAddress - special feature for Zigbee device support
844 RuntimeOutput.print("IoTMaster: IoTZigbeeAddress found! No router policy is set here..",
847 String strErrMsg = "IoTMaster: Device driver object" +
848 " can only have IoTSet<IoTAddress>, IoTSet<IoTDeviceAddress>," +
849 " or IoTSet<IoTZigbeeAddress>!";
850 throw new Error(strErrMsg);
853 String strErrMsg = "IoTMaster: Device driver object can only have IoTSet for addresses!";
854 throw new Error(strErrMsg);
861 * A private method to send files to a Java slave driver
863 * @params serverSocket ServerSocket
864 * @params _inStream InputStream
865 * @params _outStream OutputStream
866 * @params strObjName String
867 * @params strObjClassName String
868 * @params strObjClassInterfaceName String
869 * @params strObjStubClsIntfaceName String
870 * @params strIoTSlaveObjectHostAdd String
871 * @params strFieldObjectID String
872 * @params arrFieldValues Object[]
873 * @params arrFieldClasses Class[]
876 private void sendFileToJavaSlaveDriver(ServerSocket serverSocket, InputStream _inStream, OutputStream _outStream,
877 String strObjName, String strObjClassName, String strObjClassInterfaceName, String strObjStubClsIntfaceName,
878 String strIoTSlaveObjectHostAdd, String strFieldObjectID, Object[] arrFieldValues, Class[] arrFieldClasses)
879 throws IOException, ClassNotFoundException {
881 ObjectInputStream inStream = (ObjectInputStream) _inStream;
882 ObjectOutputStream outStream = (ObjectOutputStream) _outStream;
883 // Create message to transfer file first
884 String sFileName = strObjClassName + STR_JAR_FILE_EXT;
885 String sPath = STR_IOT_CODE_PATH + strObjClassName + "/" + sFileName;
886 File file = new File(sPath);
887 commMasterToSlave(new MessageSendFile(IoTCommCode.TRANSFER_FILE, sFileName, file.length()),
888 "Sending file!", inStream, outStream);
889 // Send file - JAR file for object creation
890 sendFile(serverSocket.accept(), sPath, file.length());
891 Message msgReply = (Message) inStream.readObject();
892 RuntimeOutput.print("IoTMaster: Reply message: " + msgReply.getMessage(), BOOL_VERBOSE);
893 // Pack object information to create object on a IoTSlave
894 Message msgObjIoTSlave = new MessageCreateObject(IoTCommCode.CREATE_OBJECT, strIoTSlaveObjectHostAdd,
895 strObjClassName, strObjName, strObjClassInterfaceName, strObjStubClsIntfaceName, commHan.getRMIRegPort(strObjName),
896 commHan.getRMIStubPort(strObjName), arrFieldValues, arrFieldClasses);
898 commMasterToSlave(msgObjIoTSlave, "Sending object information", inStream, outStream);
903 * A private method to send files to a Java slave driver
907 private void sendFileToCppSlaveDriver(String strObjClassName, String strIoTSlaveObjectHostAdd)
908 throws IOException, ClassNotFoundException {
910 // Create message to transfer file first
911 String sFileName = strObjClassName + STR_ZIP_FILE_EXT;
912 String sFile = STR_IOT_CODE_PATH + strObjClassName + "/" + sFileName;
913 String strCmdSend = STR_SCP + " " + sFile + " " + STR_USERNAME + strIoTSlaveObjectHostAdd + ":" + STR_SLAVE_DIR;
914 runCommand(strCmdSend);
915 RuntimeOutput.print("IoTMaster: Executing: " + strCmdSend, BOOL_VERBOSE);
917 String strCmdUnzip = STR_SSH + " " + STR_USERNAME + strIoTSlaveObjectHostAdd + " cd " +
918 STR_SLAVE_DIR + " sudo unzip -o " + sFileName + ";";
919 runCommand(strCmdUnzip);
920 RuntimeOutput.print("IoTMaster: Executing: " + strCmdUnzip, BOOL_VERBOSE);
926 * Construct command line for Java IoTSlave
930 private String getCmdJavaDriverIoTSlave(String strIoTMasterHostAdd, String strIoTSlaveObjectHostAdd, String strObjName) {
932 // Create an Shell executable
933 String strJavaCommand = STR_SHELL_HEADER + "\nexec " + STR_JAVA_PATH + " " + STR_CLS_PATH + " " + STR_RMI_PATH + " " +
934 STR_RMI_HOSTNAME + strIoTSlaveObjectHostAdd + " " + STR_IOT_SLAVE_CLS + " " + strIoTMasterHostAdd + " " +
935 commHan.getComPort(strObjName) + " " + commHan.getRMIRegPort(strObjName) + " " +
936 commHan.getRMIStubPort(strObjName) + " > " + STR_LOG_FILE_PATH + strObjName + ".log &";
937 String shellFile = "./" + strObjName + STR_SHELL_FILE_EXT;
938 createWrapperShellScript(strJavaCommand, shellFile);
939 // Send the file to the compute node
940 String strCmdSend = "scp " + shellFile + " " + STR_USERNAME + strIoTSlaveObjectHostAdd + ":" + STR_RUNTIME_DIR;
941 runCommand(strCmdSend);
942 System.out.println("IoTMaster: Sending shell file: " + strCmdSend);
943 return STR_SSH + " " + STR_USERNAME + strIoTSlaveObjectHostAdd + " cd " + STR_RUNTIME_DIR + " " + shellFile;
948 * Construct command line for C++ IoTSlave
952 private String getCmdCppDriverIoTSlave(String strIoTMasterHostAdd, String strIoTSlaveObjectHostAdd, String strObjName) {
954 return STR_SSH + " " + STR_USERNAME + strIoTSlaveObjectHostAdd + " cd " +
955 STR_SLAVE_DIR + " sudo " + STR_IOTSLAVE_CPP + " " + strIoTMasterHostAdd + " " +
956 commHan.getComPort(strObjName) + " " + strObjName;
961 * createWrapperShellScript() gets a wrapper shell script
963 * @param strCommand String command
964 * @param strObjectName String object name
965 * @return PrintWriter
967 private void createWrapperShellScript(String strCommand, String strFileName) {
969 PrintWriter printWriter = getPrintWriter(strFileName);
970 printWriter.println(strCommand);
972 runCommand("chmod 755 " + strFileName);
977 * A private method to create an object on a specific machine
979 * @params strObjName String object name
980 * @params strObjClassName String object class name
981 * @params strObjClassInterfaceName String object class interface name
982 * @params strIoTSlaveObjectHostAdd String IoTSlave host address
983 * @params strFieldObjectID String field object ID
984 * @params arrFieldValues Array of field values
985 * @params arrFieldClasses Array of field classes
988 private void createObject(String strObjName, String strObjClassName, String strObjClassInterfaceName, String strObjStubClsIntfaceName,
989 String strIoTSlaveObjectHostAdd, String strFieldObjectID, Object[] arrFieldValues, Class[] arrFieldClasses)
990 throws IOException, FileNotFoundException, ClassNotFoundException, InterruptedException {
993 String sCfgFile = STR_IOT_CODE_PATH + strObjClassName + "/" + strObjClassName + STR_CFG_FILE_EXT;
994 String strLanguageDriver = parseConfigFile(sCfgFile, STR_LANGUAGE + "_" + strObjName);
995 if(strLanguageDriver == null) // Read just the field LANGUAGE if the first read is null
996 strLanguageDriver = parseConfigFile(sCfgFile, STR_LANGUAGE);
997 if(strLanguageDriver == null) // Check nullness for the second time - report if it is still null
998 throw new Error("IoTMaster: Language specification missing in config file: " + sCfgFile);
1003 start = System.currentTimeMillis();
1005 // Construct ssh command line
1006 // e.g. ssh rtrimana@dw-2.eecs.uci.edu cd <path>;
1007 // java -cp $CLASSPATH:./*.jar
1008 // -Djava.rmi.server.codebase=file:./*.jar
1009 // iotruntime.IoTSlave dw-1.eecs.uci.edu 46151 23829 42874 &
1010 // The In-Port for IoTMaster is the Out-Port for IoTSlave and vice versa
1011 String strSSHCommand = null;
1012 if(strLanguageDriver.equals(STR_JAVA))
1013 strSSHCommand = getCmdJavaDriverIoTSlave(strIoTMasterHostAdd, strIoTSlaveObjectHostAdd, strObjName);
1014 else if(strLanguageDriver.equals(STR_CPP))
1015 strSSHCommand = getCmdCppDriverIoTSlave(strIoTMasterHostAdd, strIoTSlaveObjectHostAdd, strObjName);
1017 throw new Error("IoTMaster: Language specification not recognized: " + strLanguageDriver);
1018 RuntimeOutput.print("IoTMaster: Language for " + strObjName + " is " + strLanguageDriver, BOOL_VERBOSE);
1020 RuntimeOutput.print(strSSHCommand, BOOL_VERBOSE);
1021 // Start a new thread to start a new JVM
1022 createThread(strSSHCommand);
1023 ServerSocket serverSocket = new ServerSocket(commHan.getComPort(strObjName));
1024 Socket socket = serverSocket.accept();
1025 //InputStream inStream = new ObjectInputStream(socket.getInputStream());
1026 //OutputStream outStream = new ObjectOutputStream(socket.getOutputStream());
1027 InputStream inStream = null;
1028 OutputStream outStream = null;
1029 if(strLanguageDriver.equals(STR_JAVA)) {
1030 inStream = new ObjectInputStream(socket.getInputStream());
1031 outStream = new ObjectOutputStream(socket.getOutputStream());
1032 } else { // At this point the language is certainly C++, otherwise would've complained above
1033 inStream = new BufferedInputStream(socket.getInputStream());
1034 outStream = new BufferedOutputStream(socket.getOutputStream());
1039 result = System.currentTimeMillis()-start;
1040 System.out.println("\n\n ==> Time needed to start JVM for " + strObjName + ": " + result + "\n\n");
1043 start = System.currentTimeMillis();
1045 if(strLanguageDriver.equals(STR_JAVA)) {
1046 sendFileToJavaSlaveDriver(serverSocket, inStream, outStream, strObjName,
1047 strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName,
1048 strIoTSlaveObjectHostAdd, strFieldObjectID, arrFieldValues, arrFieldClasses);
1050 sendFileToCppSlaveDriver(strObjClassName, strIoTSlaveObjectHostAdd);
1051 createObjectCpp(strObjName, strObjClassName, strObjClassInterfaceName, strIoTSlaveObjectHostAdd,
1052 commHan.getRMIRegPort(strObjName), commHan.getRMIStubPort(strObjName), arrFieldValues, arrFieldClasses,
1053 outStream, inStream);
1057 result = System.currentTimeMillis()-start;
1058 System.out.println("\n\n ==> Time needed to send JAR file for " + strObjName + ": " + result + "\n\n");
1061 start = System.currentTimeMillis();
1063 // Instrument the class source code and look for IoTSet for device addresses
1064 // e.g. @config private IoTSet<IoTDeviceAddress> lb_addresses;
1065 RuntimeOutput.print("IoTMaster: Instantiating for " + strObjClassName + " with objectID " + strFieldObjectID, BOOL_VERBOSE);
1066 // Get the object and the class names
1067 // Build objects for IoTSet and IoTRelation fields in the device object classes
1068 Object crimObj = mapClassNameToCrim.get(strObjClassName + strFieldObjectID);
1069 HashMap<String,Object> hmObjectFieldObjects = null;
1070 if (crimObj instanceof ClassRuntimeInstrumenterMaster) {
1071 ClassRuntimeInstrumenterMaster crim = (ClassRuntimeInstrumenterMaster) crimObj;
1072 hmObjectFieldObjects = crim.getFieldObjects();
1073 } else if (crimObj instanceof CRuntimeInstrumenterMaster) {
1074 CRuntimeInstrumenterMaster crim = (CRuntimeInstrumenterMaster) crimObj;
1075 hmObjectFieldObjects = crim.getFieldObjects();
1077 for(Map.Entry<String,Object> map : hmObjectFieldObjects.entrySet()) {
1078 RuntimeOutput.print("IoTMaster: Object name: " + map.getValue().getClass().getName(), BOOL_VERBOSE);
1079 // Iterate over HashMap and choose between processing
1080 String strFieldName = map.getKey();
1081 String strClassName = map.getValue().getClass().getName();
1082 String strFieldIdentifier = strFieldName + strFieldObjectID;
1083 if(strClassName.equals(STR_SET_INSTRUMENTER_CLS)) {
1084 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
1085 if(setInstrumenter.getObjTableName().equals(STR_IOT_DEV_ADD_CLS)) {
1086 // Instrument the normal IoTDeviceAddress
1087 synchronized(this) {
1088 instrumentIoTSetDevice(strFieldIdentifier, strObjName, strFieldName, strIoTSlaveObjectHostAdd, inStream, outStream, strLanguageDriver);
1090 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ZB_ADD_CLS)) {
1091 // Instrument the IoTZigbeeAddress - special feature for Zigbee device support
1092 synchronized(this) {
1093 instrumentIoTSetZBDevice(map, strObjName, strFieldName, strIoTSlaveObjectHostAdd, inStream, outStream, strLanguageDriver);
1095 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ADD_CLS)) {
1096 // Instrument the IoTAddress
1097 synchronized(this) {
1098 instrumentIoTSetAddress(strFieldIdentifier, strFieldName, inStream, outStream, strLanguageDriver);
1101 String strErrMsg = "IoTMaster: Device driver object can only have IoTSet<IoTAddress>, IoTSet<IoTDeviceAddress>," +
1102 " or IoTSet<IoTZigbeeAddress>!";
1103 throw new Error(strErrMsg);
1106 String strErrMsg = "IoTMaster: Device driver object can only have IoTSet for addresses!";
1107 throw new Error(strErrMsg);
1111 // TODO: Change this later
1112 if(strLanguageDriver.equals(STR_JAVA)) {
1113 ObjectOutputStream oStream = (ObjectOutputStream) outStream;
1114 oStream.writeObject(new MessageSimple(IoTCommCode.END_SESSION));
1115 } else { // C++ side for now will be running continuously because it's an infinite loop (not in a separate thread)
1116 createDriverObjectCpp(outStream, inStream);
1117 //endSessionCpp(outStream);
1121 result = System.currentTimeMillis()-start;
1122 System.out.println("\n\n ==> Time needed to create object " + strObjName + " and instrument IoTDeviceAddress: " + result + "\n\n");
1128 serverSocket.close();
1133 * A private method to create controller objects
1137 private void createDriverObjects() throws InterruptedException {
1139 // Create a list of threads
1140 List<Thread> threads = new ArrayList<Thread>();
1141 // Get the list of active controller objects and loop it
1142 List<String> listActiveControllerObject = commHan.getActiveControllerObjectList();
1143 for(String strObjName : listActiveControllerObject) {
1145 ObjectCreationInfo objCrtInfo = commHan.getObjectCreationInfo(strObjName);
1146 Thread objectThread = new Thread(new Runnable() {
1148 synchronized(this) {
1150 createObject(strObjName, objCrtInfo.getObjectClassName(), objCrtInfo.getObjectClassInterfaceName(),
1151 objCrtInfo.getObjectStubClassInterfaceName(), objCrtInfo.getIoTSlaveObjectHostAdd(),
1152 commHan.getFieldObjectID(strObjName), commHan.getArrayFieldValues(strObjName),
1153 commHan.getArrayFieldClasses(strObjName));
1154 } catch (IOException |
1155 ClassNotFoundException |
1156 InterruptedException ex) {
1157 ex.printStackTrace();
1162 threads.add(objectThread);
1163 objectThread.start();
1166 for (Thread thread : threads) {
1169 } catch (InterruptedException ex) {
1170 ex.printStackTrace();
1177 * A private method to instrument IoTSet
1179 * @params Map.Entry<String,Object> Entry of map IoTSet instrumentation
1180 * @params strFieldName String field name
1181 * @params strLanguage String language
1184 private void instrumentIoTSet(Map.Entry<String,Object> map, String strFieldName, String strObjControllerName, String strLanguage)
1185 throws IOException, ClassNotFoundException, InterruptedException {
1187 // Get information from the set
1188 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
1189 objInitHand.addField(strFieldName, IoTCommCode.CREATE_NEW_IOTSET);
1191 int iRows = setInstrumenter.numberOfRows();
1192 for(int iRow=0; iRow<iRows; iRow++) {
1193 // Get field classes and values
1194 arrFieldClasses = setInstrumenter.fieldClasses(iRow);
1195 arrFieldValues = setInstrumenter.fieldValues(iRow);
1196 // Get object ID and class name
1197 String strObjID = setInstrumenter.fieldObjectID(iRow);
1198 strObjClassName = setInstrumenter.fieldEntryType(strObjID);
1199 // Call the method to create an object
1200 instrumentObject(strObjID, strObjControllerName, strLanguage);
1201 objInitHand.addObjectIntoField(strFieldName, strIoTSlaveObjectHostAdd, strObjName,
1202 strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName, commHan.getRMIRegPort(strObjName),
1203 commHan.getRMIStubPort(strObjName));
1209 * A private method to instrument IoTRelation
1211 * @params Map.Entry<String,Object> Entry of map IoTRelation instrumentation
1212 * @params strFieldName String field name
1213 * @params strLanguage String language
1216 private void instrumentIoTRelation(Map.Entry<String,Object> map, String strFieldName, String strObjControllerName, String strLanguage)
1217 throws IOException, ClassNotFoundException, InterruptedException {
1219 // Get information from the set
1220 RelationInstrumenter relationInstrumenter = (RelationInstrumenter) map.getValue();
1221 int iRows = relationInstrumenter.numberOfRows();
1222 objInitHand.addField(strFieldName, IoTCommCode.CREATE_NEW_IOTRELATION);
1224 for(int iRow=0; iRow<iRows; iRow++) {
1225 // Operate on the first set first
1226 arrFieldClasses = relationInstrumenter.firstFieldClasses(iRow);
1227 arrFieldValues = relationInstrumenter.firstFieldValues(iRow);
1228 String strObjID = relationInstrumenter.firstFieldObjectID(iRow);
1229 strObjClassName = relationInstrumenter.firstEntryFieldType(strObjID);
1230 // Call the method to create an object
1231 instrumentObject(strObjID, strObjControllerName, strLanguage);
1232 // Get the first object controller host address
1233 String strFirstIoTSlaveObjectHostAdd = strIoTSlaveObjectHostAdd;
1234 objInitHand.addObjectIntoField(strFieldName, strIoTSlaveObjectHostAdd, strObjName,
1235 strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName,
1236 commHan.getRMIRegPort(strObjName), commHan.getRMIStubPort(strObjName));
1237 // Operate on the second set
1238 arrFieldClasses = relationInstrumenter.secondFieldClasses(iRow);
1239 arrFieldValues = relationInstrumenter.secondFieldValues(iRow);
1240 strObjID = relationInstrumenter.secondFieldObjectID(iRow);
1241 strObjClassName = relationInstrumenter.secondEntryFieldType(strObjID);
1242 // Call the method to create an object
1243 instrumentObject(strObjID, strObjControllerName, strLanguage);
1244 // Get the second object controller host address
1245 String strSecondIoTSlaveObjectHostAdd = strIoTSlaveObjectHostAdd;
1246 objInitHand.addSecondObjectIntoField(strFieldName, strIoTSlaveObjectHostAdd, strObjName,
1247 strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName,
1248 commHan.getRMIRegPort(strObjName), commHan.getRMIStubPort(strObjName));
1249 // ROUTING POLICY: first and second controller objects in IoTRelation
1250 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strFirstIoTSlaveObjectHostAdd,
1251 strSecondIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
1252 // ROUTING POLICY: Send the same routing policy to both the hosts
1253 routerConfig.configureHostMainPolicies(strFirstIoTSlaveObjectHostAdd, strFirstIoTSlaveObjectHostAdd,
1254 strSecondIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
1255 routerConfig.configureHostMainPolicies(strSecondIoTSlaveObjectHostAdd, strFirstIoTSlaveObjectHostAdd,
1256 strSecondIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
1261 * A method to reinitialize IoTSet and IoTRelation in the code based on ObjectInitHandler information
1263 * @params inStream ObjectInputStream communication
1264 * @params outStream ObjectOutputStream communication
1267 private void initializeSetsAndRelationsJava(InputStream inStream, OutputStream outStream)
1268 throws IOException, ClassNotFoundException {
1269 // Get list of fields
1270 List<String> strFields = objInitHand.getListOfFields();
1271 // Iterate on HostAddress
1272 for(String str : strFields) {
1273 IoTCommCode iotcommMsg = objInitHand.getFieldMessage(str);
1274 if (iotcommMsg == IoTCommCode.CREATE_NEW_IOTSET) {
1275 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO CREATE IOTSET
1276 Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, str);
1277 commMasterToSlave(msgCrtIoTSet, "Create new IoTSet!", inStream, outStream);
1278 List<ObjectInitInfo> listObject = objInitHand.getListObjectInitInfo(str);
1279 for (ObjectInitInfo objInitInfo : listObject) {
1280 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTSET
1281 commMasterToSlave(new MessageGetObject(IoTCommCode.GET_IOTSET_OBJECT, objInitInfo.getIoTSlaveObjectHostAdd(),
1282 objInitInfo.getObjectName(), objInitInfo.getObjectClassName(), objInitInfo.getObjectClassInterfaceName(),
1283 objInitInfo.getObjectStubClassInterfaceName(), objInitInfo.getRMIRegistryPort(), objInitInfo.getRMIStubPort()),
1284 "Get IoTSet object!", inStream, outStream);
1287 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO REINITIALIZE IOTSET FIELD
1288 commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTSET_FIELD),
1289 "Renitialize IoTSet field!", inStream, outStream);
1290 } else if (iotcommMsg == IoTCommCode.CREATE_NEW_IOTRELATION) {
1291 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO CREATE IOTRELATION
1292 Message msgCrtIoTRel = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTRELATION, str);
1293 commMasterToSlave(msgCrtIoTRel, "Create new IoTRelation!", inStream, outStream);
1294 List<ObjectInitInfo> listObject = objInitHand.getListObjectInitInfo(str);
1295 List<ObjectInitInfo> listSecondObject = objInitHand.getSecondObjectInitInfo(str);
1296 Iterator it = listSecondObject.iterator();
1297 for (ObjectInitInfo objInitInfo : listObject) {
1298 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTRELATION (FIRST OBJECT)
1299 commMasterToSlave(new MessageGetObject(IoTCommCode.GET_IOTRELATION_FIRST_OBJECT,
1300 objInitInfo.getIoTSlaveObjectHostAdd(), objInitInfo.getObjectName(), objInitInfo.getObjectClassName(),
1301 objInitInfo.getObjectClassInterfaceName(), objInitInfo.getObjectStubClassInterfaceName(),
1302 objInitInfo.getRMIRegistryPort(), objInitInfo.getRMIStubPort()),
1303 "Get IoTRelation first object!", inStream, outStream);
1304 ObjectInitInfo objSecObj = (ObjectInitInfo) it.next();
1305 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTRELATION (SECOND OBJECT)
1306 commMasterToSlave(new MessageGetObject(IoTCommCode.GET_IOTRELATION_SECOND_OBJECT,
1307 objSecObj.getIoTSlaveObjectHostAdd(), objSecObj.getObjectName(), objSecObj.getObjectClassName(),
1308 objSecObj.getObjectClassInterfaceName(), objSecObj.getObjectStubClassInterfaceName(),
1309 objSecObj.getRMIRegistryPort(), objSecObj.getRMIStubPort()),
1310 "Get IoTRelation second object!", inStream, outStream);
1312 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO REINITIALIZE IOTRELATION FIELD
1313 commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTRELATION_FIELD),
1314 "Renitialize IoTRelation field!", inStream, outStream);
1320 * A method to reinitialize IoTSet and IoTRelation in the code based on ObjectInitHandler information
1322 * @params inStream ObjectInputStream communication
1323 * @params outStream ObjectOutputStream communication
1326 private void initializeSetsAndRelationsCpp(InputStream inStream, OutputStream outStream)
1327 throws IOException, ClassNotFoundException {
1328 // Get list of fields
1329 List<String> strFields = objInitHand.getListOfFields();
1330 // Iterate on HostAddress
1331 for(String str : strFields) {
1332 IoTCommCode iotcommMsg = objInitHand.getFieldMessage(str);
1333 if (iotcommMsg == IoTCommCode.CREATE_NEW_IOTSET) {
1334 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO CREATE IOTSET
1335 createNewIoTSetCpp(str, outStream, inStream);
1336 List<ObjectInitInfo> listObject = objInitHand.getListObjectInitInfo(str);
1337 for (ObjectInitInfo objInitInfo : listObject) {
1338 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTSET
1339 getIoTSetRelationObjectCpp(IoTCommCode.GET_IOTSET_OBJECT, objInitInfo.getIoTSlaveObjectHostAdd(), objInitInfo.getObjectName(),
1340 objInitInfo.getObjectClassName(), objInitInfo.getObjectClassInterfaceName(), objInitInfo.getObjectStubClassInterfaceName(),
1341 objInitInfo.getRMIRegistryPort(), objInitInfo.getRMIStubPort(), outStream, inStream);
1343 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO REINITIALIZE IOTSET FIELD
1344 reinitializeIoTSetFieldCpp(outStream, inStream);
1345 } else if (iotcommMsg == IoTCommCode.CREATE_NEW_IOTRELATION) {
1346 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO CREATE IOTRELATION
1347 // TODO: createNewIoTRelation needs to be created here!
1348 createNewIoTRelationCpp(str, outStream, inStream);
1349 List<ObjectInitInfo> listObject = objInitHand.getListObjectInitInfo(str);
1350 List<ObjectInitInfo> listSecondObject = objInitHand.getSecondObjectInitInfo(str);
1351 Iterator it = listSecondObject.iterator();
1352 for (ObjectInitInfo objInitInfo : listObject) {
1353 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTRELATION (FIRST OBJECT)
1354 getIoTSetRelationObjectCpp(IoTCommCode.GET_IOTRELATION_FIRST_OBJECT, objInitInfo.getIoTSlaveObjectHostAdd(), objInitInfo.getObjectName(),
1355 objInitInfo.getObjectClassName(), objInitInfo.getObjectClassInterfaceName(), objInitInfo.getObjectStubClassInterfaceName(),
1356 objInitInfo.getRMIRegistryPort(), objInitInfo.getRMIStubPort(), outStream, inStream);
1357 ObjectInitInfo objSecObj = (ObjectInitInfo) it.next();
1358 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTRELATION (SECOND OBJECT)
1359 getIoTSetRelationObjectCpp(IoTCommCode.GET_IOTRELATION_SECOND_OBJECT, objSecObj.getIoTSlaveObjectHostAdd(), objSecObj.getObjectName(),
1360 objSecObj.getObjectClassName(), objSecObj.getObjectClassInterfaceName(), objSecObj.getObjectStubClassInterfaceName(),
1361 objSecObj.getRMIRegistryPort(), objSecObj.getRMIStubPort(), outStream, inStream);
1363 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO REINITIALIZE IOTRELATION FIELD
1364 reinitializeIoTRelationFieldCpp(outStream, inStream);
1370 * A method to set router basic policies at once
1372 * @param strRouter String router name
1375 private void setRouterBasicPolicies(String strRouter) {
1377 String strMonitorHost = routerConfig.getIPFromMACAddress(STR_MONITORING_HOST);
1378 routerConfig.configureRouterICMPPolicies(strRouter, strMonitorHost);
1379 routerConfig.configureRouterDHCPPolicies(strRouter);
1380 routerConfig.configureRouterDNSPolicies(strRouter);
1381 routerConfig.configureRouterSSHPolicies(strRouter, strMonitorHost);
1382 routerConfig.configureRejectPolicies(strRouter);
1386 * A method to set host basic policies at once
1388 * @param strHost String host name
1391 private void setHostBasicPolicies(String strHost) {
1393 String strMonitorHost = routerConfig.getIPFromMACAddress(STR_MONITORING_HOST);
1394 routerConfig.configureHostDHCPPolicies(strHost);
1395 routerConfig.configureHostDNSPolicies(strHost);
1396 if (strHost.equals(strMonitorHost)) {
1397 // Check if this is the monitoring host
1398 routerConfig.configureHostICMPPolicies(strHost);
1399 routerConfig.configureHostSSHPolicies(strHost);
1401 routerConfig.configureHostICMPPolicies(strHost, strMonitorHost);
1402 routerConfig.configureHostSSHPolicies(strHost, strMonitorHost);
1404 // Apply SQL allowance policies to master host
1405 if (strHost.equals(strIoTMasterHostAdd)) {
1406 routerConfig.configureHostSQLPolicies(strHost);
1408 routerConfig.configureRejectPolicies(strHost);
1412 * A method to create a thread for policy deployment
1414 * @param strRouterAddress String router address to configure
1415 * @param setHostAddresses Set of strings for host addresses to configure
1418 private void createPolicyThreads(String strRouterAddress, Set<String> setHostAddresses) throws IOException {
1420 // Create a list of threads
1421 List<Thread> threads = new ArrayList<Thread>();
1422 // Start threads for hosts
1423 for(String strAddress : setHostAddresses) {
1424 Thread policyThread = new Thread(new Runnable() {
1426 synchronized(this) {
1427 routerConfig.sendHostPolicies(strAddress);
1431 threads.add(policyThread);
1432 policyThread.start();
1433 RuntimeOutput.print("Deploying policies for: " + strAddress, BOOL_VERBOSE);
1435 // A thread for router
1436 Thread policyThread = new Thread(new Runnable() {
1438 synchronized(this) {
1439 routerConfig.sendRouterPolicies(strRouterAddress);
1443 threads.add(policyThread);
1444 policyThread.start();
1445 RuntimeOutput.print("Deploying policies on router: " + strRouterAddress, BOOL_VERBOSE);
1447 for (Thread thread : threads) {
1450 } catch (InterruptedException ex) {
1451 ex.printStackTrace();
1457 * A method to create a thread for policy deployment
1459 * @param setHostAddresses Set of strings for host addresses to configure
1462 private void createMACPolicyThreads(Set<String> setHostAddresses) throws IOException {
1464 // Create a list of threads
1465 List<Thread> threads = new ArrayList<Thread>();
1466 // Start threads for hosts
1467 for(String strAddress : setHostAddresses) {
1468 Thread policyThread = new Thread(new Runnable() {
1470 synchronized(this) {
1471 processJailConfig.sendMACPolicies(strAddress);
1475 threads.add(policyThread);
1476 policyThread.start();
1477 RuntimeOutput.print("Deploying MAC policies for: " + strAddress, BOOL_VERBOSE);
1480 for (Thread thread : threads) {
1483 } catch (InterruptedException ex) {
1484 ex.printStackTrace();
1491 * A method to send files to Java IoTSlave
1493 * @params strObjControllerName String
1494 * @params serverSocket ServerSocket
1495 * @params inStream ObjectInputStream communication
1496 * @params outStream ObjectOutputStream communication
1499 private void sendFileToJavaSlave(String strObjControllerName, ServerSocket serverSocket,
1500 InputStream _inStream, OutputStream _outStream) throws IOException, ClassNotFoundException {
1502 ObjectInputStream inStream = (ObjectInputStream) _inStream;
1503 ObjectOutputStream outStream = (ObjectOutputStream) _outStream;
1505 String strControllerJarName = strObjControllerName + STR_JAR_FILE_EXT;
1506 String strControllerJarNamePath = STR_CONT_PATH + strObjControllerName + "/" +
1507 strControllerJarName;
1508 File file = new File(strControllerJarNamePath);
1509 commMasterToSlave(new MessageSendFile(IoTCommCode.TRANSFER_FILE, strControllerJarName, file.length()),
1510 "Sending file!", inStream, outStream);
1511 // Send file - Class file for object creation
1512 sendFile(serverSocket.accept(), strControllerJarNamePath, file.length());
1513 Message msgReply = (Message) inStream.readObject();
1514 RuntimeOutput.print("IoTMaster: Reply message: " + msgReply.getMessage(), BOOL_VERBOSE);
1515 // Send .zip file if additional zip file is specified
1516 String strObjCfgFile = strObjControllerName + STR_CFG_FILE_EXT;
1517 String strObjCfgFilePath = STR_CONT_PATH + strObjControllerName + "/" + strObjCfgFile;
1518 String strAdditionalFile = parseConfigFile(strObjCfgFilePath, STR_FILE_TRF_CFG);
1519 if (strAdditionalFile.equals(STR_YES)) {
1520 String strControllerCmpName = strObjControllerName + STR_ZIP_FILE_EXT;
1521 String strControllerCmpNamePath = STR_CONT_PATH + strObjControllerName + "/" +
1522 strControllerCmpName;
1523 file = new File(strControllerCmpNamePath);
1524 commMasterToSlave(new MessageSendFile(IoTCommCode.TRANSFER_FILE, strControllerCmpName, file.length()),
1525 "Sending file!", inStream, outStream);
1526 // Send file - Class file for object creation
1527 sendFile(serverSocket.accept(), strControllerCmpNamePath, file.length());
1528 msgReply = (Message) inStream.readObject();
1529 RuntimeOutput.print("IoTMaster: Reply message: " + msgReply.getMessage(), BOOL_VERBOSE);
1535 * A method to send files to C++ IoTSlave
1538 * TODO: Need to look into this (as of now, file transferred retains the "data" format,
1539 * hence it is unreadable from outside world
1541 private void sendFileToCppSlave(String sFilePath, String sFileName, Socket fileSocket,
1542 InputStream inStream, OutputStream outStream) throws IOException {
1544 sendCommCode(IoTCommCode.TRANSFER_FILE, outStream, inStream);
1546 sendString(sFileName, outStream); recvAck(inStream);
1547 File file = new File(sFilePath + sFileName);
1548 int iFileLen = toIntExact(file.length());
1549 RuntimeOutput.print("IoTMaster: Sending file " + sFileName + " with length " + iFileLen + " bytes...", BOOL_VERBOSE);
1551 sendInteger(iFileLen, outStream); recvAck(inStream);
1552 RuntimeOutput.print("IoTMaster: Sent file size!", BOOL_VERBOSE);
1553 byte[] bytFile = new byte[iFileLen];
1554 InputStream inFileStream = new FileInputStream(file);
1555 RuntimeOutput.print("IoTMaster: Opened file!", BOOL_VERBOSE);
1557 OutputStream outFileStream = fileSocket.getOutputStream();
1558 RuntimeOutput.print("IoTMaster: Got output stream!", BOOL_VERBOSE);
1560 while ((iCount = inFileStream.read(bytFile)) > 0) {
1561 outFileStream.write(bytFile, 0, iCount);
1563 RuntimeOutput.print("IoTMaster: File sent!", BOOL_VERBOSE);
1569 * A method to send files to C++ IoTSlave (now master using Process() to start
1570 * file transfer using scp)
1574 private void sendFileToCppSlave(String sFilePath, String sFileName) throws IOException {
1576 // Construct shell command to transfer file
1577 String sFile = sFilePath + sFileName;
1578 String strCmdSend = STR_SCP + " " + sFile + " " + STR_USERNAME + strIoTSlaveControllerHostAdd + ":" + STR_SLAVE_DIR;
1579 runCommand(strCmdSend);
1580 RuntimeOutput.print("IoTMaster: Executing: " + strCmdSend, BOOL_VERBOSE);
1582 String strCmdUnzip = STR_SSH + " " + STR_USERNAME + strIoTSlaveControllerHostAdd + " cd " +
1583 STR_SLAVE_DIR + " sudo unzip -o " + sFileName + ";";
1584 runCommand(strCmdUnzip);
1585 RuntimeOutput.print("IoTMaster: Executing: " + strCmdUnzip, BOOL_VERBOSE);
1590 * runCommand() method runs shell command
1592 * @param strCommand String that contains command line
1595 private void runCommand(String strCommand) {
1598 Runtime runtime = Runtime.getRuntime();
1599 Process process = runtime.exec(strCommand);
1601 } catch (IOException ex) {
1602 System.out.println("RouterConfig: IOException: " + ex.getMessage());
1603 ex.printStackTrace();
1604 } catch (InterruptedException ex) {
1605 System.out.println("RouterConfig: InterruptException: " + ex.getMessage());
1606 ex.printStackTrace();
1612 * Construct command line for Java IoTSlave
1616 private String getCmdJavaIoTSlave(String strObjControllerName) {
1618 // Create an Shell executable
1619 String strJavaCommand = STR_SHELL_HEADER + "\nexec " + STR_JAVA_PATH + " " + STR_JVM_INIT_HEAP_SIZE + " " +
1620 STR_JVM_MAX_HEAP_SIZE + " " + STR_CLS_PATH + " " + STR_RMI_PATH + " " + STR_IOT_SLAVE_CLS + " " +
1621 strIoTMasterHostAdd + " " + commHan.getComPort(strObjControllerName) + " " +
1622 commHan.getRMIRegPort(strObjControllerName) + " " + commHan.getRMIStubPort(strObjControllerName) +
1623 " > " + STR_LOG_FILE_PATH + strObjControllerName + ".log &";
1624 String shellFile = "./" + strObjControllerName + STR_SHELL_FILE_EXT;
1625 createWrapperShellScript(strJavaCommand, shellFile);
1626 // Send the file to the compute node
1627 String strCmdSend = "scp " + shellFile + " " + STR_USERNAME + strIoTSlaveControllerHostAdd + ":" + STR_RUNTIME_DIR;
1628 runCommand(strCmdSend);
1629 System.out.println("IoTMaster: Sending main controller shell file: " + strCmdSend);
1630 return STR_SSH + " " + STR_USERNAME + strIoTSlaveControllerHostAdd + " cd " + STR_RUNTIME_DIR + " " + shellFile;
1635 * Construct command line for C++ IoTSlave
1639 private String getCmdCppIoTSlave(String strObjControllerName) {
1641 return STR_SSH + " " + STR_USERNAME + strIoTSlaveControllerHostAdd + " cd " +
1642 STR_SLAVE_DIR + " sudo " + STR_IOTSLAVE_CPP + " " + strIoTMasterHostAdd + " " +
1643 commHan.getComPort(strObjControllerName) + " " + strObjControllerName;
1648 * sendInteger() sends an integer in bytes
1650 public void sendInteger(int intSend, OutputStream outStream) throws IOException {
1652 BufferedOutputStream output = (BufferedOutputStream) outStream;
1653 // Transform integer into bytes
1654 ByteBuffer bb = ByteBuffer.allocate(INT_SIZE);
1656 // Send the byte array
1657 output.write(bb.array(), 0, INT_SIZE);
1663 * recvInteger() receives integer in bytes
1665 public int recvInteger(InputStream inStream) throws IOException {
1667 BufferedInputStream input = (BufferedInputStream) inStream;
1668 // Wait until input is available
1669 while(input.available() == 0);
1670 // Read integer - 4 bytes
1671 byte[] recvInt = new byte[INT_SIZE];
1672 input.read(recvInt, 0, INT_SIZE);
1673 int retVal = ByteBuffer.wrap(recvInt).getInt();
1680 * recvString() receives String in bytes
1682 public String recvString(InputStream inStream) throws IOException {
1684 BufferedInputStream input = (BufferedInputStream) inStream;
1685 int strLen = recvInteger(inStream);
1686 // Wait until input is available
1687 while(input.available() == 0);
1688 // Read String per strLen
1689 byte[] recvStr = new byte[strLen];
1690 input.read(recvStr, 0, strLen);
1691 String retVal = new String(recvStr);
1698 * sendString() sends a String in bytes
1700 public void sendString(String strSend, OutputStream outStream) throws IOException {
1702 BufferedOutputStream output = (BufferedOutputStream) outStream;
1703 // Transform String into bytes
1704 byte[] strSendBytes = strSend.getBytes();
1705 int strLen = strSend.length();
1706 // Send the string length first
1707 sendInteger(strLen, outStream);
1708 // Send the byte array
1709 output.write(strSendBytes, 0, strLen);
1715 * Convert integer to enum
1717 public IoTCommCode getCode(int intCode) throws IOException {
1719 IoTCommCode[] commCode = IoTCommCode.values();
1720 IoTCommCode retCode = commCode[intCode];
1729 public synchronized boolean recvAck(InputStream inStream) throws IOException {
1731 int intAck = recvInteger(inStream);
1732 IoTCommCode codeAck = getCode(intAck);
1733 if (codeAck == IoTCommCode.ACKNOWLEDGED)
1743 public void sendEndTransfer(OutputStream outStream) throws IOException {
1745 int endCode = IoTCommCode.END_TRANSFER.ordinal();
1746 sendInteger(endCode, outStream);
1751 * Send communication code to C++
1753 public void sendCommCode(IoTCommCode inpCommCode, OutputStream outStream, InputStream inStream) throws IOException {
1756 IoTCommCode commCode = inpCommCode;
1757 int intCode = commCode.ordinal();
1758 // TODO: delete this later
1759 System.out.println("DEBUG: Sending " + commCode + " with ordinal: " + intCode);
1760 sendInteger(intCode, outStream); recvAck(inStream);
1765 * Create a main controller object for C++
1767 public void createMainObjectCpp(String strObjControllerName, OutputStream outStream, InputStream inStream) throws IOException {
1769 sendCommCode(IoTCommCode.CREATE_MAIN_OBJECT, outStream, inStream);
1770 String strMainObjName = strObjControllerName;
1771 sendString(strMainObjName, outStream); recvAck(inStream);
1772 RuntimeOutput.print("IoTMaster: Create a main object: " + strMainObjName, BOOL_VERBOSE);
1777 * A helper function that converts Class into String
1779 * @param strDataType String MySQL data type
1782 public String getClassConverted(Class<?> cls) {
1784 if (cls == String.class) {
1786 } else if (cls == int.class) {
1795 * A helper function that converts Object into String for transfer to C++ slave
1797 * @param obj Object to be converted
1798 * @param strClassType String Java Class type
1801 public String getObjectConverted(Object obj) {
1803 if (obj instanceof String) {
1804 return (String) obj;
1805 } else if (obj instanceof Integer) {
1806 return Integer.toString((Integer) obj);
1814 * Create a driver object for C++
1816 public void createObjectCpp(String strObjName, String strObjClassName, String strObjClassInterfaceName, String strIoTSlaveObjectHostAdd,
1817 Integer iRMIRegistryPort, Integer iRMIStubPort, Object[] arrFieldValues, Class[] arrFieldClasses,
1818 OutputStream outStream, InputStream inStream) throws IOException {
1820 sendCommCode(IoTCommCode.CREATE_OBJECT, outStream, inStream);
1821 RuntimeOutput.print("IoTMaster: Send request to create a driver object... ", BOOL_VERBOSE);
1822 RuntimeOutput.print("IoTMaster: Driver object name: " + strObjName, BOOL_VERBOSE);
1823 sendString(strObjName, outStream); recvAck(inStream);
1824 RuntimeOutput.print("IoTMaster: Driver object class name: " + strObjClassName, BOOL_VERBOSE);
1825 sendString(strObjClassName, outStream); recvAck(inStream);
1826 RuntimeOutput.print("IoTMaster: Driver object interface name: " + strObjClassInterfaceName, BOOL_VERBOSE);
1827 sendString(strObjStubClsIntfaceName, outStream); recvAck(inStream);
1828 RuntimeOutput.print("IoTMaster: Driver object skeleton class name: " + strObjClassInterfaceName + STR_SKEL_CLASS_SUFFIX, BOOL_VERBOSE);
1829 sendString(strObjClassInterfaceName + STR_SKEL_CLASS_SUFFIX, outStream); recvAck(inStream);
1830 RuntimeOutput.print("IoTMaster: Driver object registry port: " + iRMIRegistryPort, BOOL_VERBOSE);
1831 sendInteger(iRMIRegistryPort, outStream); recvAck(inStream);
1832 RuntimeOutput.print("IoTMaster: Driver object stub port: " + iRMIStubPort, BOOL_VERBOSE);
1833 sendInteger(iRMIStubPort, outStream); recvAck(inStream);
1834 int numOfArgs = arrFieldValues.length;
1835 RuntimeOutput.print("IoTMaster: Send constructor arguments! Number of arguments: " + numOfArgs, BOOL_VERBOSE);
1836 sendInteger(numOfArgs, outStream); recvAck(inStream);
1837 for(Object obj : arrFieldValues) {
1838 String str = getObjectConverted(obj);
1839 sendString(str, outStream); recvAck(inStream);
1841 RuntimeOutput.print("IoTMaster: Send constructor argument classes!", BOOL_VERBOSE);
1842 for(Class cls : arrFieldClasses) {
1843 String str = getClassConverted(cls);
1844 sendString(str, outStream); recvAck(inStream);
1850 * Create new IoTSet for C++
1852 public void createNewIoTSetCpp(String strObjFieldName, OutputStream outStream, InputStream inStream) throws IOException {
1854 sendCommCode(IoTCommCode.CREATE_NEW_IOTSET, outStream, inStream);
1855 RuntimeOutput.print("IoTMaster: Creating new IoTSet...", BOOL_VERBOSE);
1856 RuntimeOutput.print("IoTMaster: Send object field name: " + strObjFieldName, BOOL_VERBOSE);
1857 sendString(strObjFieldName, outStream); recvAck(inStream);
1862 * Create new IoTRelation for C++
1864 public void createNewIoTRelationCpp(String strObjFieldName, OutputStream outStream, InputStream inStream) throws IOException {
1866 sendCommCode(IoTCommCode.CREATE_NEW_IOTRELATION, outStream, inStream);
1867 RuntimeOutput.print("IoTMaster: Creating new IoTRelation...", BOOL_VERBOSE);
1868 RuntimeOutput.print("IoTMaster: Send object field name: " + strObjFieldName, BOOL_VERBOSE);
1869 sendString(strObjFieldName, outStream); recvAck(inStream);
1874 * Get a IoTDeviceAddress object for C++
1876 public void getDeviceIoTSetObjectCpp(OutputStream outStream, InputStream inStream,
1877 String strDeviceAddress, int iSourcePort, int iDestPort, boolean bSourceWildCard, boolean bDestWildCard) throws IOException {
1879 sendCommCode(IoTCommCode.GET_DEVICE_IOTSET_OBJECT, outStream, inStream);
1880 RuntimeOutput.print("IoTMaster: Getting IoTDeviceAddress...", BOOL_VERBOSE);
1881 sendString(strDeviceAddress, outStream); recvAck(inStream);
1882 sendInteger(iSourcePort, outStream); recvAck(inStream);
1883 sendInteger(iDestPort, outStream); recvAck(inStream);
1884 int iSourceWildCard = (bSourceWildCard ? 1 : 0);
1885 sendInteger(iSourceWildCard, outStream); recvAck(inStream);
1886 int iDestWildCard = (bDestWildCard ? 1 : 0);
1887 sendInteger(iDestWildCard, outStream); recvAck(inStream);
1888 RuntimeOutput.print("IoTMaster: Send device address: " + strDeviceAddress, BOOL_VERBOSE);
1893 * Get a IoTSet content object for C++
1895 public void getIoTSetRelationObjectCpp(IoTCommCode iotCommCode, String strIoTSlaveHostAddress, String strObjectName, String strObjectClassName,
1896 String strObjectClassInterfaceName, String strObjectStubClassInterfaceName, int iRMIRegistryPort, int iRMIStubPort,
1897 OutputStream outStream, InputStream inStream) throws IOException {
1899 sendCommCode(iotCommCode, outStream, inStream);
1900 RuntimeOutput.print("IoTMaster: Getting IoTSet object content...", BOOL_VERBOSE);
1902 RuntimeOutput.print("IoTMaster: Send host address: " + strIoTSlaveHostAddress, BOOL_VERBOSE);
1903 sendString(strIoTSlaveHostAddress, outStream); recvAck(inStream);
1904 RuntimeOutput.print("IoTMaster: Driver object name: " + strObjectName, BOOL_VERBOSE);
1905 sendString(strObjectName, outStream); recvAck(inStream);
1906 RuntimeOutput.print("IoTMaster: Driver object class name: " + strObjectClassName, BOOL_VERBOSE);
1907 sendString(strObjectClassName, outStream); recvAck(inStream);
1908 RuntimeOutput.print("IoTMaster: Driver object interface name: " + strObjectClassInterfaceName, BOOL_VERBOSE);
1909 sendString(strObjectClassInterfaceName, outStream); recvAck(inStream);
1910 RuntimeOutput.print("IoTMaster: Driver object stub class name: " + strObjectStubClassInterfaceName + STR_STUB_CLASS_SUFFIX, BOOL_VERBOSE);
1911 sendString(strObjectStubClassInterfaceName + STR_STUB_CLASS_SUFFIX, outStream); recvAck(inStream);
1912 RuntimeOutput.print("IoTMaster: Driver object registry port: " + iRMIRegistryPort, BOOL_VERBOSE);
1913 sendInteger(iRMIRegistryPort, outStream); recvAck(inStream);
1914 RuntimeOutput.print("IoTMaster: Driver object stub port: " + iRMIStubPort, BOOL_VERBOSE);
1915 sendInteger(iRMIStubPort, outStream); recvAck(inStream);
1920 * Reinitialize IoTRelation field for C++
1922 private void reinitializeIoTRelationFieldCpp(OutputStream outStream, InputStream inStream) throws IOException {
1924 RuntimeOutput.print("IoTMaster: About to Reinitialize IoTRelation field!", BOOL_VERBOSE);
1925 sendCommCode(IoTCommCode.REINITIALIZE_IOTRELATION_FIELD, outStream, inStream);
1926 RuntimeOutput.print("IoTMaster: Reinitialize IoTRelation field!", BOOL_VERBOSE);
1931 * Reinitialize IoTSet field for C++
1933 private void reinitializeIoTSetFieldCpp(OutputStream outStream, InputStream inStream) throws IOException {
1935 RuntimeOutput.print("IoTMaster: About to Reinitialize IoTSet field!", BOOL_VERBOSE);
1936 sendCommCode(IoTCommCode.REINITIALIZE_IOTSET_FIELD, outStream, inStream);
1937 RuntimeOutput.print("IoTMaster: Reinitialize IoTSet field!", BOOL_VERBOSE);
1942 * Create driver object for C++
1944 private void createDriverObjectCpp(OutputStream outStream, InputStream inStream) throws IOException {
1946 sendCommCode(IoTCommCode.CREATE_DRIVER_OBJECT, outStream, inStream);
1947 RuntimeOutput.print("IoTMaster: Send command to create driver object!", BOOL_VERBOSE);
1952 * Invoke init() for C++
1954 private void invokeInitMethodCpp(OutputStream outStream, InputStream inStream) throws IOException {
1956 sendCommCode(IoTCommCode.INVOKE_INIT_METHOD, outStream, inStream);
1957 RuntimeOutput.print("IoTMaster: Invoke init method!", BOOL_VERBOSE);
1962 * End session for C++
1964 public void endSessionCpp(OutputStream outStream) throws IOException {
1966 // Send message to end session
1967 IoTCommCode endSessionCode = IoTCommCode.END_SESSION;
1968 int intCode = endSessionCode.ordinal();
1969 sendInteger(intCode, outStream);
1970 //RuntimeOutput.print("IoTMaster: Send request to create a main object: " + strObjName, BOOL_VERBOSE);
1971 RuntimeOutput.print("IoTMaster: Send request to end session!", BOOL_VERBOSE);
1976 * A method to assign objects to multiple JVMs, including
1977 * the controller/device object that uses other objects
1978 * in IoTSet and IoTRelation
1982 private void createObjects() {
1989 // Extract hostname for this IoTMaster from MySQL DB
1990 strIoTMasterHostAdd = routerConfig.getIPFromMACAddress(STR_MASTER_MAC_ADD);
1991 // Loop as we can still find controller/device classes
1992 for(int i=0; i<strObjectNames.length; i++) {
1994 start = System.currentTimeMillis();
1996 // Assign a new list of PrintWriter objects
1997 routerConfig.renewPrintWriter();
1998 // Get controller names one by one
1999 String strObjControllerName = strObjectNames[i];
2000 // Use LoadBalancer to assign a host address
2001 //strIoTSlaveControllerHostAdd = lbIoT.selectHost();
2002 strIoTSlaveControllerHostAdd = routerConfig.getIPFromMACAddress(lbIoT.selectHost());
2003 if (strIoTSlaveControllerHostAdd == null)
2004 throw new Error("IoTMaster: Could not translate MAC to IP address! Please check the router's /tmp/dhcp.leases!");
2005 // == START INITIALIZING CONTROLLER/DEVICE IOTSLAVE ==
2006 // Add port connection and get port numbers
2007 // Naming for objects ProximitySensor becomes ProximitySensor0, ProximitySensor1, etc.
2008 commHan.addPortConnection(strIoTSlaveControllerHostAdd, strObjControllerName);
2009 // ROUTING POLICY: IoTMaster and main controller object
2010 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTMasterHostAdd,
2011 strIoTSlaveControllerHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjControllerName));
2012 // ROUTING POLICY: Send the same routing policy to both the hosts
2013 routerConfig.configureHostMainPolicies(strIoTMasterHostAdd, strIoTMasterHostAdd,
2014 strIoTSlaveControllerHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjControllerName));
2015 routerConfig.configureHostMainPolicies(strIoTSlaveControllerHostAdd, strIoTMasterHostAdd,
2016 strIoTSlaveControllerHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjControllerName));
2018 String strControllerCfg = STR_CONT_PATH + strObjControllerName + "/" + strObjControllerName + STR_CFG_FILE_EXT;
2019 STR_LANGUAGE_CONTROLLER = parseConfigFile(strControllerCfg, STR_LANGUAGE);
2020 if(STR_LANGUAGE_CONTROLLER == null)
2021 throw new Error("IoTMaster: Language specification missing in config file: " + strControllerCfg);
2022 // Construct ssh command line and create a controller thread for e.g. AcmeProximity
2023 String strSSHCommand = null;
2024 if(STR_LANGUAGE_CONTROLLER.equals(STR_JAVA))
2025 strSSHCommand = getCmdJavaIoTSlave(strObjControllerName);
2026 else if(STR_LANGUAGE_CONTROLLER.equals(STR_CPP))
2027 strSSHCommand = getCmdCppIoTSlave(strObjControllerName);
2029 throw new Error("IoTMaster: Language specification not recognized: " + STR_LANGUAGE_CONTROLLER);
2030 RuntimeOutput.print(strSSHCommand, BOOL_VERBOSE);
2031 createThread(strSSHCommand);
2032 // Wait for connection
2033 // Create a new socket for communication
2034 ServerSocket serverSocket = new ServerSocket(commHan.getComPort(strObjControllerName));
2035 Socket socket = serverSocket.accept();
2036 InputStream inStream = null;
2037 OutputStream outStream = null;
2038 if(STR_LANGUAGE_CONTROLLER.equals(STR_JAVA)) {
2039 inStream = new ObjectInputStream(socket.getInputStream());
2040 outStream = new ObjectOutputStream(socket.getOutputStream());
2041 } else { // At this point the language is certainly C++, otherwise would've complained above
2042 inStream = new BufferedInputStream(socket.getInputStream());
2043 outStream = new BufferedOutputStream(socket.getOutputStream());
2046 RuntimeOutput.print("IoTMaster: Communication established!", BOOL_VERBOSE);
2049 result = System.currentTimeMillis()-start;
2050 System.out.println("\n\n ==> From start until after SSH for main controller: " + result);
2052 start = System.currentTimeMillis();
2054 // Send files for every controller class
2055 // e.g. AcmeProximity.jar and AcmeProximity.zip
2056 String strControllerClassName = strObjControllerName + STR_CLS_FILE_EXT;
2057 String strControllerClassNamePath = STR_CONT_PATH + strObjControllerName + "/" +
2058 strControllerClassName;
2060 if(STR_LANGUAGE_CONTROLLER.equals(STR_JAVA)) {
2061 sendFileToJavaSlave(strObjControllerName, serverSocket, inStream, outStream);
2062 // Create main controller/device object
2063 commMasterToSlave(new MessageCreateMainObject(IoTCommCode.CREATE_MAIN_OBJECT, strObjControllerName),
2064 "Create main object!", inStream, outStream);
2066 String strControllerZipFile = strObjControllerName + STR_ZIP_FILE_EXT;
2067 String strControllerFilePath = STR_CONT_PATH + strObjControllerName + "/";
2068 sendFileToCppSlave(strControllerFilePath, strControllerZipFile);
2069 createMainObjectCpp(strObjControllerName, outStream, inStream);
2071 // Write basic MAC policies for controller
2072 //String strFileName = STR_MAC_POL_PATH + strObjControllerName + STR_MAC_POLICY_EXT;
2073 if (STR_ACTIVATE_SANDBOXING.equals("Yes")) {
2074 String strFileName = STR_MAC_POL_PATH + STR_JAVA + STR_MAC_POLICY_EXT;
2075 processJailConfig.configureProcessJailControllerPolicies(strObjControllerName, strFileName,
2076 strIoTMasterHostAdd, commHan.getComPort(strObjControllerName));
2079 result = System.currentTimeMillis()-start;
2080 System.out.println("\n\n ==> From IoTSlave start until main controller object is created: " + result);
2081 System.out.println(" ==> Including file transfer times!\n\n");
2083 start = System.currentTimeMillis();
2085 // == END INITIALIZING CONTROLLER/DEVICE IOTSLAVE ==
2086 // Instrumenting one file
2087 RuntimeOutput.print("IoTMaster: Opening class file: " + strControllerClassName, BOOL_VERBOSE);
2088 RuntimeOutput.print("IoTMaster: Class file path: " + strControllerClassNamePath, BOOL_VERBOSE);
2089 HashMap<String,Object> hmControllerFieldObjects = null;
2090 if(STR_LANGUAGE_CONTROLLER.equals(STR_JAVA)) {
2091 FileInputStream fis = new FileInputStream(strControllerClassNamePath);
2092 ClassReader cr = new ClassReader(fis);
2093 ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
2094 ClassRuntimeInstrumenterMaster crim = new ClassRuntimeInstrumenterMaster(cw, null, BOOL_VERBOSE);
2097 hmControllerFieldObjects = crim.getFieldObjects();
2099 String strControllerConfigFile = STR_CONT_PATH + strObjControllerName + "/" + strObjControllerName + STR_CFG_FILE_EXT;
2100 CRuntimeInstrumenterMaster crim = new CRuntimeInstrumenterMaster(strControllerConfigFile, null, BOOL_VERBOSE);
2101 hmControllerFieldObjects = crim.getFieldObjects();
2103 // Get the object and the class names
2104 // Build objects for IoTSet and IoTRelation fields in the controller/device classes
2105 //HashMap<String,Object> hmControllerFieldObjects = crim.getFieldObjects();
2106 for(Map.Entry<String,Object> map : hmControllerFieldObjects.entrySet()) {
2107 RuntimeOutput.print("IoTMaster: Object name: " + map.getValue().getClass().getName(), BOOL_VERBOSE);
2108 // Iterate over HashMap and choose between processing
2109 // SetInstrumenter vs. RelationInstrumenter
2110 String strFieldName = map.getKey();
2111 String strClassName = map.getValue().getClass().getName();
2112 if(strClassName.equals(STR_SET_INSTRUMENTER_CLS)) {
2113 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
2114 if(setInstrumenter.getObjTableName().equals(STR_IOT_DEV_ADD_CLS)) {
2115 String strErrMsg = "IoTMaster: Controller object" +
2116 " cannot have IoTSet<IoTDeviceAddress>!";
2117 throw new Error(strErrMsg);
2118 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ZB_ADD_CLS)) {
2119 String strErrMsg = "IoTMaster: Controller object" +
2120 " cannot have IoTSet<ZigbeeAddress>!";
2121 throw new Error(strErrMsg);
2122 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ADD_CLS)) {
2123 // Instrument the IoTAddress
2124 setRouterPolicyIoTSetAddress(strFieldName, map, strIoTSlaveControllerHostAdd, strObjControllerName);
2125 instrumentIoTSetAddress(strFieldName, strFieldName, inStream, outStream, STR_LANGUAGE_CONTROLLER);
2128 instrumentIoTSet(map, strFieldName, strObjControllerName, STR_LANGUAGE_CONTROLLER);
2130 } else if (strClassName.equals(STR_REL_INSTRUMENTER_CLS)) {
2131 instrumentIoTRelation(map, strFieldName, strObjControllerName, STR_LANGUAGE_CONTROLLER);
2134 // Combine controller MAC policies with the main policy file for the host
2135 String strTempFileName = "./" + strObjControllerName + STR_MAC_POLICY_EXT;
2136 processJailConfig.combineControllerMACPolicies(strIoTSlaveControllerHostAdd, strObjControllerName, strTempFileName);
2137 processJailConfig.close();
2140 result = System.currentTimeMillis()-start;
2141 System.out.println("\n\n ==> Time needed to instrument device driver objects: " + result + "\n\n");
2142 System.out.println(" ==> #Objects: " + commHan.getActiveControllerObjectList().size() + "\n\n");
2145 start = System.currentTimeMillis();
2147 // ROUTING POLICY: Deploy basic policies if this is the last controller
2148 if (i == strObjectNames.length-1) {
2149 // ROUTING POLICY: implement basic policies to reject all other irrelevant traffics
2150 for(String s: commHan.getHosts()) {
2151 setHostBasicPolicies(s);
2153 // We retain all the basic policies for router,
2154 // but we delete the initial allowance policies for internal all TCP and UDP communications
2155 setRouterBasicPolicies(STR_ROUTER_ADD);
2157 // Close access to policy files and deploy policies
2158 routerConfig.close();
2159 // Deploy the policy
2160 HashSet<String> setAddresses = new HashSet<String>(commHan.getHosts());
2161 setAddresses.add(strIoTMasterHostAdd);
2162 createPolicyThreads(STR_ROUTER_ADD, setAddresses);
2165 result = System.currentTimeMillis()-start;
2166 System.out.println("\n\n ==> Time needed to send policy files and deploy them : " + result + "\n\n");
2169 start = System.currentTimeMillis();
2171 // Separating object creations and Set/Relation initializations
2172 createDriverObjects();
2175 result = System.currentTimeMillis()-start;
2176 System.out.println("\n\n ==> Time needed to instantiate objects: " + result + "\n\n");
2178 start = System.currentTimeMillis();
2180 // Sets and relations initializations
2181 if(STR_LANGUAGE_CONTROLLER.equals(STR_JAVA))
2182 initializeSetsAndRelationsJava(inStream, outStream);
2184 initializeSetsAndRelationsCpp(inStream, outStream);;
2187 result = System.currentTimeMillis()-start;
2188 System.out.println("\n\n ==> Time needed to initialize sets and relations: " + result + "\n\n");
2190 if(STR_LANGUAGE_CONTROLLER.equals(STR_JAVA))
2191 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO EXECUTE INIT METHOD
2192 commMasterToSlave(new MessageSimple(IoTCommCode.INVOKE_INIT_METHOD), "Invoke init() method!", inStream, outStream);
2194 invokeInitMethodCpp(outStream, inStream);
2195 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO END PROCESS
2196 if(STR_LANGUAGE_CONTROLLER.equals(STR_JAVA)) {
2197 ObjectOutputStream oStream = (ObjectOutputStream) outStream;
2198 oStream.writeObject(new MessageSimple(IoTCommCode.END_SESSION));
2199 } else // C++ side will wait until the program finishes, it's not generating a separate thread for now
2200 //endSessionCpp(outStream);
2204 serverSocket.close();
2205 commHan.printLists();
2206 lbIoT.printHostInfo();
2207 if (STR_ACTIVATE_SANDBOXING.equals("Yes"))
2208 createMACPolicyThreads(setAddresses);
2211 } catch (IOException |
2212 InterruptedException |
2213 ClassNotFoundException ex) {
2214 System.out.println("IoTMaster: Exception: "
2216 ex.printStackTrace();
2220 public static void main(String args[]) {
2222 // Detect the available controller/device classes
2223 // Input args[] should be used to list the controllers/devices
2224 // e.g. java IoTMaster AcmeProximity AcmeThermostat AcmeVentController
2225 IoTMaster iotMaster = new IoTMaster(args);
2227 iotMaster.parseIoTMasterConfigFile();
2228 // Initialize CommunicationHandler, LoadBalancer, and RouterConfig
2229 iotMaster.initLiveDataStructure();
2231 iotMaster.createObjects();