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 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 boolean BOOL_VERBOSE;
108 * IoTMaster class constants
110 * Name constants - not to be configured by users
112 private static final String STR_IOT_MASTER_NAME = "IoTMaster";
113 private static final String STR_CFG_FILE_EXT = ".config";
114 private static final String STR_CLS_FILE_EXT = ".class";
115 private static final String STR_JAR_FILE_EXT = ".jar";
116 private static final String STR_MAC_POLICY_EXT = ".tomoyo.pol";
117 private static final String STR_SHELL_FILE_EXT = ".sh";
118 private static final String STR_SO_FILE_EXT = ".so";
119 private static final String STR_ZIP_FILE_EXT = ".zip";
120 private static final String STR_TCP_PROTOCOL = "tcp";
121 private static final String STR_UDP_PROTOCOL = "udp";
122 private static final String STR_TCPGW_PROTOCOL = "tcpgw";
123 private static final String STR_NO_PROTOCOL = "nopro";
124 private static final String STR_SELF_MAC_ADD = "00:00:00:00:00:00";
125 private static final String STR_INTERFACE_CLS_CFG = "INTERFACE_CLASS";
126 private static final String STR_INT_STUB_CLS_CFG = "INTERFACE_STUB_CLASS";
127 private static final String STR_FILE_TRF_CFG = "ADDITIONAL_ZIP_FILE";
128 private static final String STR_LANGUAGE = "LANGUAGE";
129 private static final String STR_YES = "Yes";
130 private static final String STR_NO = "No";
131 private static final String STR_JAVA = "Java";
132 private static final String STR_CPP = "C++";
133 private static final String STR_SSH = "ssh";
134 private static final String STR_SCP = "scp";
135 private static final String STR_IOTSLAVE_CPP = "./IoTSlave.o";
136 private static final String STR_SHELL_HEADER = "#!/bin/sh";
137 private static final String STR_JAVA_PATH = "/usr/bin/java";
138 private static final String STR_MAC_POL_PATH = "tomoyo/";
140 private static int INT_SIZE = 4; // send length in the size of integer (4 bytes)
143 * Runtime class name constants - not to be configured by users
145 private static final String STR_REL_INSTRUMENTER_CLS = "iotruntime.master.RelationInstrumenter";
146 private static final String STR_SET_INSTRUMENTER_CLS = "iotruntime.master.SetInstrumenter";
147 private static final String STR_IOT_SLAVE_CLS = "iotruntime.slave.IoTSlave";
148 private static final String STR_IOT_DEV_ADD_CLS = "IoTDeviceAddress";
149 private static final String STR_IOT_ZB_ADD_CLS = "IoTZigbeeAddress";
150 private static final String STR_IOT_ADD_CLS = "IoTAddress";
156 public IoTMaster(String[] argObjNms) {
161 processJailConfig = null;
163 objAddInitHand = null;
164 strObjectNames = argObjNms;
166 strObjClassName = null;
167 strObjClassInterfaceName = null;
168 strObjStubClsIntfaceName = null;
169 strIoTMasterHostAdd = null;
170 strIoTSlaveControllerHostAdd = null;
171 strIoTSlaveObjectHostAdd = null;
172 arrFieldClasses = null;
173 arrFieldValues = null;
175 mapClassNameToCrim = null;
176 // Connection with C++ IoTSlave
177 serverSocketCpp = null;
182 STR_MASTER_MAC_ADD = null;
183 STR_IOT_CODE_PATH = null;
184 STR_CONT_PATH = null;
185 STR_RUNTIME_DIR = null;
186 STR_SLAVE_DIR = null;
189 STR_RMI_HOSTNAME = null;
190 STR_LOG_FILE_PATH = null;
192 STR_ROUTER_ADD = null;
193 STR_MONITORING_HOST = null;
194 STR_ZB_GATEWAY_ADDRESS = null;
195 STR_ZB_GATEWAY_PORT = null;
196 STR_ZB_IOTMASTER_PORT = null;
197 STR_JVM_INIT_HEAP_SIZE = null;
198 STR_JVM_MAX_HEAP_SIZE = null;
199 STR_LANGUAGE_CONTROLLER = null;
200 BOOL_VERBOSE = false;
204 * A method to initialize CommunicationHandler, LoadBalancer, RouterConfig and ObjectInitHandler
208 private void initLiveDataStructure() {
210 commHan = new CommunicationHandler(BOOL_VERBOSE);
211 lbIoT = new LoadBalancer(BOOL_VERBOSE);
212 lbIoT.setupLoadBalancer();
213 routerConfig = new RouterConfig();
214 routerConfig.getAddressList(STR_ROUTER_ADD);
215 processJailConfig = new ProcessJailConfig();
216 //processJailConfig.setAddressListObject(routerConfig.getAddressListObject());
217 objInitHand = new ObjectInitHandler(BOOL_VERBOSE);
218 objAddInitHand = new ObjectAddressInitHandler(BOOL_VERBOSE);
219 mapClassNameToCrim = new HashMap<String,Object>();
223 * getPrintWriter() gets a new PrintWriter for a new object
225 * @param strObjectName String object name
226 * @return PrintWriter
228 private PrintWriter getPrintWriter(String strObjectName) {
230 FileWriter fw = null;
232 fw = new FileWriter(strObjectName);
233 } catch (IOException ex) {
234 ex.printStackTrace();
236 PrintWriter printWriter = new PrintWriter(new BufferedWriter(fw));
241 * A method to initialize constants from config file
245 private void parseIoTMasterConfigFile() {
246 // Parse configuration file
247 Properties prop = new Properties();
248 String strCfgFileName = STR_IOT_MASTER_NAME + STR_CFG_FILE_EXT;
249 File file = new File(strCfgFileName);
250 FileInputStream fis = null;
252 fis = new FileInputStream(file);
255 } catch (IOException ex) {
256 System.out.println("IoTMaster: Error reading config file: " + strCfgFileName);
257 ex.printStackTrace();
259 // Initialize constants from config file
260 STR_MASTER_MAC_ADD = prop.getProperty("MAC_ADDRESS");
261 STR_IOT_CODE_PATH = prop.getProperty("IOT_CODE_PATH");
262 STR_CONT_PATH = prop.getProperty("CONTROLLERS_CODE_PATH");
263 STR_RUNTIME_DIR = prop.getProperty("RUNTIME_DIR");
264 STR_SLAVE_DIR = prop.getProperty("SLAVE_DIR");
265 STR_CLS_PATH = prop.getProperty("CLASS_PATH");
266 STR_RMI_PATH = prop.getProperty("RMI_PATH");
267 STR_RMI_HOSTNAME = prop.getProperty("RMI_HOSTNAME");
268 STR_LOG_FILE_PATH = prop.getProperty("LOG_FILE_PATH");
269 STR_USERNAME = prop.getProperty("USERNAME");
270 STR_ROUTER_ADD = prop.getProperty("ROUTER_ADD");
271 STR_MONITORING_HOST = prop.getProperty("MONITORING_HOST");
272 STR_ZB_GATEWAY_ADDRESS = prop.getProperty("ZIGBEE_GATEWAY_ADDRESS");
273 STR_ZB_GATEWAY_PORT = prop.getProperty("ZIGBEE_GATEWAY_PORT");
274 STR_ZB_IOTMASTER_PORT = prop.getProperty("ZIGBEE_IOTMASTER_PORT");
275 STR_JVM_INIT_HEAP_SIZE = prop.getProperty("JVM_INIT_HEAP_SIZE");
276 STR_JVM_MAX_HEAP_SIZE = prop.getProperty("JVM_MAX_HEAP_SIZE");
277 STR_SKEL_CLASS_SUFFIX = prop.getProperty("SKEL_CLASS_SUFFIX");
278 STR_STUB_CLASS_SUFFIX = prop.getProperty("STUB_CLASS_SUFFIX");
279 if(prop.getProperty("VERBOSE").equals(STR_YES)) {
283 RuntimeOutput.print("IoTMaster: Extracting information from config file: " + strCfgFileName, BOOL_VERBOSE);
284 RuntimeOutput.print("STR_MASTER_MAC_ADD=" + STR_MASTER_MAC_ADD, BOOL_VERBOSE);
285 RuntimeOutput.print("STR_IOT_CODE_PATH=" + STR_IOT_CODE_PATH, BOOL_VERBOSE);
286 RuntimeOutput.print("STR_CONT_PATH=" + STR_CONT_PATH, BOOL_VERBOSE);
287 RuntimeOutput.print("STR_RUNTIME_DIR=" + STR_RUNTIME_DIR, BOOL_VERBOSE);
288 RuntimeOutput.print("STR_SLAVE_DIR=" + STR_SLAVE_DIR, BOOL_VERBOSE);
289 RuntimeOutput.print("STR_CLS_PATH=" + STR_CLS_PATH, BOOL_VERBOSE);
290 RuntimeOutput.print("STR_RMI_PATH=" + STR_RMI_PATH, BOOL_VERBOSE);
291 RuntimeOutput.print("STR_RMI_HOSTNAME=" + STR_RMI_HOSTNAME, BOOL_VERBOSE);
292 RuntimeOutput.print("STR_LOG_FILE_PATH=" + STR_LOG_FILE_PATH, BOOL_VERBOSE);
293 RuntimeOutput.print("STR_USERNAME=" + STR_USERNAME, BOOL_VERBOSE);
294 RuntimeOutput.print("STR_ROUTER_ADD=" + STR_ROUTER_ADD, BOOL_VERBOSE);
295 RuntimeOutput.print("STR_MONITORING_HOST=" + STR_MONITORING_HOST, BOOL_VERBOSE);
296 RuntimeOutput.print("STR_ZB_GATEWAY_ADDRESS=" + STR_ZB_GATEWAY_ADDRESS, BOOL_VERBOSE);
297 RuntimeOutput.print("STR_ZB_GATEWAY_PORT=" + STR_ZB_GATEWAY_PORT, BOOL_VERBOSE);
298 RuntimeOutput.print("STR_ZB_IOTMASTER_PORT=" + STR_ZB_IOTMASTER_PORT, BOOL_VERBOSE);
299 RuntimeOutput.print("STR_JVM_INIT_HEAP_SIZE=" + STR_JVM_INIT_HEAP_SIZE, BOOL_VERBOSE);
300 RuntimeOutput.print("STR_JVM_MAX_HEAP_SIZE=" + STR_JVM_MAX_HEAP_SIZE, BOOL_VERBOSE);
301 RuntimeOutput.print("STR_SKEL_CLASS_SUFFIX=" + STR_SKEL_CLASS_SUFFIX, BOOL_VERBOSE);
302 RuntimeOutput.print("STR_STUB_CLASS_SUFFIX=" + STR_STUB_CLASS_SUFFIX, BOOL_VERBOSE);
303 RuntimeOutput.print("BOOL_VERBOSE=" + BOOL_VERBOSE, BOOL_VERBOSE);
304 RuntimeOutput.print("IoTMaster: Information extracted successfully!", BOOL_VERBOSE);
308 * A method to parse information from a config file
310 * @param strCfgFileName Config file name
311 * @param strCfgField Config file field name
314 private String parseConfigFile(String strCfgFileName, String strCfgField) {
315 // Parse configuration file
316 Properties prop = new Properties();
317 File file = new File(strCfgFileName);
318 FileInputStream fis = null;
320 fis = new FileInputStream(file);
323 } catch (IOException ex) {
324 System.out.println("IoTMaster: Error reading config file: " + strCfgFileName);
325 ex.printStackTrace();
327 System.out.println("IoTMaster: Reading " + strCfgField +
328 " from config file: " + strCfgFileName + " with value: " +
329 prop.getProperty(strCfgField, null));
330 // NULL is returned if the property isn't found
331 return prop.getProperty(strCfgField, null);
335 * A method to send files from IoTMaster
337 * @param filesocket File socket object
338 * @param sFileName File name
339 * @param lFLength File length
342 private void sendFile(Socket filesocket, String sFileName, long lFLength) throws IOException {
344 File file = new File(sFileName);
345 byte[] bytFile = new byte[toIntExact(lFLength)];
346 InputStream inFileStream = new FileInputStream(file);
348 OutputStream outFileStream = filesocket.getOutputStream();
350 while ((iCount = inFileStream.read(bytFile)) > 0) {
351 outFileStream.write(bytFile, 0, iCount);
354 RuntimeOutput.print("IoTMaster: File sent!", BOOL_VERBOSE);
358 * A method to create a thread
360 * @param sSSHCmd SSH command
363 private void createThread(String sSSHCmd) throws IOException {
365 // Start a new thread to start a new JVM
367 Runtime runtime = Runtime.getRuntime();
368 Process process = runtime.exec(sSSHCmd);
370 RuntimeOutput.print("Executing: " + sSSHCmd, BOOL_VERBOSE);
374 * A method to send command from master and receive reply from slave
376 * @params msgSend Message object
377 * @params strPurpose String that prints purpose message
378 * @params inStream Input stream
379 * @params outStream Output stream
382 private void commMasterToSlave(Message msgSend, String strPurpose,
383 InputStream _inStream, OutputStream _outStream)
384 throws IOException, ClassNotFoundException {
386 // Send message/command from master
387 ObjectOutputStream outStream = (ObjectOutputStream) _outStream;
388 outStream.writeObject(msgSend);
389 RuntimeOutput.print("IoTMaster: Send message: " + strPurpose, BOOL_VERBOSE);
391 // Get reply from slave as acknowledgment
392 ObjectInputStream inStream = (ObjectInputStream) _inStream;
393 Message msgReply = (Message) inStream.readObject();
394 RuntimeOutput.print("IoTMaster: Reply message: " + msgReply.getMessage(), BOOL_VERBOSE);
398 * A private method to instrument IoTSet device
400 * @params strFieldIdentifier String field name + object ID
401 * @params strFieldName String field name
402 * @params strIoTSlaveObjectHostAdd String slave host address
403 * @params inStream ObjectInputStream communication
404 * @params inStream ObjectOutputStream communication
405 * @params strLanguage String language
408 private void instrumentIoTSetDevice(String strFieldIdentifier, String strObjName, String strFieldName, String strIoTSlaveObjectHostAdd,
409 InputStream inStream, OutputStream outStream, String strLanguage)
410 throws IOException, ClassNotFoundException, InterruptedException {
412 // Get information from the set
413 List<Object[]> listObject = objAddInitHand.getFields(strFieldIdentifier);
414 // Create a new IoTSet
415 if(strLanguage.equals(STR_JAVA)) {
416 Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, strFieldName);
417 commMasterToSlave(msgCrtIoTSet, "Create new IoTSet for IoTDeviceAddress!", inStream, outStream);
419 createNewIoTSetCpp(strFieldName, outStream, inStream);
420 int iRows = listObject.size();
421 RuntimeOutput.print("IoTMaster: Number of rows for IoTDeviceAddress: " + iRows, BOOL_VERBOSE);
422 // Transfer the address
423 for(int iRow=0; iRow<iRows; iRow++) {
424 arrFieldValues = listObject.get(iRow);
425 // Get device address - if 00:00:00:00:00:00 that means it needs the driver object address (self)
426 String strDeviceAddress = null;
427 String strDeviceAddressKey = null;
428 if (arrFieldValues[0].equals(STR_SELF_MAC_ADD)) {
429 strDeviceAddress = strIoTSlaveObjectHostAdd;
430 strDeviceAddressKey = strObjName + "-" + strIoTSlaveObjectHostAdd;
432 strDeviceAddress = routerConfig.getIPFromMACAddress((String) arrFieldValues[0]);
433 strDeviceAddressKey = strObjName + "-" + strDeviceAddress;
435 int iDestDeviceDriverPort = (int) arrFieldValues[1];
436 String strProtocol = (String) arrFieldValues[2];
437 // Check for wildcard feature
438 boolean bSrcPortWildCard = false;
439 boolean bDstPortWildCard = false;
440 if (arrFieldValues.length > 3) {
441 bSrcPortWildCard = (boolean) arrFieldValues[3];
442 bDstPortWildCard = (boolean) arrFieldValues[4];
444 // Add the port connection into communication handler - if it's not assigned yet
445 if (commHan.getComPort(strDeviceAddressKey) == null) {
446 commHan.addPortConnection(strIoTSlaveObjectHostAdd, strDeviceAddressKey);
450 System.out.println("\n\n DEBUG: InstrumentSetDevice: Object Name: " + strObjName);
451 System.out.println("DEBUG: InstrumentSetDevice: Port number: " + commHan.getComPort(strDeviceAddressKey));
452 System.out.println("DEBUG: InstrumentSetDevice: Device address: " + strDeviceAddressKey + "\n\n");
454 // Send address one by one
455 if(strLanguage.equals(STR_JAVA)) {
456 Message msgGetIoTSetObj = null;
457 if (bDstPortWildCard) {
458 String strUniqueDev = strDeviceAddressKey + ":" + iRow;
459 msgGetIoTSetObj = new MessageGetDeviceObject(IoTCommCode.GET_DEVICE_IOTSET_OBJECT,
460 strDeviceAddress, commHan.getAdditionalPort(strUniqueDev), iDestDeviceDriverPort, bSrcPortWildCard, bDstPortWildCard);
462 msgGetIoTSetObj = new MessageGetDeviceObject(IoTCommCode.GET_DEVICE_IOTSET_OBJECT,
463 strDeviceAddress, commHan.getComPort(strDeviceAddressKey), iDestDeviceDriverPort, bSrcPortWildCard, bDstPortWildCard);
464 commMasterToSlave(msgGetIoTSetObj, "Get IoTSet objects!", inStream, outStream);
466 getDeviceIoTSetObjectCpp(outStream, inStream, strDeviceAddress, commHan.getComPort(strDeviceAddressKey), iDestDeviceDriverPort,
467 bSrcPortWildCard, bDstPortWildCard);
469 // Reinitialize IoTSet on device object
470 if(strLanguage.equals(STR_JAVA))
471 commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTSET_FIELD), "Reinitialize IoTSet fields!", inStream, outStream);
473 reinitializeIoTSetFieldCpp(outStream, inStream);
478 * A private method to instrument IoTSet Zigbee device
480 * @params Map.Entry<String,Object> Entry of map IoTSet instrumentation
481 * @params strFieldName String field name
482 * @params strIoTSlaveObjectHostAdd String slave host address
483 * @params inStream ObjectInputStream communication
484 * @params inStream ObjectOutputStream communication
485 * @params strLanguage String language
488 private void instrumentIoTSetZBDevice(Map.Entry<String,Object> map, String strObjName, String strFieldName, String strIoTSlaveObjectHostAdd,
489 InputStream inStream, OutputStream outStream, String strLanguage)
490 throws IOException, ClassNotFoundException, InterruptedException {
492 // Get information from the set
493 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
494 // Create a new IoTSet
495 if(strLanguage.equals(STR_JAVA)) {
496 Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, strFieldName);
497 commMasterToSlave(msgCrtIoTSet, "Create new IoTSet for IoTZigbeeAddress!", inStream, outStream);
498 } else // TODO: will need to implement IoTSet Zigbee for C++ later
500 // Prepare ZigbeeConfig
501 String strZigbeeGWAddress = routerConfig.getIPFromMACAddress(STR_ZB_GATEWAY_ADDRESS);
502 String strZigbeeGWAddressKey = strObjName + "-" + strZigbeeGWAddress;
503 int iZigbeeGWPort = Integer.parseInt(STR_ZB_GATEWAY_PORT);
504 int iZigbeeIoTMasterPort = Integer.parseInt(STR_ZB_IOTMASTER_PORT);
505 commHan.addDevicePort(iZigbeeIoTMasterPort);
506 ZigbeeConfig zbConfig = new ZigbeeConfig(strZigbeeGWAddress, iZigbeeGWPort, iZigbeeIoTMasterPort,
508 // Add the port connection into communication handler - if it's not assigned yet
509 if (commHan.getComPort(strZigbeeGWAddressKey) == null) {
510 commHan.addPortConnection(strIoTSlaveObjectHostAdd, strZigbeeGWAddressKey);
512 int iRows = setInstrumenter.numberOfRows();
513 RuntimeOutput.print("IoTMaster: Number of rows for IoTZigbeeAddress: " + iRows, BOOL_VERBOSE);
516 System.out.println("\n\n DEBUG: InstrumentZigbeeDevice: Object Name: " + strObjName);
517 System.out.println("DEBUG: InstrumentZigbeeDevice: Port number: " + commHan.getComPort(strZigbeeGWAddressKey));
518 System.out.println("DEBUG: InstrumentZigbeeDevice: Device address: " + strZigbeeGWAddress + "\n\n");
520 // Transfer the address
521 for(int iRow=0; iRow<iRows; iRow++) {
522 arrFieldValues = setInstrumenter.fieldValues(iRow);
523 // Get device address
524 String strZBDevAddress = (String) arrFieldValues[0];
525 // Send policy to Zigbee gateway - TODO: Need to clear policy first?
526 zbConfig.setPolicy(strIoTSlaveObjectHostAdd, commHan.getComPort(strZigbeeGWAddressKey), strZBDevAddress);
527 // Send address one by one
528 if(strLanguage.equals(STR_JAVA)) {
529 Message msgGetIoTSetZBObj = new MessageGetSimpleDeviceObject(IoTCommCode.GET_ZB_DEV_IOTSET_OBJECT, strZBDevAddress);
530 commMasterToSlave(msgGetIoTSetZBObj, "Get IoTSet objects!", inStream, outStream);
531 } else // TODO: Implement IoTSet Zigbee for C++
534 zbConfig.closeConnection();
535 // Reinitialize IoTSet on device object
536 commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTSET_FIELD), "Reinitialize IoTSet fields!", inStream, outStream);
541 * A private method to instrument IoTSet of addresses
543 * @params strFieldIdentifier String field name + object ID
544 * @params strFieldName String field name
545 * @params inStream ObjectInputStream communication
546 * @params inStream ObjectOutputStream communication
547 * @params strLanguage String language
550 private void instrumentIoTSetAddress(String strFieldIdentifier, String strFieldName,
551 InputStream inStream, OutputStream outStream, String strLanguage)
552 throws IOException, ClassNotFoundException, InterruptedException {
554 // Get information from the set
555 List<Object[]> listObject = objAddInitHand.getFields(strFieldIdentifier);
556 // Create a new IoTSet
557 if(strLanguage.equals(STR_JAVA)) {
558 Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, strFieldName);
559 commMasterToSlave(msgCrtIoTSet, "Create new IoTSet for IoTAddress!", inStream, outStream);
562 int iRows = listObject.size();
563 RuntimeOutput.print("IoTMaster: Number of rows for IoTAddress: " + iRows, BOOL_VERBOSE);
564 // Transfer the address
565 for(int iRow=0; iRow<iRows; iRow++) {
566 arrFieldValues = listObject.get(iRow);
567 // Get device address
568 String strAddress = (String) arrFieldValues[0];
569 // Send address one by one
570 if(strLanguage.equals(STR_JAVA)) {
571 Message msgGetIoTSetAddObj = new MessageGetSimpleDeviceObject(IoTCommCode.GET_ADD_IOTSET_OBJECT, strAddress);
572 commMasterToSlave(msgGetIoTSetAddObj, "Get IoTSet objects!", inStream, outStream);
573 } else // TODO: Implement IoTSet Address for C++
576 // Reinitialize IoTSet on device object
577 commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTSET_FIELD),
578 "Reinitialize IoTSet fields!", inStream, outStream);
583 * A private method to instrument an object on a specific machine and setting up policies
585 * @params strFieldObjectID String field object ID
586 * @params strObjControllerName String object controller name
587 * @params strLanguage String language
590 private void instrumentObject(String strFieldObjectID, String strObjControllerName, String strLanguage) throws IOException {
592 // Extract the interface name for RMI
593 // e.g. ProximitySensorInterface, TempSensorInterface, etc.
595 String strObjCfgFile = STR_IOT_CODE_PATH + strObjClassName + "/" + strObjClassName + STR_CFG_FILE_EXT;
596 strObjClassInterfaceName = parseConfigFile(strObjCfgFile, STR_INTERFACE_CLS_CFG);
597 strObjStubClsIntfaceName = parseConfigFile(strObjCfgFile, STR_INT_STUB_CLS_CFG);
598 // Create an object name, e.g. ProximitySensorImplPS1
599 strObjName = strObjClassName + strFieldObjectID;
600 // Check first if host exists
601 if(commHan.objectExists(strObjName)) {
602 // If this object exists already ...
603 // Re-read IoTSlave object hostname for further reference
604 strIoTSlaveObjectHostAdd = commHan.getHostAddress(strObjName);
605 RuntimeOutput.print("IoTMaster: Object with name: " + strObjName + " has existed!", BOOL_VERBOSE);
607 // If this is a new object ... then create one
608 // Get host address for IoTSlave from LoadBalancer
609 //strIoTSlaveObjectHostAdd = lbIoT.selectHost();
610 strIoTSlaveObjectHostAdd = routerConfig.getIPFromMACAddress(lbIoT.selectHost());
611 if (strIoTSlaveControllerHostAdd == null)
612 throw new Error("IoTMaster: Could not translate MAC to IP address! Please check the router's /tmp/dhcp.leases!");
613 RuntimeOutput.print("IoTMaster: Object name: " + strObjName, BOOL_VERBOSE);
614 // Add port connection and get port numbers
615 // Naming for objects ProximitySensor becomes ProximitySensor0, ProximitySensor1, etc.
616 commHan.addPortConnection(strIoTSlaveObjectHostAdd, strObjName);
617 commHan.addActiveControllerObject(strFieldObjectID, strObjName, strObjClassName, strObjClassInterfaceName,
618 strObjStubClsIntfaceName, strIoTSlaveObjectHostAdd, arrFieldValues, arrFieldClasses);
619 // ROUTING POLICY: IoTMaster and device/controller object
620 // Master-slave communication
621 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTMasterHostAdd,
622 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjName));
623 // ROUTING POLICY: Send the same routing policy to both the hosts
624 routerConfig.configureHostMainPolicies(strIoTMasterHostAdd, strIoTMasterHostAdd,
625 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjName));
626 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTMasterHostAdd,
627 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjName));
628 // Need to accommodate callback functions here - open ports for TCP
629 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveControllerHostAdd,
630 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
631 routerConfig.configureHostMainPolicies(strIoTSlaveControllerHostAdd, strIoTSlaveControllerHostAdd,
632 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
633 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveControllerHostAdd,
634 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
635 // Configure MAC policies for objects
636 String strFileName = STR_MAC_POL_PATH + strObjClassName + STR_MAC_POLICY_EXT;
637 processJailConfig.configureProcessJailDeviceDriverPolicies(strIoTSlaveObjectHostAdd, strObjName,
638 strFileName, strIoTMasterHostAdd, commHan.getComPort(strObjName), commHan.getRMIRegPort(strObjName),
639 commHan.getRMIStubPort(strObjName));
640 processJailConfig.configureProcessJailContRMIPolicies(strObjControllerName, strIoTSlaveObjectHostAdd,
641 commHan.getRMIRegPort(strObjName), commHan.getRMIStubPort(strObjName));
642 // Instrument the IoTSet declarations inside the class file
643 instrumentObjectIoTSet(strFieldObjectID, strLanguage);
645 // Send routing policy to router for controller object
646 // ROUTING POLICY: RMI communication - RMI registry and stub ports
647 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
648 STR_TCP_PROTOCOL, commHan.getRMIRegPort(strObjName));
649 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
650 STR_TCP_PROTOCOL, commHan.getRMIStubPort(strObjName));
651 // Send the same set of routing policies to compute nodes
652 routerConfig.configureHostMainPolicies(strIoTSlaveControllerHostAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
653 STR_TCP_PROTOCOL, commHan.getRMIRegPort(strObjName));
654 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
655 STR_TCP_PROTOCOL, commHan.getRMIRegPort(strObjName));
656 routerConfig.configureHostMainPolicies(strIoTSlaveControllerHostAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
657 STR_TCP_PROTOCOL, commHan.getRMIStubPort(strObjName));
658 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
659 STR_TCP_PROTOCOL, commHan.getRMIStubPort(strObjName));
664 * A private method to set router policies for IoTDeviceAddress objects
666 * @params strFieldIdentifier String field name + object ID
667 * @params Map.Entry<String,Object> Entry of map IoTSet instrumentation
668 * @params strIoTSlaveObjectHostAdd String slave host address
671 private void setRouterPolicyIoTSetDevice(String strFieldIdentifier, Map.Entry<String,Object> map,
672 String strIoTSlaveObjectHostAdd) {
674 // Get information from the set
675 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
676 int iRows = setInstrumenter.numberOfRows();
677 RuntimeOutput.print("IoTMaster: Number of rows for IoTDeviceAddress: " + iRows, BOOL_VERBOSE);
678 // Transfer the address
679 for(int iRow=0; iRow<iRows; iRow++) {
680 arrFieldValues = setInstrumenter.fieldValues(iRow);
681 objAddInitHand.addField(strFieldIdentifier, arrFieldValues); // Save this for object instantiation
682 // Get device address - if 00:00:00:00:00:00 that means it needs the driver object address (self)
683 String strDeviceAddress = null;
684 String strDeviceAddressKey = null;
685 if (arrFieldValues[0].equals(STR_SELF_MAC_ADD)) {
686 strDeviceAddress = strIoTSlaveObjectHostAdd;
687 strDeviceAddressKey = strObjName + "-" + strIoTSlaveObjectHostAdd;
688 } else { // Concatenate object name and IP address to give unique key - for a case where there is one device for multiple drivers
689 strDeviceAddress = routerConfig.getIPFromMACAddress((String) arrFieldValues[0]);
690 strDeviceAddressKey = strObjName + "-" + strDeviceAddress;
692 int iDestDeviceDriverPort = (int) arrFieldValues[1];
693 String strProtocol = (String) arrFieldValues[2];
694 // Add the port connection into communication handler - if it's not assigned yet
695 if (commHan.getComPort(strDeviceAddressKey) == null)
696 commHan.addPortConnection(strIoTSlaveObjectHostAdd, strDeviceAddressKey);
697 boolean bDstPortWildCard = false;
698 // Recognize this and allocate different ports for it
699 if (arrFieldValues.length > 3) {
700 bDstPortWildCard = (boolean) arrFieldValues[4];
701 if (bDstPortWildCard) { // This needs a unique source port
702 String strUniqueDev = strDeviceAddressKey + ":" + iRow;
703 commHan.addAdditionalPort(strUniqueDev);
708 System.out.println("\n\n DEBUG: InstrumentPolicySetDevice: Object Name: " + strObjName);
709 System.out.println("DEBUG: InstrumentPolicySetDevice: Port number: " + commHan.getComPort(strDeviceAddressKey));
710 System.out.println("DEBUG: InstrumentPolicySetDevice: Device address: " + strDeviceAddressKey + "\n\n");
712 // Send routing policy to router for device drivers and devices
713 // ROUTING POLICY: RMI communication - RMI registry and stub ports
714 if((iDestDeviceDriverPort == -1) && (!strProtocol.equals(STR_NO_PROTOCOL))) {
715 // Port number -1 means that we don't set the policy strictly to port number level
716 // "nopro" = no protocol specified for just TCP or just UDP (can be both used as well)
717 // ROUTING POLICY: Device driver and device
718 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveObjectHostAdd, strDeviceAddress, strProtocol);
719 // ROUTING POLICY: Send to the compute node where the device driver is
720 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress, strProtocol);
721 } else if((iDestDeviceDriverPort == -1) && (strProtocol.equals(STR_NO_PROTOCOL))) {
722 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveObjectHostAdd, strDeviceAddress);
723 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress);
724 } else if(strProtocol.equals(STR_TCPGW_PROTOCOL)) {
725 // This is a TCP protocol that connects, e.g. a phone to our runtime system
726 // that provides a gateway access (accessed through destination port number)
727 commHan.addDevicePort(iDestDeviceDriverPort);
728 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveObjectHostAdd, strDeviceAddress, STR_TCP_PROTOCOL, iDestDeviceDriverPort);
729 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress, STR_TCP_PROTOCOL, iDestDeviceDriverPort);
730 routerConfig.configureRouterHTTPPolicies(STR_ROUTER_ADD, strIoTSlaveObjectHostAdd, strDeviceAddress);
731 routerConfig.configureHostHTTPPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress);
733 // Other port numbers...
734 commHan.addDevicePort(iDestDeviceDriverPort);
735 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveObjectHostAdd, strDeviceAddress, strProtocol,
736 commHan.getComPort(strDeviceAddressKey), iDestDeviceDriverPort);
737 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress, strProtocol,
738 commHan.getComPort(strDeviceAddressKey), iDestDeviceDriverPort);
739 // Configure MAC policies
740 processJailConfig.configureProcessJailDevicePolicies(strIoTSlaveObjectHostAdd, strProtocol,
741 commHan.getComPort(strDeviceAddressKey), strDeviceAddress, iDestDeviceDriverPort);
747 * A private method to set router policies for IoTAddress objects
749 * @params strFieldIdentifier String field name + object ID
750 * @params Map.Entry<String,Object> Entry of map IoTSet instrumentation
751 * @params strHostAddress String host address
754 private void setRouterPolicyIoTSetAddress(String strFieldIdentifier, Map.Entry<String,Object> map,
755 String strHostAddress) {
757 // Get information from the set
758 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
759 int iRows = setInstrumenter.numberOfRows();
760 RuntimeOutput.print("IoTMaster: Number of rows for IoTAddress: " + iRows, BOOL_VERBOSE);
761 // Transfer the address
762 for(int iRow=0; iRow<iRows; iRow++) {
763 arrFieldValues = setInstrumenter.fieldValues(iRow);
764 objAddInitHand.addField(strFieldIdentifier, arrFieldValues); // Save this for object instantiation
765 // Get device address
766 String strAddress = (String) arrFieldValues[0];
767 // Setting up router policies for HTTP/HTTPs
768 routerConfig.configureRouterHTTPPolicies(STR_ROUTER_ADD, strHostAddress, strAddress);
769 routerConfig.configureHostHTTPPolicies(strHostAddress, strHostAddress, strAddress);
774 * A private method to instrument an object's IoTSet and IoTRelation field to up policies
776 * Mostly the IoTSet fields would contain IoTDeviceAddress objects
778 * @params strFieldObjectID String field object ID
779 * @params strLanguage String language
782 private void instrumentObjectIoTSet(String strFieldObjectID, String strLanguage) throws IOException {
784 // If this is a new object ... then create one
785 // Instrument the class source code and look for IoTSet for device addresses
786 // e.g. @config private IoTSet<IoTDeviceAddress> lb_addresses;
787 HashMap<String,Object> hmObjectFieldObjects = null;
788 if(strLanguage.equals(STR_JAVA)) {
789 String strObjectClassNamePath = STR_IOT_CODE_PATH + strObjClassName + "/" + strObjClassName + STR_CLS_FILE_EXT;
790 FileInputStream fis = new FileInputStream(strObjectClassNamePath);
791 ClassReader cr = new ClassReader(fis);
792 ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
793 // We need Object ID to instrument IoTDeviceAddress
794 ClassRuntimeInstrumenterMaster crim = new ClassRuntimeInstrumenterMaster(cw, strFieldObjectID, BOOL_VERBOSE);
797 mapClassNameToCrim.put(strObjClassName + strFieldObjectID, crim);
798 hmObjectFieldObjects = crim.getFieldObjects();
800 String strObjectClassNamePath = STR_IOT_CODE_PATH + strObjClassName + "/" + strObjClassName + STR_CFG_FILE_EXT;
801 CRuntimeInstrumenterMaster crim = new CRuntimeInstrumenterMaster(strObjectClassNamePath, strFieldObjectID, BOOL_VERBOSE);
802 mapClassNameToCrim.put(strObjClassName + strFieldObjectID, crim);
803 hmObjectFieldObjects = crim.getFieldObjects();
805 // Get the object and the class names
806 // Build objects for IoTSet and IoTRelation fields in the device object classes
807 RuntimeOutput.print("IoTMaster: Going to instrument for " + strObjClassName + " with objectID " +
808 strFieldObjectID, BOOL_VERBOSE);
809 for(Map.Entry<String,Object> map : hmObjectFieldObjects.entrySet()) {
810 RuntimeOutput.print("IoTMaster: Object name: " + map.getValue().getClass().getName(), BOOL_VERBOSE);
811 // Iterate over HashMap and choose between processing
812 String strFieldName = map.getKey();
813 String strClassName = map.getValue().getClass().getName();
814 String strFieldIdentifier = strFieldName + strFieldObjectID;
815 if(strClassName.equals(STR_SET_INSTRUMENTER_CLS)) {
816 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
817 if(setInstrumenter.getObjTableName().equals(STR_IOT_DEV_ADD_CLS)) {
818 // Instrument the normal IoTDeviceAddress
819 setRouterPolicyIoTSetDevice(strFieldIdentifier, map, strIoTSlaveObjectHostAdd);
820 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ADD_CLS)) {
821 // Instrument the IoTAddress
822 setRouterPolicyIoTSetAddress(strFieldIdentifier, map, strIoTSlaveObjectHostAdd);
823 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ZB_ADD_CLS)) {
824 // Instrument the IoTZigbeeAddress - special feature for Zigbee device support
825 RuntimeOutput.print("IoTMaster: IoTZigbeeAddress found! No router policy is set here..",
828 String strErrMsg = "IoTMaster: Device driver object" +
829 " can only have IoTSet<IoTAddress>, IoTSet<IoTDeviceAddress>," +
830 " or IoTSet<IoTZigbeeAddress>!";
831 throw new Error(strErrMsg);
834 String strErrMsg = "IoTMaster: Device driver object can only have IoTSet for addresses!";
835 throw new Error(strErrMsg);
842 * A private method to send files to a Java slave driver
844 * @params serverSocket ServerSocket
845 * @params _inStream InputStream
846 * @params _outStream OutputStream
847 * @params strObjName String
848 * @params strObjClassName String
849 * @params strObjClassInterfaceName String
850 * @params strObjStubClsIntfaceName String
851 * @params strIoTSlaveObjectHostAdd String
852 * @params strFieldObjectID String
853 * @params arrFieldValues Object[]
854 * @params arrFieldClasses Class[]
857 private void sendFileToJavaSlaveDriver(ServerSocket serverSocket, InputStream _inStream, OutputStream _outStream,
858 String strObjName, String strObjClassName, String strObjClassInterfaceName, String strObjStubClsIntfaceName,
859 String strIoTSlaveObjectHostAdd, String strFieldObjectID, Object[] arrFieldValues, Class[] arrFieldClasses)
860 throws IOException, ClassNotFoundException {
862 ObjectInputStream inStream = (ObjectInputStream) _inStream;
863 ObjectOutputStream outStream = (ObjectOutputStream) _outStream;
864 // Create message to transfer file first
865 String sFileName = strObjClassName + STR_JAR_FILE_EXT;
866 String sPath = STR_IOT_CODE_PATH + strObjClassName + "/" + sFileName;
867 File file = new File(sPath);
868 commMasterToSlave(new MessageSendFile(IoTCommCode.TRANSFER_FILE, sFileName, file.length()),
869 "Sending file!", inStream, outStream);
870 // Send file - JAR file for object creation
871 sendFile(serverSocket.accept(), sPath, file.length());
872 Message msgReply = (Message) inStream.readObject();
873 RuntimeOutput.print("IoTMaster: Reply message: " + msgReply.getMessage(), BOOL_VERBOSE);
874 // Pack object information to create object on a IoTSlave
875 Message msgObjIoTSlave = new MessageCreateObject(IoTCommCode.CREATE_OBJECT, strIoTSlaveObjectHostAdd,
876 strObjClassName, strObjName, strObjClassInterfaceName, strObjStubClsIntfaceName, commHan.getRMIRegPort(strObjName),
877 commHan.getRMIStubPort(strObjName), arrFieldValues, arrFieldClasses);
879 commMasterToSlave(msgObjIoTSlave, "Sending object information", inStream, outStream);
884 * A private method to send files to a Java slave driver
888 private void sendFileToCppSlaveDriver(String strObjClassName, String strIoTSlaveObjectHostAdd)
889 throws IOException, ClassNotFoundException {
891 // Create message to transfer file first
892 String sFileName = strObjClassName + STR_ZIP_FILE_EXT;
893 String sFile = STR_IOT_CODE_PATH + strObjClassName + "/" + sFileName;
894 String strCmdSend = STR_SCP + " " + sFile + " " + STR_USERNAME + strIoTSlaveObjectHostAdd + ":" + STR_SLAVE_DIR;
895 runCommand(strCmdSend);
896 RuntimeOutput.print("IoTMaster: Executing: " + strCmdSend, BOOL_VERBOSE);
898 String strCmdUnzip = STR_SSH + " " + STR_USERNAME + strIoTSlaveObjectHostAdd + " cd " +
899 STR_SLAVE_DIR + " sudo unzip -o " + sFileName + ";";
900 runCommand(strCmdUnzip);
901 RuntimeOutput.print("IoTMaster: Executing: " + strCmdUnzip, BOOL_VERBOSE);
907 * Construct command line for Java IoTSlave
911 private String getCmdJavaDriverIoTSlave(String strIoTMasterHostAdd, String strIoTSlaveObjectHostAdd, String strObjName) {
913 // Create an Shell executable
914 String strJavaCommand = STR_SHELL_HEADER + "\nexec " + STR_JAVA_PATH + " " + STR_CLS_PATH + " " + STR_RMI_PATH + " " +
915 STR_RMI_HOSTNAME + strIoTSlaveObjectHostAdd + " " + STR_IOT_SLAVE_CLS + " " + strIoTMasterHostAdd + " " +
916 commHan.getComPort(strObjName) + " " + commHan.getRMIRegPort(strObjName) + " " +
917 commHan.getRMIStubPort(strObjName) + " > " + STR_LOG_FILE_PATH + strObjName + ".log &";
918 String shellFile = "./" + strObjName + STR_SHELL_FILE_EXT;
919 createWrapperShellScript(strJavaCommand, shellFile);
920 // Send the file to the compute node
921 String strCmdSend = "scp " + shellFile + " " + STR_USERNAME + strIoTSlaveObjectHostAdd + ":" + STR_RUNTIME_DIR;
922 runCommand(strCmdSend);
923 System.out.println("IoTMaster: Sending shell file: " + strCmdSend);
924 return STR_SSH + " " + STR_USERNAME + strIoTSlaveObjectHostAdd + " cd " + STR_RUNTIME_DIR + " " + shellFile;
929 * Construct command line for C++ IoTSlave
933 private String getCmdCppDriverIoTSlave(String strIoTMasterHostAdd, String strIoTSlaveObjectHostAdd, String strObjName) {
935 return STR_SSH + " " + STR_USERNAME + strIoTSlaveObjectHostAdd + " cd " +
936 STR_SLAVE_DIR + " sudo " + STR_IOTSLAVE_CPP + " " + strIoTMasterHostAdd + " " +
937 commHan.getComPort(strObjName) + " " + strObjName;
942 * createWrapperShellScript() gets a wrapper shell script
944 * @param strCommand String command
945 * @param strObjectName String object name
946 * @return PrintWriter
948 private void createWrapperShellScript(String strCommand, String strFileName) {
950 PrintWriter printWriter = getPrintWriter(strFileName);
951 printWriter.println(strCommand);
953 runCommand("chmod 755 " + strFileName);
958 * A private method to create an object on a specific machine
960 * @params strObjName String object name
961 * @params strObjClassName String object class name
962 * @params strObjClassInterfaceName String object class interface name
963 * @params strIoTSlaveObjectHostAdd String IoTSlave host address
964 * @params strFieldObjectID String field object ID
965 * @params arrFieldValues Array of field values
966 * @params arrFieldClasses Array of field classes
969 private void createObject(String strObjName, String strObjClassName, String strObjClassInterfaceName, String strObjStubClsIntfaceName,
970 String strIoTSlaveObjectHostAdd, String strFieldObjectID, Object[] arrFieldValues, Class[] arrFieldClasses)
971 throws IOException, FileNotFoundException, ClassNotFoundException, InterruptedException {
974 String sCfgFile = STR_IOT_CODE_PATH + strObjClassName + "/" + strObjClassName + STR_CFG_FILE_EXT;
975 String strLanguageDriver = parseConfigFile(sCfgFile, STR_LANGUAGE + "_" + strObjName);
976 if(strLanguageDriver == null) // Read just the field LANGUAGE if the first read is null
977 strLanguageDriver = parseConfigFile(sCfgFile, STR_LANGUAGE);
978 if(strLanguageDriver == null) // Check nullness for the second time - report if it is still null
979 throw new Error("IoTMaster: Language specification missing in config file: " + sCfgFile);
984 start = System.currentTimeMillis();
986 // Construct ssh command line
987 // e.g. ssh rtrimana@dw-2.eecs.uci.edu cd <path>;
988 // java -cp $CLASSPATH:./*.jar
989 // -Djava.rmi.server.codebase=file:./*.jar
990 // iotruntime.IoTSlave dw-1.eecs.uci.edu 46151 23829 42874 &
991 // The In-Port for IoTMaster is the Out-Port for IoTSlave and vice versa
992 String strSSHCommand = null;
993 if(strLanguageDriver.equals(STR_JAVA))
994 strSSHCommand = getCmdJavaDriverIoTSlave(strIoTMasterHostAdd, strIoTSlaveObjectHostAdd, strObjName);
995 else if(strLanguageDriver.equals(STR_CPP))
996 strSSHCommand = getCmdCppDriverIoTSlave(strIoTMasterHostAdd, strIoTSlaveObjectHostAdd, strObjName);
998 throw new Error("IoTMaster: Language specification not recognized: " + strLanguageDriver);
999 RuntimeOutput.print("IoTMaster: Language for " + strObjName + " is " + strLanguageDriver, BOOL_VERBOSE);
1001 RuntimeOutput.print(strSSHCommand, BOOL_VERBOSE);
1002 // Start a new thread to start a new JVM
1003 createThread(strSSHCommand);
1004 ServerSocket serverSocket = new ServerSocket(commHan.getComPort(strObjName));
1005 Socket socket = serverSocket.accept();
1006 //InputStream inStream = new ObjectInputStream(socket.getInputStream());
1007 //OutputStream outStream = new ObjectOutputStream(socket.getOutputStream());
1008 InputStream inStream = null;
1009 OutputStream outStream = null;
1010 if(strLanguageDriver.equals(STR_JAVA)) {
1011 inStream = new ObjectInputStream(socket.getInputStream());
1012 outStream = new ObjectOutputStream(socket.getOutputStream());
1013 } else { // At this point the language is certainly C++, otherwise would've complained above
1014 inStream = new BufferedInputStream(socket.getInputStream());
1015 outStream = new BufferedOutputStream(socket.getOutputStream());
1020 result = System.currentTimeMillis()-start;
1021 System.out.println("\n\n ==> Time needed to start JVM for " + strObjName + ": " + result + "\n\n");
1024 start = System.currentTimeMillis();
1026 if(strLanguageDriver.equals(STR_JAVA)) {
1027 sendFileToJavaSlaveDriver(serverSocket, inStream, outStream, strObjName,
1028 strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName,
1029 strIoTSlaveObjectHostAdd, strFieldObjectID, arrFieldValues, arrFieldClasses);
1031 sendFileToCppSlaveDriver(strObjClassName, strIoTSlaveObjectHostAdd);
1032 createObjectCpp(strObjName, strObjClassName, strObjClassInterfaceName, strIoTSlaveObjectHostAdd,
1033 commHan.getRMIRegPort(strObjName), commHan.getRMIStubPort(strObjName), arrFieldValues, arrFieldClasses,
1034 outStream, inStream);
1038 result = System.currentTimeMillis()-start;
1039 System.out.println("\n\n ==> Time needed to send JAR file for " + strObjName + ": " + result + "\n\n");
1042 start = System.currentTimeMillis();
1044 // Instrument the class source code and look for IoTSet for device addresses
1045 // e.g. @config private IoTSet<IoTDeviceAddress> lb_addresses;
1046 RuntimeOutput.print("IoTMaster: Instantiating for " + strObjClassName + " with objectID " + strFieldObjectID, BOOL_VERBOSE);
1047 // Get the object and the class names
1048 // Build objects for IoTSet and IoTRelation fields in the device object classes
1049 Object crimObj = mapClassNameToCrim.get(strObjClassName + strFieldObjectID);
1050 HashMap<String,Object> hmObjectFieldObjects = null;
1051 if (crimObj instanceof ClassRuntimeInstrumenterMaster) {
1052 ClassRuntimeInstrumenterMaster crim = (ClassRuntimeInstrumenterMaster) crimObj;
1053 hmObjectFieldObjects = crim.getFieldObjects();
1054 } else if (crimObj instanceof CRuntimeInstrumenterMaster) {
1055 CRuntimeInstrumenterMaster crim = (CRuntimeInstrumenterMaster) crimObj;
1056 hmObjectFieldObjects = crim.getFieldObjects();
1058 for(Map.Entry<String,Object> map : hmObjectFieldObjects.entrySet()) {
1059 RuntimeOutput.print("IoTMaster: Object name: " + map.getValue().getClass().getName(), BOOL_VERBOSE);
1060 // Iterate over HashMap and choose between processing
1061 String strFieldName = map.getKey();
1062 String strClassName = map.getValue().getClass().getName();
1063 String strFieldIdentifier = strFieldName + strFieldObjectID;
1064 if(strClassName.equals(STR_SET_INSTRUMENTER_CLS)) {
1065 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
1066 if(setInstrumenter.getObjTableName().equals(STR_IOT_DEV_ADD_CLS)) {
1067 // Instrument the normal IoTDeviceAddress
1068 synchronized(this) {
1069 instrumentIoTSetDevice(strFieldIdentifier, strObjName, strFieldName, strIoTSlaveObjectHostAdd, inStream, outStream, strLanguageDriver);
1071 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ZB_ADD_CLS)) {
1072 // Instrument the IoTZigbeeAddress - special feature for Zigbee device support
1073 synchronized(this) {
1074 instrumentIoTSetZBDevice(map, strObjName, strFieldName, strIoTSlaveObjectHostAdd, inStream, outStream, strLanguageDriver);
1076 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ADD_CLS)) {
1077 // Instrument the IoTAddress
1078 synchronized(this) {
1079 instrumentIoTSetAddress(strFieldIdentifier, strFieldName, inStream, outStream, strLanguageDriver);
1082 String strErrMsg = "IoTMaster: Device driver object can only have IoTSet<IoTAddress>, IoTSet<IoTDeviceAddress>," +
1083 " or IoTSet<IoTZigbeeAddress>!";
1084 throw new Error(strErrMsg);
1087 String strErrMsg = "IoTMaster: Device driver object can only have IoTSet for addresses!";
1088 throw new Error(strErrMsg);
1092 // TODO: Change this later
1093 if(strLanguageDriver.equals(STR_JAVA)) {
1094 ObjectOutputStream oStream = (ObjectOutputStream) outStream;
1095 oStream.writeObject(new MessageSimple(IoTCommCode.END_SESSION));
1096 } else { // C++ side for now will be running continuously because it's an infinite loop (not in a separate thread)
1097 createDriverObjectCpp(outStream, inStream);
1098 //endSessionCpp(outStream);
1102 result = System.currentTimeMillis()-start;
1103 System.out.println("\n\n ==> Time needed to create object " + strObjName + " and instrument IoTDeviceAddress: " + result + "\n\n");
1109 serverSocket.close();
1114 * A private method to create controller objects
1118 private void createDriverObjects() throws InterruptedException {
1120 // Create a list of threads
1121 List<Thread> threads = new ArrayList<Thread>();
1122 // Get the list of active controller objects and loop it
1123 List<String> listActiveControllerObject = commHan.getActiveControllerObjectList();
1124 for(String strObjName : listActiveControllerObject) {
1126 ObjectCreationInfo objCrtInfo = commHan.getObjectCreationInfo(strObjName);
1127 Thread objectThread = new Thread(new Runnable() {
1129 synchronized(this) {
1131 createObject(strObjName, objCrtInfo.getObjectClassName(), objCrtInfo.getObjectClassInterfaceName(),
1132 objCrtInfo.getObjectStubClassInterfaceName(), objCrtInfo.getIoTSlaveObjectHostAdd(),
1133 commHan.getFieldObjectID(strObjName), commHan.getArrayFieldValues(strObjName),
1134 commHan.getArrayFieldClasses(strObjName));
1135 } catch (IOException |
1136 ClassNotFoundException |
1137 InterruptedException ex) {
1138 ex.printStackTrace();
1143 threads.add(objectThread);
1144 objectThread.start();
1147 for (Thread thread : threads) {
1150 } catch (InterruptedException ex) {
1151 ex.printStackTrace();
1158 * A private method to instrument IoTSet
1160 * @params Map.Entry<String,Object> Entry of map IoTSet instrumentation
1161 * @params strFieldName String field name
1162 * @params strLanguage String language
1165 private void instrumentIoTSet(Map.Entry<String,Object> map, String strFieldName, String strObjControllerName, String strLanguage)
1166 throws IOException, ClassNotFoundException, InterruptedException {
1168 // Get information from the set
1169 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
1170 objInitHand.addField(strFieldName, IoTCommCode.CREATE_NEW_IOTSET);
1172 int iRows = setInstrumenter.numberOfRows();
1173 for(int iRow=0; iRow<iRows; iRow++) {
1174 // Get field classes and values
1175 arrFieldClasses = setInstrumenter.fieldClasses(iRow);
1176 arrFieldValues = setInstrumenter.fieldValues(iRow);
1177 // Get object ID and class name
1178 String strObjID = setInstrumenter.fieldObjectID(iRow);
1179 strObjClassName = setInstrumenter.fieldEntryType(strObjID);
1180 // Call the method to create an object
1181 instrumentObject(strObjID, strObjControllerName, strLanguage);
1182 objInitHand.addObjectIntoField(strFieldName, strIoTSlaveObjectHostAdd, strObjName,
1183 strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName, commHan.getRMIRegPort(strObjName),
1184 commHan.getRMIStubPort(strObjName));
1190 * A private method to instrument IoTRelation
1192 * @params Map.Entry<String,Object> Entry of map IoTRelation instrumentation
1193 * @params strFieldName String field name
1194 * @params strLanguage String language
1197 private void instrumentIoTRelation(Map.Entry<String,Object> map, String strFieldName, String strObjControllerName, String strLanguage)
1198 throws IOException, ClassNotFoundException, InterruptedException {
1200 // Get information from the set
1201 RelationInstrumenter relationInstrumenter = (RelationInstrumenter) map.getValue();
1202 int iRows = relationInstrumenter.numberOfRows();
1203 objInitHand.addField(strFieldName, IoTCommCode.CREATE_NEW_IOTRELATION);
1205 for(int iRow=0; iRow<iRows; iRow++) {
1206 // Operate on the first set first
1207 arrFieldClasses = relationInstrumenter.firstFieldClasses(iRow);
1208 arrFieldValues = relationInstrumenter.firstFieldValues(iRow);
1209 String strObjID = relationInstrumenter.firstFieldObjectID(iRow);
1210 strObjClassName = relationInstrumenter.firstEntryFieldType(strObjID);
1211 // Call the method to create an object
1212 instrumentObject(strObjID, strObjControllerName, strLanguage);
1213 // Get the first object controller host address
1214 String strFirstIoTSlaveObjectHostAdd = strIoTSlaveObjectHostAdd;
1215 objInitHand.addObjectIntoField(strFieldName, strIoTSlaveObjectHostAdd, strObjName,
1216 strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName,
1217 commHan.getRMIRegPort(strObjName), commHan.getRMIStubPort(strObjName));
1218 // Operate on the second set
1219 arrFieldClasses = relationInstrumenter.secondFieldClasses(iRow);
1220 arrFieldValues = relationInstrumenter.secondFieldValues(iRow);
1221 strObjID = relationInstrumenter.secondFieldObjectID(iRow);
1222 strObjClassName = relationInstrumenter.secondEntryFieldType(strObjID);
1223 // Call the method to create an object
1224 instrumentObject(strObjID, strObjControllerName, strLanguage);
1225 // Get the second object controller host address
1226 String strSecondIoTSlaveObjectHostAdd = strIoTSlaveObjectHostAdd;
1227 objInitHand.addSecondObjectIntoField(strFieldName, strIoTSlaveObjectHostAdd, strObjName,
1228 strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName,
1229 commHan.getRMIRegPort(strObjName), commHan.getRMIStubPort(strObjName));
1230 // ROUTING POLICY: first and second controller objects in IoTRelation
1231 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strFirstIoTSlaveObjectHostAdd,
1232 strSecondIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
1233 // ROUTING POLICY: Send the same routing policy to both the hosts
1234 routerConfig.configureHostMainPolicies(strFirstIoTSlaveObjectHostAdd, strFirstIoTSlaveObjectHostAdd,
1235 strSecondIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
1236 routerConfig.configureHostMainPolicies(strSecondIoTSlaveObjectHostAdd, strFirstIoTSlaveObjectHostAdd,
1237 strSecondIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
1242 * A method to reinitialize IoTSet and IoTRelation in the code based on ObjectInitHandler information
1244 * @params inStream ObjectInputStream communication
1245 * @params outStream ObjectOutputStream communication
1248 private void initializeSetsAndRelationsJava(InputStream inStream, OutputStream outStream)
1249 throws IOException, ClassNotFoundException {
1250 // Get list of fields
1251 List<String> strFields = objInitHand.getListOfFields();
1252 // Iterate on HostAddress
1253 for(String str : strFields) {
1254 IoTCommCode iotcommMsg = objInitHand.getFieldMessage(str);
1255 if (iotcommMsg == IoTCommCode.CREATE_NEW_IOTSET) {
1256 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO CREATE IOTSET
1257 Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, str);
1258 commMasterToSlave(msgCrtIoTSet, "Create new IoTSet!", inStream, outStream);
1259 List<ObjectInitInfo> listObject = objInitHand.getListObjectInitInfo(str);
1260 for (ObjectInitInfo objInitInfo : listObject) {
1261 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTSET
1262 commMasterToSlave(new MessageGetObject(IoTCommCode.GET_IOTSET_OBJECT, objInitInfo.getIoTSlaveObjectHostAdd(),
1263 objInitInfo.getObjectName(), objInitInfo.getObjectClassName(), objInitInfo.getObjectClassInterfaceName(),
1264 objInitInfo.getObjectStubClassInterfaceName(), objInitInfo.getRMIRegistryPort(), objInitInfo.getRMIStubPort()),
1265 "Get IoTSet object!", inStream, outStream);
1268 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO REINITIALIZE IOTSET FIELD
1269 commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTSET_FIELD),
1270 "Renitialize IoTSet field!", inStream, outStream);
1271 } else if (iotcommMsg == IoTCommCode.CREATE_NEW_IOTRELATION) {
1272 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO CREATE IOTRELATION
1273 Message msgCrtIoTRel = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTRELATION, str);
1274 commMasterToSlave(msgCrtIoTRel, "Create new IoTRelation!", inStream, outStream);
1275 List<ObjectInitInfo> listObject = objInitHand.getListObjectInitInfo(str);
1276 List<ObjectInitInfo> listSecondObject = objInitHand.getSecondObjectInitInfo(str);
1277 Iterator it = listSecondObject.iterator();
1278 for (ObjectInitInfo objInitInfo : listObject) {
1279 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTRELATION (FIRST OBJECT)
1280 commMasterToSlave(new MessageGetObject(IoTCommCode.GET_IOTRELATION_FIRST_OBJECT,
1281 objInitInfo.getIoTSlaveObjectHostAdd(), objInitInfo.getObjectName(), objInitInfo.getObjectClassName(),
1282 objInitInfo.getObjectClassInterfaceName(), objInitInfo.getObjectStubClassInterfaceName(),
1283 objInitInfo.getRMIRegistryPort(), objInitInfo.getRMIStubPort()),
1284 "Get IoTRelation first object!", inStream, outStream);
1285 ObjectInitInfo objSecObj = (ObjectInitInfo) it.next();
1286 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTRELATION (SECOND OBJECT)
1287 commMasterToSlave(new MessageGetObject(IoTCommCode.GET_IOTRELATION_SECOND_OBJECT,
1288 objSecObj.getIoTSlaveObjectHostAdd(), objSecObj.getObjectName(), objSecObj.getObjectClassName(),
1289 objSecObj.getObjectClassInterfaceName(), objSecObj.getObjectStubClassInterfaceName(),
1290 objSecObj.getRMIRegistryPort(), objSecObj.getRMIStubPort()),
1291 "Get IoTRelation second object!", inStream, outStream);
1293 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO REINITIALIZE IOTRELATION FIELD
1294 commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTRELATION_FIELD),
1295 "Renitialize IoTRelation field!", inStream, outStream);
1301 * A method to reinitialize IoTSet and IoTRelation in the code based on ObjectInitHandler information
1303 * @params inStream ObjectInputStream communication
1304 * @params outStream ObjectOutputStream communication
1307 private void initializeSetsAndRelationsCpp(InputStream inStream, OutputStream outStream)
1308 throws IOException, ClassNotFoundException {
1309 // Get list of fields
1310 List<String> strFields = objInitHand.getListOfFields();
1311 // Iterate on HostAddress
1312 for(String str : strFields) {
1313 IoTCommCode iotcommMsg = objInitHand.getFieldMessage(str);
1314 if (iotcommMsg == IoTCommCode.CREATE_NEW_IOTSET) {
1315 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO CREATE IOTSET
1316 createNewIoTSetCpp(str, outStream, inStream);
1317 List<ObjectInitInfo> listObject = objInitHand.getListObjectInitInfo(str);
1318 for (ObjectInitInfo objInitInfo : listObject) {
1319 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTSET
1320 getIoTSetRelationObjectCpp(IoTCommCode.GET_IOTSET_OBJECT, objInitInfo.getIoTSlaveObjectHostAdd(), objInitInfo.getObjectName(),
1321 objInitInfo.getObjectClassName(), objInitInfo.getObjectClassInterfaceName(), objInitInfo.getObjectStubClassInterfaceName(),
1322 objInitInfo.getRMIRegistryPort(), objInitInfo.getRMIStubPort(), outStream, inStream);
1324 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO REINITIALIZE IOTSET FIELD
1325 reinitializeIoTSetFieldCpp(outStream, inStream);
1326 } else if (iotcommMsg == IoTCommCode.CREATE_NEW_IOTRELATION) {
1327 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO CREATE IOTRELATION
1328 // TODO: createNewIoTRelation needs to be created here!
1329 createNewIoTRelationCpp(str, outStream, inStream);
1330 List<ObjectInitInfo> listObject = objInitHand.getListObjectInitInfo(str);
1331 List<ObjectInitInfo> listSecondObject = objInitHand.getSecondObjectInitInfo(str);
1332 Iterator it = listSecondObject.iterator();
1333 for (ObjectInitInfo objInitInfo : listObject) {
1334 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTRELATION (FIRST OBJECT)
1335 getIoTSetRelationObjectCpp(IoTCommCode.GET_IOTRELATION_FIRST_OBJECT, objInitInfo.getIoTSlaveObjectHostAdd(), objInitInfo.getObjectName(),
1336 objInitInfo.getObjectClassName(), objInitInfo.getObjectClassInterfaceName(), objInitInfo.getObjectStubClassInterfaceName(),
1337 objInitInfo.getRMIRegistryPort(), objInitInfo.getRMIStubPort(), outStream, inStream);
1338 ObjectInitInfo objSecObj = (ObjectInitInfo) it.next();
1339 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTRELATION (SECOND OBJECT)
1340 getIoTSetRelationObjectCpp(IoTCommCode.GET_IOTRELATION_SECOND_OBJECT, objSecObj.getIoTSlaveObjectHostAdd(), objSecObj.getObjectName(),
1341 objSecObj.getObjectClassName(), objSecObj.getObjectClassInterfaceName(), objSecObj.getObjectStubClassInterfaceName(),
1342 objSecObj.getRMIRegistryPort(), objSecObj.getRMIStubPort(), outStream, inStream);
1344 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO REINITIALIZE IOTRELATION FIELD
1345 reinitializeIoTRelationFieldCpp(outStream, inStream);
1351 * A method to set router basic policies at once
1353 * @param strRouter String router name
1356 private void setRouterBasicPolicies(String strRouter) {
1358 String strMonitorHost = routerConfig.getIPFromMACAddress(STR_MONITORING_HOST);
1359 routerConfig.configureRouterICMPPolicies(strRouter, strMonitorHost);
1360 routerConfig.configureRouterDHCPPolicies(strRouter);
1361 routerConfig.configureRouterDNSPolicies(strRouter);
1362 routerConfig.configureRouterSSHPolicies(strRouter, strMonitorHost);
1363 routerConfig.configureRejectPolicies(strRouter);
1367 * A method to set host basic policies at once
1369 * @param strHost String host name
1372 private void setHostBasicPolicies(String strHost) {
1374 String strMonitorHost = routerConfig.getIPFromMACAddress(STR_MONITORING_HOST);
1375 routerConfig.configureHostDHCPPolicies(strHost);
1376 routerConfig.configureHostDNSPolicies(strHost);
1377 if (strHost.equals(strMonitorHost)) {
1378 // Check if this is the monitoring host
1379 routerConfig.configureHostICMPPolicies(strHost);
1380 routerConfig.configureHostSSHPolicies(strHost);
1382 routerConfig.configureHostICMPPolicies(strHost, strMonitorHost);
1383 routerConfig.configureHostSSHPolicies(strHost, strMonitorHost);
1385 // Apply SQL allowance policies to master host
1386 if (strHost.equals(strIoTMasterHostAdd)) {
1387 routerConfig.configureHostSQLPolicies(strHost);
1389 routerConfig.configureRejectPolicies(strHost);
1393 * A method to create a thread for policy deployment
1395 * @param strRouterAddress String router address to configure
1396 * @param setHostAddresses Set of strings for host addresses to configure
1399 private void createPolicyThreads(String strRouterAddress, Set<String> setHostAddresses) throws IOException {
1401 // Create a list of threads
1402 List<Thread> threads = new ArrayList<Thread>();
1403 // Start threads for hosts
1404 for(String strAddress : setHostAddresses) {
1405 Thread policyThread = new Thread(new Runnable() {
1407 synchronized(this) {
1408 routerConfig.sendHostPolicies(strAddress);
1412 threads.add(policyThread);
1413 policyThread.start();
1414 RuntimeOutput.print("Deploying policies for: " + strAddress, BOOL_VERBOSE);
1416 // A thread for router
1417 Thread policyThread = new Thread(new Runnable() {
1419 synchronized(this) {
1420 routerConfig.sendRouterPolicies(strRouterAddress);
1424 threads.add(policyThread);
1425 policyThread.start();
1426 RuntimeOutput.print("Deploying policies on router: " + strRouterAddress, BOOL_VERBOSE);
1428 for (Thread thread : threads) {
1431 } catch (InterruptedException ex) {
1432 ex.printStackTrace();
1438 * A method to create a thread for policy deployment
1440 * @param setHostAddresses Set of strings for host addresses to configure
1443 private void createMACPolicyThreads(Set<String> setHostAddresses) throws IOException {
1445 // Create a list of threads
1446 List<Thread> threads = new ArrayList<Thread>();
1447 // Start threads for hosts
1448 for(String strAddress : setHostAddresses) {
1449 Thread policyThread = new Thread(new Runnable() {
1451 synchronized(this) {
1452 processJailConfig.sendMACPolicies(strAddress);
1456 threads.add(policyThread);
1457 policyThread.start();
1458 RuntimeOutput.print("Deploying MAC policies for: " + strAddress, BOOL_VERBOSE);
1461 for (Thread thread : threads) {
1464 } catch (InterruptedException ex) {
1465 ex.printStackTrace();
1472 * A method to send files to Java IoTSlave
1474 * @params strObjControllerName String
1475 * @params serverSocket ServerSocket
1476 * @params inStream ObjectInputStream communication
1477 * @params outStream ObjectOutputStream communication
1480 private void sendFileToJavaSlave(String strObjControllerName, ServerSocket serverSocket,
1481 InputStream _inStream, OutputStream _outStream) throws IOException, ClassNotFoundException {
1483 ObjectInputStream inStream = (ObjectInputStream) _inStream;
1484 ObjectOutputStream outStream = (ObjectOutputStream) _outStream;
1486 String strControllerJarName = strObjControllerName + STR_JAR_FILE_EXT;
1487 String strControllerJarNamePath = STR_CONT_PATH + strObjControllerName + "/" +
1488 strControllerJarName;
1489 File file = new File(strControllerJarNamePath);
1490 commMasterToSlave(new MessageSendFile(IoTCommCode.TRANSFER_FILE, strControllerJarName, file.length()),
1491 "Sending file!", inStream, outStream);
1492 // Send file - Class file for object creation
1493 sendFile(serverSocket.accept(), strControllerJarNamePath, file.length());
1494 Message msgReply = (Message) inStream.readObject();
1495 RuntimeOutput.print("IoTMaster: Reply message: " + msgReply.getMessage(), BOOL_VERBOSE);
1496 // Send .zip file if additional zip file is specified
1497 String strObjCfgFile = strObjControllerName + STR_CFG_FILE_EXT;
1498 String strObjCfgFilePath = STR_CONT_PATH + strObjControllerName + "/" + strObjCfgFile;
1499 String strAdditionalFile = parseConfigFile(strObjCfgFilePath, STR_FILE_TRF_CFG);
1500 if (strAdditionalFile.equals(STR_YES)) {
1501 String strControllerCmpName = strObjControllerName + STR_ZIP_FILE_EXT;
1502 String strControllerCmpNamePath = STR_CONT_PATH + strObjControllerName + "/" +
1503 strControllerCmpName;
1504 file = new File(strControllerCmpNamePath);
1505 commMasterToSlave(new MessageSendFile(IoTCommCode.TRANSFER_FILE, strControllerCmpName, file.length()),
1506 "Sending file!", inStream, outStream);
1507 // Send file - Class file for object creation
1508 sendFile(serverSocket.accept(), strControllerCmpNamePath, file.length());
1509 msgReply = (Message) inStream.readObject();
1510 RuntimeOutput.print("IoTMaster: Reply message: " + msgReply.getMessage(), BOOL_VERBOSE);
1516 * A method to send files to C++ IoTSlave
1519 * TODO: Need to look into this (as of now, file transferred retains the "data" format,
1520 * hence it is unreadable from outside world
1522 private void sendFileToCppSlave(String sFilePath, String sFileName, Socket fileSocket,
1523 InputStream inStream, OutputStream outStream) throws IOException {
1525 sendCommCode(IoTCommCode.TRANSFER_FILE, outStream, inStream);
1527 sendString(sFileName, outStream); recvAck(inStream);
1528 File file = new File(sFilePath + sFileName);
1529 int iFileLen = toIntExact(file.length());
1530 RuntimeOutput.print("IoTMaster: Sending file " + sFileName + " with length " + iFileLen + " bytes...", BOOL_VERBOSE);
1532 sendInteger(iFileLen, outStream); recvAck(inStream);
1533 RuntimeOutput.print("IoTMaster: Sent file size!", BOOL_VERBOSE);
1534 byte[] bytFile = new byte[iFileLen];
1535 InputStream inFileStream = new FileInputStream(file);
1536 RuntimeOutput.print("IoTMaster: Opened file!", BOOL_VERBOSE);
1538 OutputStream outFileStream = fileSocket.getOutputStream();
1539 RuntimeOutput.print("IoTMaster: Got output stream!", BOOL_VERBOSE);
1541 while ((iCount = inFileStream.read(bytFile)) > 0) {
1542 outFileStream.write(bytFile, 0, iCount);
1544 RuntimeOutput.print("IoTMaster: File sent!", BOOL_VERBOSE);
1550 * A method to send files to C++ IoTSlave (now master using Process() to start
1551 * file transfer using scp)
1555 private void sendFileToCppSlave(String sFilePath, String sFileName) throws IOException {
1557 // Construct shell command to transfer file
1558 String sFile = sFilePath + sFileName;
1559 String strCmdSend = STR_SCP + " " + sFile + " " + STR_USERNAME + strIoTSlaveControllerHostAdd + ":" + STR_SLAVE_DIR;
1560 runCommand(strCmdSend);
1561 RuntimeOutput.print("IoTMaster: Executing: " + strCmdSend, BOOL_VERBOSE);
1563 String strCmdUnzip = STR_SSH + " " + STR_USERNAME + strIoTSlaveControllerHostAdd + " cd " +
1564 STR_SLAVE_DIR + " sudo unzip -o " + sFileName + ";";
1565 runCommand(strCmdUnzip);
1566 RuntimeOutput.print("IoTMaster: Executing: " + strCmdUnzip, BOOL_VERBOSE);
1571 * runCommand() method runs shell command
1573 * @param strCommand String that contains command line
1576 private void runCommand(String strCommand) {
1579 Runtime runtime = Runtime.getRuntime();
1580 Process process = runtime.exec(strCommand);
1582 } catch (IOException ex) {
1583 System.out.println("RouterConfig: IOException: " + ex.getMessage());
1584 ex.printStackTrace();
1585 } catch (InterruptedException ex) {
1586 System.out.println("RouterConfig: InterruptException: " + ex.getMessage());
1587 ex.printStackTrace();
1593 * Construct command line for Java IoTSlave
1597 private String getCmdJavaIoTSlave(String strObjControllerName) {
1599 // Create an Shell executable
1600 String strJavaCommand = STR_SHELL_HEADER + "\nexec " + STR_JAVA_PATH + " " + STR_JVM_INIT_HEAP_SIZE + " " +
1601 STR_JVM_MAX_HEAP_SIZE + " " + STR_CLS_PATH + " " + STR_RMI_PATH + " " + STR_IOT_SLAVE_CLS + " " +
1602 strIoTMasterHostAdd + " " + commHan.getComPort(strObjControllerName) + " " +
1603 commHan.getRMIRegPort(strObjControllerName) + " " + commHan.getRMIStubPort(strObjControllerName) +
1604 " > " + STR_LOG_FILE_PATH + strObjControllerName + ".log &";
1605 String shellFile = "./" + strObjControllerName + STR_SHELL_FILE_EXT;
1606 createWrapperShellScript(strJavaCommand, shellFile);
1607 // Send the file to the compute node
1608 String strCmdSend = "scp " + shellFile + " " + STR_USERNAME + strIoTSlaveControllerHostAdd + ":" + STR_RUNTIME_DIR;
1609 runCommand(strCmdSend);
1610 System.out.println("IoTMaster: Sending main controller shell file: " + strCmdSend);
1611 return STR_SSH + " " + STR_USERNAME + strIoTSlaveControllerHostAdd + " cd " + STR_RUNTIME_DIR + " " + shellFile;
1616 * Construct command line for C++ IoTSlave
1620 private String getCmdCppIoTSlave(String strObjControllerName) {
1622 return STR_SSH + " " + STR_USERNAME + strIoTSlaveControllerHostAdd + " cd " +
1623 STR_SLAVE_DIR + " sudo " + STR_IOTSLAVE_CPP + " " + strIoTMasterHostAdd + " " +
1624 commHan.getComPort(strObjControllerName) + " " + strObjControllerName;
1629 * sendInteger() sends an integer in bytes
1631 public void sendInteger(int intSend, OutputStream outStream) throws IOException {
1633 BufferedOutputStream output = (BufferedOutputStream) outStream;
1634 // Transform integer into bytes
1635 ByteBuffer bb = ByteBuffer.allocate(INT_SIZE);
1637 // Send the byte array
1638 output.write(bb.array(), 0, INT_SIZE);
1644 * recvInteger() receives integer in bytes
1646 public int recvInteger(InputStream inStream) throws IOException {
1648 BufferedInputStream input = (BufferedInputStream) inStream;
1649 // Wait until input is available
1650 while(input.available() == 0);
1651 // Read integer - 4 bytes
1652 byte[] recvInt = new byte[INT_SIZE];
1653 input.read(recvInt, 0, INT_SIZE);
1654 int retVal = ByteBuffer.wrap(recvInt).getInt();
1661 * recvString() receives String in bytes
1663 public String recvString(InputStream inStream) throws IOException {
1665 BufferedInputStream input = (BufferedInputStream) inStream;
1666 int strLen = recvInteger(inStream);
1667 // Wait until input is available
1668 while(input.available() == 0);
1669 // Read String per strLen
1670 byte[] recvStr = new byte[strLen];
1671 input.read(recvStr, 0, strLen);
1672 String retVal = new String(recvStr);
1679 * sendString() sends a String in bytes
1681 public void sendString(String strSend, OutputStream outStream) throws IOException {
1683 BufferedOutputStream output = (BufferedOutputStream) outStream;
1684 // Transform String into bytes
1685 byte[] strSendBytes = strSend.getBytes();
1686 int strLen = strSend.length();
1687 // Send the string length first
1688 sendInteger(strLen, outStream);
1689 // Send the byte array
1690 output.write(strSendBytes, 0, strLen);
1696 * Convert integer to enum
1698 public IoTCommCode getCode(int intCode) throws IOException {
1700 IoTCommCode[] commCode = IoTCommCode.values();
1701 IoTCommCode retCode = commCode[intCode];
1710 public synchronized boolean recvAck(InputStream inStream) throws IOException {
1712 int intAck = recvInteger(inStream);
1713 IoTCommCode codeAck = getCode(intAck);
1714 if (codeAck == IoTCommCode.ACKNOWLEDGED)
1724 public void sendEndTransfer(OutputStream outStream) throws IOException {
1726 int endCode = IoTCommCode.END_TRANSFER.ordinal();
1727 sendInteger(endCode, outStream);
1732 * Send communication code to C++
1734 public void sendCommCode(IoTCommCode inpCommCode, OutputStream outStream, InputStream inStream) throws IOException {
1737 IoTCommCode commCode = inpCommCode;
1738 int intCode = commCode.ordinal();
1739 // TODO: delete this later
1740 System.out.println("DEBUG: Sending " + commCode + " with ordinal: " + intCode);
1741 sendInteger(intCode, outStream); recvAck(inStream);
1746 * Create a main controller object for C++
1748 public void createMainObjectCpp(String strObjControllerName, OutputStream outStream, InputStream inStream) throws IOException {
1750 sendCommCode(IoTCommCode.CREATE_MAIN_OBJECT, outStream, inStream);
1751 String strMainObjName = strObjControllerName;
1752 sendString(strMainObjName, outStream); recvAck(inStream);
1753 RuntimeOutput.print("IoTMaster: Create a main object: " + strMainObjName, BOOL_VERBOSE);
1758 * A helper function that converts Class into String
1760 * @param strDataType String MySQL data type
1763 public String getClassConverted(Class<?> cls) {
1765 if (cls == String.class) {
1767 } else if (cls == int.class) {
1776 * A helper function that converts Object into String for transfer to C++ slave
1778 * @param obj Object to be converted
1779 * @param strClassType String Java Class type
1782 public String getObjectConverted(Object obj) {
1784 if (obj instanceof String) {
1785 return (String) obj;
1786 } else if (obj instanceof Integer) {
1787 return Integer.toString((Integer) obj);
1795 * Create a driver object for C++
1797 public void createObjectCpp(String strObjName, String strObjClassName, String strObjClassInterfaceName, String strIoTSlaveObjectHostAdd,
1798 Integer iRMIRegistryPort, Integer iRMIStubPort, Object[] arrFieldValues, Class[] arrFieldClasses,
1799 OutputStream outStream, InputStream inStream) throws IOException {
1801 sendCommCode(IoTCommCode.CREATE_OBJECT, outStream, inStream);
1802 RuntimeOutput.print("IoTMaster: Send request to create a driver object... ", BOOL_VERBOSE);
1803 RuntimeOutput.print("IoTMaster: Driver object name: " + strObjName, BOOL_VERBOSE);
1804 sendString(strObjName, outStream); recvAck(inStream);
1805 RuntimeOutput.print("IoTMaster: Driver object class name: " + strObjClassName, BOOL_VERBOSE);
1806 sendString(strObjClassName, outStream); recvAck(inStream);
1807 RuntimeOutput.print("IoTMaster: Driver object interface name: " + strObjClassInterfaceName, BOOL_VERBOSE);
1808 sendString(strObjStubClsIntfaceName, outStream); recvAck(inStream);
1809 RuntimeOutput.print("IoTMaster: Driver object skeleton class name: " + strObjClassInterfaceName + STR_SKEL_CLASS_SUFFIX, BOOL_VERBOSE);
1810 sendString(strObjClassInterfaceName + STR_SKEL_CLASS_SUFFIX, outStream); recvAck(inStream);
1811 RuntimeOutput.print("IoTMaster: Driver object registry port: " + iRMIRegistryPort, BOOL_VERBOSE);
1812 sendInteger(iRMIRegistryPort, outStream); recvAck(inStream);
1813 RuntimeOutput.print("IoTMaster: Driver object stub port: " + iRMIStubPort, BOOL_VERBOSE);
1814 sendInteger(iRMIStubPort, outStream); recvAck(inStream);
1815 int numOfArgs = arrFieldValues.length;
1816 RuntimeOutput.print("IoTMaster: Send constructor arguments! Number of arguments: " + numOfArgs, BOOL_VERBOSE);
1817 sendInteger(numOfArgs, outStream); recvAck(inStream);
1818 for(Object obj : arrFieldValues) {
1819 String str = getObjectConverted(obj);
1820 sendString(str, outStream); recvAck(inStream);
1822 RuntimeOutput.print("IoTMaster: Send constructor argument classes!", BOOL_VERBOSE);
1823 for(Class cls : arrFieldClasses) {
1824 String str = getClassConverted(cls);
1825 sendString(str, outStream); recvAck(inStream);
1831 * Create new IoTSet for C++
1833 public void createNewIoTSetCpp(String strObjFieldName, OutputStream outStream, InputStream inStream) throws IOException {
1835 sendCommCode(IoTCommCode.CREATE_NEW_IOTSET, outStream, inStream);
1836 RuntimeOutput.print("IoTMaster: Creating new IoTSet...", BOOL_VERBOSE);
1837 RuntimeOutput.print("IoTMaster: Send object field name: " + strObjFieldName, BOOL_VERBOSE);
1838 sendString(strObjFieldName, outStream); recvAck(inStream);
1843 * Create new IoTRelation for C++
1845 public void createNewIoTRelationCpp(String strObjFieldName, OutputStream outStream, InputStream inStream) throws IOException {
1847 sendCommCode(IoTCommCode.CREATE_NEW_IOTRELATION, outStream, inStream);
1848 RuntimeOutput.print("IoTMaster: Creating new IoTRelation...", BOOL_VERBOSE);
1849 RuntimeOutput.print("IoTMaster: Send object field name: " + strObjFieldName, BOOL_VERBOSE);
1850 sendString(strObjFieldName, outStream); recvAck(inStream);
1855 * Get a IoTDeviceAddress object for C++
1857 public void getDeviceIoTSetObjectCpp(OutputStream outStream, InputStream inStream,
1858 String strDeviceAddress, int iSourcePort, int iDestPort, boolean bSourceWildCard, boolean bDestWildCard) throws IOException {
1860 sendCommCode(IoTCommCode.GET_DEVICE_IOTSET_OBJECT, outStream, inStream);
1861 RuntimeOutput.print("IoTMaster: Getting IoTDeviceAddress...", BOOL_VERBOSE);
1862 sendString(strDeviceAddress, outStream); recvAck(inStream);
1863 sendInteger(iSourcePort, outStream); recvAck(inStream);
1864 sendInteger(iDestPort, outStream); recvAck(inStream);
1865 int iSourceWildCard = (bSourceWildCard ? 1 : 0);
1866 sendInteger(iSourceWildCard, outStream); recvAck(inStream);
1867 int iDestWildCard = (bDestWildCard ? 1 : 0);
1868 sendInteger(iDestWildCard, outStream); recvAck(inStream);
1869 RuntimeOutput.print("IoTMaster: Send device address: " + strDeviceAddress, BOOL_VERBOSE);
1874 * Get a IoTSet content object for C++
1876 public void getIoTSetRelationObjectCpp(IoTCommCode iotCommCode, String strIoTSlaveHostAddress, String strObjectName, String strObjectClassName,
1877 String strObjectClassInterfaceName, String strObjectStubClassInterfaceName, int iRMIRegistryPort, int iRMIStubPort,
1878 OutputStream outStream, InputStream inStream) throws IOException {
1880 sendCommCode(iotCommCode, outStream, inStream);
1881 RuntimeOutput.print("IoTMaster: Getting IoTSet object content...", BOOL_VERBOSE);
1883 RuntimeOutput.print("IoTMaster: Send host address: " + strIoTSlaveHostAddress, BOOL_VERBOSE);
1884 sendString(strIoTSlaveHostAddress, outStream); recvAck(inStream);
1885 RuntimeOutput.print("IoTMaster: Driver object name: " + strObjectName, BOOL_VERBOSE);
1886 sendString(strObjectName, outStream); recvAck(inStream);
1887 RuntimeOutput.print("IoTMaster: Driver object class name: " + strObjectClassName, BOOL_VERBOSE);
1888 sendString(strObjectClassName, outStream); recvAck(inStream);
1889 RuntimeOutput.print("IoTMaster: Driver object interface name: " + strObjectClassInterfaceName, BOOL_VERBOSE);
1890 sendString(strObjectClassInterfaceName, outStream); recvAck(inStream);
1891 RuntimeOutput.print("IoTMaster: Driver object stub class name: " + strObjectStubClassInterfaceName + STR_STUB_CLASS_SUFFIX, BOOL_VERBOSE);
1892 sendString(strObjectStubClassInterfaceName + STR_STUB_CLASS_SUFFIX, outStream); recvAck(inStream);
1893 RuntimeOutput.print("IoTMaster: Driver object registry port: " + iRMIRegistryPort, BOOL_VERBOSE);
1894 sendInteger(iRMIRegistryPort, outStream); recvAck(inStream);
1895 RuntimeOutput.print("IoTMaster: Driver object stub port: " + iRMIStubPort, BOOL_VERBOSE);
1896 sendInteger(iRMIStubPort, outStream); recvAck(inStream);
1901 * Reinitialize IoTRelation field for C++
1903 private void reinitializeIoTRelationFieldCpp(OutputStream outStream, InputStream inStream) throws IOException {
1905 RuntimeOutput.print("IoTMaster: About to Reinitialize IoTRelation field!", BOOL_VERBOSE);
1906 sendCommCode(IoTCommCode.REINITIALIZE_IOTRELATION_FIELD, outStream, inStream);
1907 RuntimeOutput.print("IoTMaster: Reinitialize IoTRelation field!", BOOL_VERBOSE);
1912 * Reinitialize IoTSet field for C++
1914 private void reinitializeIoTSetFieldCpp(OutputStream outStream, InputStream inStream) throws IOException {
1916 RuntimeOutput.print("IoTMaster: About to Reinitialize IoTSet field!", BOOL_VERBOSE);
1917 sendCommCode(IoTCommCode.REINITIALIZE_IOTSET_FIELD, outStream, inStream);
1918 RuntimeOutput.print("IoTMaster: Reinitialize IoTSet field!", BOOL_VERBOSE);
1923 * Create driver object for C++
1925 private void createDriverObjectCpp(OutputStream outStream, InputStream inStream) throws IOException {
1927 sendCommCode(IoTCommCode.CREATE_DRIVER_OBJECT, outStream, inStream);
1928 RuntimeOutput.print("IoTMaster: Send command to create driver object!", BOOL_VERBOSE);
1933 * Invoke init() for C++
1935 private void invokeInitMethodCpp(OutputStream outStream, InputStream inStream) throws IOException {
1937 sendCommCode(IoTCommCode.INVOKE_INIT_METHOD, outStream, inStream);
1938 RuntimeOutput.print("IoTMaster: Invoke init method!", BOOL_VERBOSE);
1943 * End session for C++
1945 public void endSessionCpp(OutputStream outStream) throws IOException {
1947 // Send message to end session
1948 IoTCommCode endSessionCode = IoTCommCode.END_SESSION;
1949 int intCode = endSessionCode.ordinal();
1950 sendInteger(intCode, outStream);
1951 //RuntimeOutput.print("IoTMaster: Send request to create a main object: " + strObjName, BOOL_VERBOSE);
1952 RuntimeOutput.print("IoTMaster: Send request to end session!", BOOL_VERBOSE);
1957 * A method to assign objects to multiple JVMs, including
1958 * the controller/device object that uses other objects
1959 * in IoTSet and IoTRelation
1963 private void createObjects() {
1970 // Extract hostname for this IoTMaster from MySQL DB
1971 strIoTMasterHostAdd = routerConfig.getIPFromMACAddress(STR_MASTER_MAC_ADD);
1972 // Loop as we can still find controller/device classes
1973 for(int i=0; i<strObjectNames.length; i++) {
1975 start = System.currentTimeMillis();
1977 // Assign a new list of PrintWriter objects
1978 routerConfig.renewPrintWriter();
1979 // Get controller names one by one
1980 String strObjControllerName = strObjectNames[i];
1981 // Use LoadBalancer to assign a host address
1982 //strIoTSlaveControllerHostAdd = lbIoT.selectHost();
1983 strIoTSlaveControllerHostAdd = routerConfig.getIPFromMACAddress(lbIoT.selectHost());
1984 if (strIoTSlaveControllerHostAdd == null)
1985 throw new Error("IoTMaster: Could not translate MAC to IP address! Please check the router's /tmp/dhcp.leases!");
1986 // == START INITIALIZING CONTROLLER/DEVICE IOTSLAVE ==
1987 // Add port connection and get port numbers
1988 // Naming for objects ProximitySensor becomes ProximitySensor0, ProximitySensor1, etc.
1989 commHan.addPortConnection(strIoTSlaveControllerHostAdd, strObjControllerName);
1990 // ROUTING POLICY: IoTMaster and main controller object
1991 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTMasterHostAdd,
1992 strIoTSlaveControllerHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjControllerName));
1993 // ROUTING POLICY: Send the same routing policy to both the hosts
1994 routerConfig.configureHostMainPolicies(strIoTMasterHostAdd, strIoTMasterHostAdd,
1995 strIoTSlaveControllerHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjControllerName));
1996 routerConfig.configureHostMainPolicies(strIoTSlaveControllerHostAdd, strIoTMasterHostAdd,
1997 strIoTSlaveControllerHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjControllerName));
1999 String strControllerCfg = STR_CONT_PATH + strObjControllerName + "/" + strObjControllerName + STR_CFG_FILE_EXT;
2000 STR_LANGUAGE_CONTROLLER = parseConfigFile(strControllerCfg, STR_LANGUAGE);
2001 if(STR_LANGUAGE_CONTROLLER == null)
2002 throw new Error("IoTMaster: Language specification missing in config file: " + strControllerCfg);
2003 // Construct ssh command line and create a controller thread for e.g. AcmeProximity
2004 String strSSHCommand = null;
2005 if(STR_LANGUAGE_CONTROLLER.equals(STR_JAVA))
2006 strSSHCommand = getCmdJavaIoTSlave(strObjControllerName);
2007 else if(STR_LANGUAGE_CONTROLLER.equals(STR_CPP))
2008 strSSHCommand = getCmdCppIoTSlave(strObjControllerName);
2010 throw new Error("IoTMaster: Language specification not recognized: " + STR_LANGUAGE_CONTROLLER);
2011 RuntimeOutput.print(strSSHCommand, BOOL_VERBOSE);
2012 createThread(strSSHCommand);
2013 // Wait for connection
2014 // Create a new socket for communication
2015 ServerSocket serverSocket = new ServerSocket(commHan.getComPort(strObjControllerName));
2016 Socket socket = serverSocket.accept();
2017 InputStream inStream = null;
2018 OutputStream outStream = null;
2019 if(STR_LANGUAGE_CONTROLLER.equals(STR_JAVA)) {
2020 inStream = new ObjectInputStream(socket.getInputStream());
2021 outStream = new ObjectOutputStream(socket.getOutputStream());
2022 } else { // At this point the language is certainly C++, otherwise would've complained above
2023 inStream = new BufferedInputStream(socket.getInputStream());
2024 outStream = new BufferedOutputStream(socket.getOutputStream());
2027 RuntimeOutput.print("IoTMaster: Communication established!", BOOL_VERBOSE);
2030 result = System.currentTimeMillis()-start;
2031 System.out.println("\n\n ==> From start until after SSH for main controller: " + result);
2033 start = System.currentTimeMillis();
2035 // Send files for every controller class
2036 // e.g. AcmeProximity.jar and AcmeProximity.zip
2037 String strControllerClassName = strObjControllerName + STR_CLS_FILE_EXT;
2038 String strControllerClassNamePath = STR_CONT_PATH + strObjControllerName + "/" +
2039 strControllerClassName;
2041 if(STR_LANGUAGE_CONTROLLER.equals(STR_JAVA)) {
2042 sendFileToJavaSlave(strObjControllerName, serverSocket, inStream, outStream);
2043 // Create main controller/device object
2044 commMasterToSlave(new MessageCreateMainObject(IoTCommCode.CREATE_MAIN_OBJECT, strObjControllerName),
2045 "Create main object!", inStream, outStream);
2047 String strControllerZipFile = strObjControllerName + STR_ZIP_FILE_EXT;
2048 String strControllerFilePath = STR_CONT_PATH + strObjControllerName + "/";
2049 sendFileToCppSlave(strControllerFilePath, strControllerZipFile);
2050 createMainObjectCpp(strObjControllerName, outStream, inStream);
2052 // Write basic MAC policies for controller
2053 String strFileName = STR_MAC_POL_PATH + strObjControllerName + STR_MAC_POLICY_EXT;
2054 processJailConfig.configureProcessJailControllerPolicies(strObjControllerName, strFileName,
2055 strIoTMasterHostAdd, commHan.getComPort(strObjControllerName));
2057 result = System.currentTimeMillis()-start;
2058 System.out.println("\n\n ==> From IoTSlave start until main controller object is created: " + result);
2059 System.out.println(" ==> Including file transfer times!\n\n");
2061 start = System.currentTimeMillis();
2063 // == END INITIALIZING CONTROLLER/DEVICE IOTSLAVE ==
2064 // Instrumenting one file
2065 RuntimeOutput.print("IoTMaster: Opening class file: " + strControllerClassName, BOOL_VERBOSE);
2066 RuntimeOutput.print("IoTMaster: Class file path: " + strControllerClassNamePath, BOOL_VERBOSE);
2067 HashMap<String,Object> hmControllerFieldObjects = null;
2068 if(STR_LANGUAGE_CONTROLLER.equals(STR_JAVA)) {
2069 FileInputStream fis = new FileInputStream(strControllerClassNamePath);
2070 ClassReader cr = new ClassReader(fis);
2071 ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
2072 ClassRuntimeInstrumenterMaster crim = new ClassRuntimeInstrumenterMaster(cw, null, BOOL_VERBOSE);
2075 hmControllerFieldObjects = crim.getFieldObjects();
2077 String strControllerConfigFile = STR_CONT_PATH + strObjControllerName + "/" + strObjControllerName + STR_CFG_FILE_EXT;
2078 CRuntimeInstrumenterMaster crim = new CRuntimeInstrumenterMaster(strControllerConfigFile, null, BOOL_VERBOSE);
2079 hmControllerFieldObjects = crim.getFieldObjects();
2081 // Get the object and the class names
2082 // Build objects for IoTSet and IoTRelation fields in the controller/device classes
2083 //HashMap<String,Object> hmControllerFieldObjects = crim.getFieldObjects();
2084 for(Map.Entry<String,Object> map : hmControllerFieldObjects.entrySet()) {
2085 RuntimeOutput.print("IoTMaster: Object name: " + map.getValue().getClass().getName(), BOOL_VERBOSE);
2086 // Iterate over HashMap and choose between processing
2087 // SetInstrumenter vs. RelationInstrumenter
2088 String strFieldName = map.getKey();
2089 String strClassName = map.getValue().getClass().getName();
2090 if(strClassName.equals(STR_SET_INSTRUMENTER_CLS)) {
2091 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
2092 if(setInstrumenter.getObjTableName().equals(STR_IOT_DEV_ADD_CLS)) {
2093 String strErrMsg = "IoTMaster: Controller object" +
2094 " cannot have IoTSet<IoTDeviceAddress>!";
2095 throw new Error(strErrMsg);
2096 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ZB_ADD_CLS)) {
2097 String strErrMsg = "IoTMaster: Controller object" +
2098 " cannot have IoTSet<ZigbeeAddress>!";
2099 throw new Error(strErrMsg);
2100 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ADD_CLS)) {
2101 // Instrument the IoTAddress
2102 setRouterPolicyIoTSetAddress(strFieldName, map, strIoTSlaveControllerHostAdd);
2103 instrumentIoTSetAddress(strFieldName, strFieldName, inStream, outStream, STR_LANGUAGE_CONTROLLER);
2106 instrumentIoTSet(map, strFieldName, strObjControllerName, STR_LANGUAGE_CONTROLLER);
2108 } else if (strClassName.equals(STR_REL_INSTRUMENTER_CLS)) {
2109 instrumentIoTRelation(map, strFieldName, strObjControllerName, STR_LANGUAGE_CONTROLLER);
2112 // Combine controller MAC policies with the main policy file for the host
2113 String strTempFileName = "./" + strObjControllerName + STR_MAC_POLICY_EXT;
2114 processJailConfig.combineControllerMACPolicies(strIoTSlaveControllerHostAdd, strObjControllerName, strTempFileName);
2115 processJailConfig.close();
2118 result = System.currentTimeMillis()-start;
2119 System.out.println("\n\n ==> Time needed to instrument device driver objects: " + result + "\n\n");
2120 System.out.println(" ==> #Objects: " + commHan.getActiveControllerObjectList().size() + "\n\n");
2123 start = System.currentTimeMillis();
2125 // ROUTING POLICY: Deploy basic policies if this is the last controller
2126 if (i == strObjectNames.length-1) {
2127 // ROUTING POLICY: implement basic policies to reject all other irrelevant traffics
2128 for(String s: commHan.getHosts()) {
2129 setHostBasicPolicies(s);
2131 // We retain all the basic policies for router,
2132 // but we delete the initial allowance policies for internal all TCP and UDP communications
2133 setRouterBasicPolicies(STR_ROUTER_ADD);
2135 // Close access to policy files and deploy policies
2136 routerConfig.close();
2137 // Deploy the policy
2138 HashSet<String> setAddresses = new HashSet<String>(commHan.getHosts());
2139 setAddresses.add(strIoTMasterHostAdd);
2140 createPolicyThreads(STR_ROUTER_ADD, setAddresses);
2143 result = System.currentTimeMillis()-start;
2144 System.out.println("\n\n ==> Time needed to send policy files and deploy them : " + result + "\n\n");
2147 start = System.currentTimeMillis();
2149 // Separating object creations and Set/Relation initializations
2150 createDriverObjects();
2153 result = System.currentTimeMillis()-start;
2154 System.out.println("\n\n ==> Time needed to instantiate objects: " + result + "\n\n");
2156 start = System.currentTimeMillis();
2158 // Sets and relations initializations
2159 if(STR_LANGUAGE_CONTROLLER.equals(STR_JAVA))
2160 initializeSetsAndRelationsJava(inStream, outStream);
2162 initializeSetsAndRelationsCpp(inStream, outStream);;
2165 result = System.currentTimeMillis()-start;
2166 System.out.println("\n\n ==> Time needed to initialize sets and relations: " + result + "\n\n");
2168 if(STR_LANGUAGE_CONTROLLER.equals(STR_JAVA))
2169 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO EXECUTE INIT METHOD
2170 commMasterToSlave(new MessageSimple(IoTCommCode.INVOKE_INIT_METHOD), "Invoke init() method!", inStream, outStream);
2172 invokeInitMethodCpp(outStream, inStream);
2173 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO END PROCESS
2174 if(STR_LANGUAGE_CONTROLLER.equals(STR_JAVA)) {
2175 ObjectOutputStream oStream = (ObjectOutputStream) outStream;
2176 oStream.writeObject(new MessageSimple(IoTCommCode.END_SESSION));
2177 } else // C++ side will wait until the program finishes, it's not generating a separate thread for now
2178 //endSessionCpp(outStream);
2182 serverSocket.close();
2183 commHan.printLists();
2184 lbIoT.printHostInfo();
2185 createMACPolicyThreads(setAddresses);
2188 } catch (IOException |
2189 InterruptedException |
2190 ClassNotFoundException ex) {
2191 System.out.println("IoTMaster: Exception: "
2193 ex.printStackTrace();
2197 public static void main(String args[]) {
2199 // Detect the available controller/device classes
2200 // Input args[] should be used to list the controllers/devices
2201 // e.g. java IoTMaster AcmeProximity AcmeThermostat AcmeVentController
2202 IoTMaster iotMaster = new IoTMaster(args);
2204 iotMaster.parseIoTMasterConfigFile();
2205 // Initialize CommunicationHandler, LoadBalancer, and RouterConfig
2206 iotMaster.initLiveDataStructure();
2208 iotMaster.createObjects();