1 package iotruntime.master;
4 import iotruntime.slave.IoTAddress;
5 import iotruntime.slave.IoTDeviceAddress;
6 import iotruntime.messages.*;
9 import org.objectweb.asm.ClassReader;
10 import org.objectweb.asm.ClassWriter;
11 import org.objectweb.asm.ClassVisitor;
16 import java.io.BufferedReader;
17 import java.io.InputStream;
18 import java.io.InputStreamReader;
20 import java.io.FileInputStream;
21 import java.io.FileOutputStream;
22 import java.io.OutputStream;
23 import java.io.ObjectInputStream;
24 import java.io.ObjectOutputStream;
25 import java.io.IOException;
26 import java.lang.ClassNotFoundException;
27 import java.lang.Class;
28 import java.lang.reflect.*;
29 import java.net.Socket;
30 import java.net.ServerSocket;
31 import java.nio.ByteBuffer;
33 import static java.lang.Math.toIntExact;
35 /** Class IoTMaster is responsible to use ClassRuntimeInstrumenterMaster
36 * to instrument the controller/device bytecode and starts multiple
37 * IoTSlave running on different JVM's in a distributed fashion.
39 * @author Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>
43 public final class IoTMaster {
46 * IoTMaster class properties
48 * CommunicationHandler maintains the data structure for hostnames and ports
49 * LoadBalancer assigns a job onto a host based on certain metrics
51 private CommunicationHandler commHan;
52 private LoadBalancer lbIoT;
53 private RouterConfig routerConfig;
54 private ProcessJailConfig processJailConfig;
55 private ObjectInitHandler objInitHand;
56 private ObjectAddressInitHandler objAddInitHand;
57 private String[] strObjectNames;
58 // Now this can be either ClassRuntimeInstrumenterMaster or CRuntimeInstrumenterMaster
59 private Map<String,Object> mapClassNameToCrim;
62 * These properties hold information of a certain object
65 private String strObjName;
66 private String strObjClassName;
67 private String strObjClassInterfaceName;
68 private String strObjStubClsIntfaceName;
69 private String strIoTMasterHostAdd;
70 private String strIoTSlaveControllerHostAdd;
71 private String strIoTSlaveObjectHostAdd;
72 private Class[] arrFieldClasses;
73 private Object[] arrFieldValues;
74 private Socket filesocket;
77 * For connection with C++ IoTSlave
79 private ServerSocket serverSocketCpp;
80 private Socket socketCpp;
81 private BufferedInputStream inputCpp;
82 private BufferedOutputStream outputCpp;
84 // Constants that are to be extracted from config file
85 private static String STR_MASTER_MAC_ADD;
86 private static String STR_IOT_CODE_PATH;
87 private static String STR_CONT_PATH;
88 private static String STR_RUNTIME_DIR;
89 private static String STR_SLAVE_DIR;
90 private static String STR_CLS_PATH;
91 private static String STR_RMI_PATH;
92 private static String STR_RMI_HOSTNAME;
93 private static String STR_LOG_FILE_PATH;
94 private static String STR_USERNAME;
95 private static String STR_ROUTER_ADD;
96 private static String STR_MONITORING_HOST;
97 private static String STR_ZB_GATEWAY_ADDRESS;
98 private static String STR_ZB_GATEWAY_PORT;
99 private static String STR_ZB_IOTMASTER_PORT;
100 private static String STR_JVM_INIT_HEAP_SIZE;
101 private static String STR_JVM_MAX_HEAP_SIZE;
102 private static String STR_LANGUAGE_CONTROLLER;
103 private static String STR_SKEL_CLASS_SUFFIX;
104 private static String STR_STUB_CLASS_SUFFIX;
105 private static 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)
141 private static final int INT_DNS_PORT = 53;
144 * Runtime class name constants - not to be configured by users
146 private static final String STR_REL_INSTRUMENTER_CLS = "iotruntime.master.RelationInstrumenter";
147 private static final String STR_SET_INSTRUMENTER_CLS = "iotruntime.master.SetInstrumenter";
148 private static final String STR_IOT_SLAVE_CLS = "iotruntime.slave.IoTSlave";
149 private static final String STR_IOT_DEV_ADD_CLS = "IoTDeviceAddress";
150 private static final String STR_IOT_ZB_ADD_CLS = "IoTZigbeeAddress";
151 private static final String STR_IOT_ADD_CLS = "IoTAddress";
157 public IoTMaster(String[] argObjNms) {
162 processJailConfig = null;
164 objAddInitHand = null;
165 strObjectNames = argObjNms;
167 strObjClassName = null;
168 strObjClassInterfaceName = null;
169 strObjStubClsIntfaceName = null;
170 strIoTMasterHostAdd = null;
171 strIoTSlaveControllerHostAdd = null;
172 strIoTSlaveObjectHostAdd = null;
173 arrFieldClasses = null;
174 arrFieldValues = null;
176 mapClassNameToCrim = null;
177 // Connection with C++ IoTSlave
178 serverSocketCpp = null;
183 STR_MASTER_MAC_ADD = null;
184 STR_IOT_CODE_PATH = null;
185 STR_CONT_PATH = null;
186 STR_RUNTIME_DIR = null;
187 STR_SLAVE_DIR = null;
190 STR_RMI_HOSTNAME = null;
191 STR_LOG_FILE_PATH = null;
193 STR_ROUTER_ADD = null;
194 STR_MONITORING_HOST = null;
195 STR_ZB_GATEWAY_ADDRESS = null;
196 STR_ZB_GATEWAY_PORT = null;
197 STR_ZB_IOTMASTER_PORT = null;
198 STR_JVM_INIT_HEAP_SIZE = null;
199 STR_JVM_MAX_HEAP_SIZE = null;
200 STR_LANGUAGE_CONTROLLER = null;
201 BOOL_VERBOSE = false;
205 * A method to initialize CommunicationHandler, LoadBalancer, RouterConfig and ObjectInitHandler
209 private void initLiveDataStructure() {
211 commHan = new CommunicationHandler(BOOL_VERBOSE);
212 lbIoT = new LoadBalancer(BOOL_VERBOSE);
213 lbIoT.setupLoadBalancer();
214 routerConfig = new RouterConfig();
215 routerConfig.getAddressList(STR_ROUTER_ADD);
216 processJailConfig = new ProcessJailConfig();
217 //processJailConfig.setAddressListObject(routerConfig.getAddressListObject());
218 objInitHand = new ObjectInitHandler(BOOL_VERBOSE);
219 objAddInitHand = new ObjectAddressInitHandler(BOOL_VERBOSE);
220 mapClassNameToCrim = new HashMap<String,Object>();
224 * getPrintWriter() gets a new PrintWriter for a new object
226 * @param strObjectName String object name
227 * @return PrintWriter
229 private PrintWriter getPrintWriter(String strObjectName) {
231 FileWriter fw = null;
233 fw = new FileWriter(strObjectName);
234 } catch (IOException ex) {
235 ex.printStackTrace();
237 PrintWriter printWriter = new PrintWriter(new BufferedWriter(fw));
242 * A method to initialize constants from config file
246 private void parseIoTMasterConfigFile() {
247 // Parse configuration file
248 Properties prop = new Properties();
249 String strCfgFileName = STR_IOT_MASTER_NAME + STR_CFG_FILE_EXT;
250 File file = new File(strCfgFileName);
251 FileInputStream fis = null;
253 fis = new FileInputStream(file);
256 } catch (IOException ex) {
257 System.out.println("IoTMaster: Error reading config file: " + strCfgFileName);
258 ex.printStackTrace();
260 // Initialize constants from config file
261 STR_MASTER_MAC_ADD = prop.getProperty("MAC_ADDRESS");
262 STR_IOT_CODE_PATH = prop.getProperty("IOT_CODE_PATH");
263 STR_CONT_PATH = prop.getProperty("CONTROLLERS_CODE_PATH");
264 STR_RUNTIME_DIR = prop.getProperty("RUNTIME_DIR");
265 STR_SLAVE_DIR = prop.getProperty("SLAVE_DIR");
266 STR_CLS_PATH = prop.getProperty("CLASS_PATH");
267 STR_RMI_PATH = prop.getProperty("RMI_PATH");
268 STR_RMI_HOSTNAME = prop.getProperty("RMI_HOSTNAME");
269 STR_LOG_FILE_PATH = prop.getProperty("LOG_FILE_PATH");
270 STR_USERNAME = prop.getProperty("USERNAME");
271 STR_ROUTER_ADD = prop.getProperty("ROUTER_ADD");
272 STR_MONITORING_HOST = prop.getProperty("MONITORING_HOST");
273 STR_ZB_GATEWAY_ADDRESS = prop.getProperty("ZIGBEE_GATEWAY_ADDRESS");
274 STR_ZB_GATEWAY_PORT = prop.getProperty("ZIGBEE_GATEWAY_PORT");
275 STR_ZB_IOTMASTER_PORT = prop.getProperty("ZIGBEE_IOTMASTER_PORT");
276 STR_JVM_INIT_HEAP_SIZE = prop.getProperty("JVM_INIT_HEAP_SIZE");
277 STR_JVM_MAX_HEAP_SIZE = prop.getProperty("JVM_MAX_HEAP_SIZE");
278 STR_SKEL_CLASS_SUFFIX = prop.getProperty("SKEL_CLASS_SUFFIX");
279 STR_STUB_CLASS_SUFFIX = prop.getProperty("STUB_CLASS_SUFFIX");
280 if(prop.getProperty("VERBOSE").equals(STR_YES)) {
284 RuntimeOutput.print("IoTMaster: Extracting information from config file: " + strCfgFileName, BOOL_VERBOSE);
285 RuntimeOutput.print("STR_MASTER_MAC_ADD=" + STR_MASTER_MAC_ADD, BOOL_VERBOSE);
286 RuntimeOutput.print("STR_IOT_CODE_PATH=" + STR_IOT_CODE_PATH, BOOL_VERBOSE);
287 RuntimeOutput.print("STR_CONT_PATH=" + STR_CONT_PATH, BOOL_VERBOSE);
288 RuntimeOutput.print("STR_RUNTIME_DIR=" + STR_RUNTIME_DIR, BOOL_VERBOSE);
289 RuntimeOutput.print("STR_SLAVE_DIR=" + STR_SLAVE_DIR, BOOL_VERBOSE);
290 RuntimeOutput.print("STR_CLS_PATH=" + STR_CLS_PATH, BOOL_VERBOSE);
291 RuntimeOutput.print("STR_RMI_PATH=" + STR_RMI_PATH, BOOL_VERBOSE);
292 RuntimeOutput.print("STR_RMI_HOSTNAME=" + STR_RMI_HOSTNAME, BOOL_VERBOSE);
293 RuntimeOutput.print("STR_LOG_FILE_PATH=" + STR_LOG_FILE_PATH, BOOL_VERBOSE);
294 RuntimeOutput.print("STR_USERNAME=" + STR_USERNAME, BOOL_VERBOSE);
295 RuntimeOutput.print("STR_ROUTER_ADD=" + STR_ROUTER_ADD, BOOL_VERBOSE);
296 RuntimeOutput.print("STR_MONITORING_HOST=" + STR_MONITORING_HOST, BOOL_VERBOSE);
297 RuntimeOutput.print("STR_ZB_GATEWAY_ADDRESS=" + STR_ZB_GATEWAY_ADDRESS, BOOL_VERBOSE);
298 RuntimeOutput.print("STR_ZB_GATEWAY_PORT=" + STR_ZB_GATEWAY_PORT, BOOL_VERBOSE);
299 RuntimeOutput.print("STR_ZB_IOTMASTER_PORT=" + STR_ZB_IOTMASTER_PORT, BOOL_VERBOSE);
300 RuntimeOutput.print("STR_JVM_INIT_HEAP_SIZE=" + STR_JVM_INIT_HEAP_SIZE, BOOL_VERBOSE);
301 RuntimeOutput.print("STR_JVM_MAX_HEAP_SIZE=" + STR_JVM_MAX_HEAP_SIZE, BOOL_VERBOSE);
302 RuntimeOutput.print("STR_SKEL_CLASS_SUFFIX=" + STR_SKEL_CLASS_SUFFIX, BOOL_VERBOSE);
303 RuntimeOutput.print("STR_STUB_CLASS_SUFFIX=" + STR_STUB_CLASS_SUFFIX, BOOL_VERBOSE);
304 RuntimeOutput.print("BOOL_VERBOSE=" + BOOL_VERBOSE, BOOL_VERBOSE);
305 RuntimeOutput.print("IoTMaster: Information extracted successfully!", BOOL_VERBOSE);
309 * A method to parse information from a config file
311 * @param strCfgFileName Config file name
312 * @param strCfgField Config file field name
315 private String parseConfigFile(String strCfgFileName, String strCfgField) {
316 // Parse configuration file
317 Properties prop = new Properties();
318 File file = new File(strCfgFileName);
319 FileInputStream fis = null;
321 fis = new FileInputStream(file);
324 } catch (IOException ex) {
325 System.out.println("IoTMaster: Error reading config file: " + strCfgFileName);
326 ex.printStackTrace();
328 System.out.println("IoTMaster: Reading " + strCfgField +
329 " from config file: " + strCfgFileName + " with value: " +
330 prop.getProperty(strCfgField, null));
331 // NULL is returned if the property isn't found
332 return prop.getProperty(strCfgField, null);
336 * A method to send files from IoTMaster
338 * @param filesocket File socket object
339 * @param sFileName File name
340 * @param lFLength File length
343 private void sendFile(Socket filesocket, String sFileName, long lFLength) throws IOException {
345 File file = new File(sFileName);
346 byte[] bytFile = new byte[toIntExact(lFLength)];
347 InputStream inFileStream = new FileInputStream(file);
349 OutputStream outFileStream = filesocket.getOutputStream();
351 while ((iCount = inFileStream.read(bytFile)) > 0) {
352 outFileStream.write(bytFile, 0, iCount);
355 RuntimeOutput.print("IoTMaster: File sent!", BOOL_VERBOSE);
359 * A method to create a thread
361 * @param sSSHCmd SSH command
364 private void createThread(String sSSHCmd) throws IOException {
366 // Start a new thread to start a new JVM
368 Runtime runtime = Runtime.getRuntime();
369 Process process = runtime.exec(sSSHCmd);
371 RuntimeOutput.print("Executing: " + sSSHCmd, BOOL_VERBOSE);
375 * A method to send command from master and receive reply from slave
377 * @params msgSend Message object
378 * @params strPurpose String that prints purpose message
379 * @params inStream Input stream
380 * @params outStream Output stream
383 private void commMasterToSlave(Message msgSend, String strPurpose,
384 InputStream _inStream, OutputStream _outStream)
385 throws IOException, ClassNotFoundException {
387 // Send message/command from master
388 ObjectOutputStream outStream = (ObjectOutputStream) _outStream;
389 outStream.writeObject(msgSend);
390 RuntimeOutput.print("IoTMaster: Send message: " + strPurpose, BOOL_VERBOSE);
392 // Get reply from slave as acknowledgment
393 ObjectInputStream inStream = (ObjectInputStream) _inStream;
394 Message msgReply = (Message) inStream.readObject();
395 RuntimeOutput.print("IoTMaster: Reply message: " + msgReply.getMessage(), BOOL_VERBOSE);
399 * A private method to instrument IoTSet device
401 * @params strFieldIdentifier String field name + object ID
402 * @params strFieldName String field name
403 * @params strIoTSlaveObjectHostAdd String slave host address
404 * @params inStream ObjectInputStream communication
405 * @params inStream ObjectOutputStream communication
406 * @params strLanguage String language
409 private void instrumentIoTSetDevice(String strFieldIdentifier, String strObjName, String strFieldName, String strIoTSlaveObjectHostAdd,
410 InputStream inStream, OutputStream outStream, String strLanguage)
411 throws IOException, ClassNotFoundException, InterruptedException {
413 // Get information from the set
414 List<Object[]> listObject = objAddInitHand.getFields(strFieldIdentifier);
415 // Create a new IoTSet
416 if(strLanguage.equals(STR_JAVA)) {
417 Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, strFieldName);
418 commMasterToSlave(msgCrtIoTSet, "Create new IoTSet for IoTDeviceAddress!", inStream, outStream);
420 createNewIoTSetCpp(strFieldName, outStream, inStream);
421 int iRows = listObject.size();
422 RuntimeOutput.print("IoTMaster: Number of rows for IoTDeviceAddress: " + iRows, BOOL_VERBOSE);
423 // Transfer the address
424 for(int iRow=0; iRow<iRows; iRow++) {
425 arrFieldValues = listObject.get(iRow);
426 // Get device address - if 00:00:00:00:00:00 that means it needs the driver object address (self)
427 String strDeviceAddress = null;
428 String strDeviceAddressKey = null;
429 if (arrFieldValues[0].equals(STR_SELF_MAC_ADD)) {
430 strDeviceAddress = strIoTSlaveObjectHostAdd;
431 strDeviceAddressKey = strObjName + "-" + strIoTSlaveObjectHostAdd;
433 strDeviceAddress = routerConfig.getIPFromMACAddress((String) arrFieldValues[0]);
434 strDeviceAddressKey = strObjName + "-" + strDeviceAddress;
436 int iDestDeviceDriverPort = (int) arrFieldValues[1];
437 String strProtocol = (String) arrFieldValues[2];
438 // Check for wildcard feature
439 boolean bSrcPortWildCard = false;
440 boolean bDstPortWildCard = false;
441 if (arrFieldValues.length > 3) {
442 bSrcPortWildCard = (boolean) arrFieldValues[3];
443 bDstPortWildCard = (boolean) arrFieldValues[4];
445 // Add the port connection into communication handler - if it's not assigned yet
446 if (commHan.getComPort(strDeviceAddressKey) == null) {
447 commHan.addPortConnection(strIoTSlaveObjectHostAdd, strDeviceAddressKey);
451 System.out.println("\n\n DEBUG: InstrumentSetDevice: Object Name: " + strObjName);
452 System.out.println("DEBUG: InstrumentSetDevice: Port number: " + commHan.getComPort(strDeviceAddressKey));
453 System.out.println("DEBUG: InstrumentSetDevice: Device address: " + strDeviceAddressKey + "\n\n");
455 // Send address one by one
456 if(strLanguage.equals(STR_JAVA)) {
457 Message msgGetIoTSetObj = null;
458 if (bDstPortWildCard) {
459 String strUniqueDev = strDeviceAddressKey + ":" + iRow;
460 msgGetIoTSetObj = new MessageGetDeviceObject(IoTCommCode.GET_DEVICE_IOTSET_OBJECT,
461 strDeviceAddress, commHan.getAdditionalPort(strUniqueDev), iDestDeviceDriverPort, bSrcPortWildCard, bDstPortWildCard);
463 msgGetIoTSetObj = new MessageGetDeviceObject(IoTCommCode.GET_DEVICE_IOTSET_OBJECT,
464 strDeviceAddress, commHan.getComPort(strDeviceAddressKey), iDestDeviceDriverPort, bSrcPortWildCard, bDstPortWildCard);
465 commMasterToSlave(msgGetIoTSetObj, "Get IoTSet objects!", inStream, outStream);
467 getDeviceIoTSetObjectCpp(outStream, inStream, strDeviceAddress, commHan.getComPort(strDeviceAddressKey), iDestDeviceDriverPort,
468 bSrcPortWildCard, bDstPortWildCard);
470 // Reinitialize IoTSet on device object
471 if(strLanguage.equals(STR_JAVA))
472 commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTSET_FIELD), "Reinitialize IoTSet fields!", inStream, outStream);
474 reinitializeIoTSetFieldCpp(outStream, inStream);
479 * A private method to instrument IoTSet Zigbee device
481 * @params Map.Entry<String,Object> Entry of map IoTSet instrumentation
482 * @params strFieldName String field name
483 * @params strIoTSlaveObjectHostAdd String slave host address
484 * @params inStream ObjectInputStream communication
485 * @params inStream ObjectOutputStream communication
486 * @params strLanguage String language
489 private void instrumentIoTSetZBDevice(Map.Entry<String,Object> map, String strObjName, String strFieldName, String strIoTSlaveObjectHostAdd,
490 InputStream inStream, OutputStream outStream, String strLanguage)
491 throws IOException, ClassNotFoundException, InterruptedException {
493 // Get information from the set
494 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
495 // Create a new IoTSet
496 if(strLanguage.equals(STR_JAVA)) {
497 Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, strFieldName);
498 commMasterToSlave(msgCrtIoTSet, "Create new IoTSet for IoTZigbeeAddress!", inStream, outStream);
499 } else // TODO: will need to implement IoTSet Zigbee for C++ later
501 // Prepare ZigbeeConfig
502 String strZigbeeGWAddress = routerConfig.getIPFromMACAddress(STR_ZB_GATEWAY_ADDRESS);
503 String strZigbeeGWAddressKey = strObjName + "-" + strZigbeeGWAddress;
504 int iZigbeeGWPort = Integer.parseInt(STR_ZB_GATEWAY_PORT);
505 int iZigbeeIoTMasterPort = Integer.parseInt(STR_ZB_IOTMASTER_PORT);
506 commHan.addDevicePort(iZigbeeIoTMasterPort);
507 ZigbeeConfig zbConfig = new ZigbeeConfig(strZigbeeGWAddress, iZigbeeGWPort, iZigbeeIoTMasterPort,
509 // Add the port connection into communication handler - if it's not assigned yet
510 if (commHan.getComPort(strZigbeeGWAddressKey) == null) {
511 commHan.addPortConnection(strIoTSlaveObjectHostAdd, strZigbeeGWAddressKey);
513 int iRows = setInstrumenter.numberOfRows();
514 RuntimeOutput.print("IoTMaster: Number of rows for IoTZigbeeAddress: " + iRows, BOOL_VERBOSE);
517 System.out.println("\n\nDEBUG: InstrumentZigbeeDevice: Object Name: " + strObjName);
518 System.out.println("DEBUG: InstrumentZigbeeDevice: Port number: " + commHan.getComPort(strZigbeeGWAddressKey));
519 System.out.println("DEBUG: InstrumentZigbeeDevice: Device address: " + strZigbeeGWAddress + "\n\n");
521 // Transfer the address
522 for(int iRow=0; iRow<iRows; iRow++) {
523 arrFieldValues = setInstrumenter.fieldValues(iRow);
524 // Get device address
525 String strZBDevAddress = (String) arrFieldValues[0];
526 // Send policy to Zigbee gateway - TODO: Need to clear policy first?
527 zbConfig.setPolicy(strIoTSlaveObjectHostAdd, commHan.getComPort(strZigbeeGWAddressKey), strZBDevAddress);
528 // Send address one by one
529 if(strLanguage.equals(STR_JAVA)) {
530 Message msgGetIoTSetZBObj = new MessageGetSimpleDeviceObject(IoTCommCode.GET_ZB_DEV_IOTSET_OBJECT, strZBDevAddress);
531 commMasterToSlave(msgGetIoTSetZBObj, "Get IoTSet objects!", inStream, outStream);
532 } else // TODO: Implement IoTSet Zigbee for C++
535 zbConfig.closeConnection();
536 // Reinitialize IoTSet on device object
537 commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTSET_FIELD), "Reinitialize IoTSet fields!", inStream, outStream);
542 * A private method to instrument IoTSet of addresses
544 * @params strFieldIdentifier String field name + object ID
545 * @params strFieldName String field name
546 * @params inStream ObjectInputStream communication
547 * @params inStream ObjectOutputStream communication
548 * @params strLanguage String language
551 private void instrumentIoTSetAddress(String strFieldIdentifier, String strFieldName,
552 InputStream inStream, OutputStream outStream, String strLanguage)
553 throws IOException, ClassNotFoundException, InterruptedException {
555 // Get information from the set
556 List<Object[]> listObject = objAddInitHand.getFields(strFieldIdentifier);
557 // Create a new IoTSet
558 if(strLanguage.equals(STR_JAVA)) {
559 Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, strFieldName);
560 commMasterToSlave(msgCrtIoTSet, "Create new IoTSet for IoTAddress!", inStream, outStream);
563 int iRows = listObject.size();
564 RuntimeOutput.print("IoTMaster: Number of rows for IoTAddress: " + iRows, BOOL_VERBOSE);
565 // Transfer the address
566 for(int iRow=0; iRow<iRows; iRow++) {
567 arrFieldValues = listObject.get(iRow);
568 // Get device address
569 String strAddress = (String) arrFieldValues[0];
570 // Send address one by one
571 if(strLanguage.equals(STR_JAVA)) {
572 Message msgGetIoTSetAddObj = new MessageGetSimpleDeviceObject(IoTCommCode.GET_ADD_IOTSET_OBJECT, strAddress);
573 commMasterToSlave(msgGetIoTSetAddObj, "Get IoTSet objects!", inStream, outStream);
574 } else // TODO: Implement IoTSet Address for C++
577 // Reinitialize IoTSet on device object
578 commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTSET_FIELD),
579 "Reinitialize IoTSet fields!", inStream, outStream);
584 * A private method to instrument an object on a specific machine and setting up policies
586 * @params strFieldObjectID String field object ID
587 * @params strObjControllerName String object controller name
588 * @params strLanguage String language
591 private void instrumentObject(String strFieldObjectID, String strObjControllerName, String strLanguage) throws IOException {
593 // Extract the interface name for RMI
594 // e.g. ProximitySensorInterface, TempSensorInterface, etc.
596 String strObjCfgFile = STR_IOT_CODE_PATH + strObjClassName + "/" + strObjClassName + STR_CFG_FILE_EXT;
597 strObjClassInterfaceName = parseConfigFile(strObjCfgFile, STR_INTERFACE_CLS_CFG);
598 strObjStubClsIntfaceName = parseConfigFile(strObjCfgFile, STR_INT_STUB_CLS_CFG);
599 // Create an object name, e.g. ProximitySensorImplPS1
600 strObjName = strObjClassName + strFieldObjectID;
601 // Check first if host exists
602 if(commHan.objectExists(strObjName)) {
603 // If this object exists already ...
604 // Re-read IoTSlave object hostname for further reference
605 strIoTSlaveObjectHostAdd = commHan.getHostAddress(strObjName);
606 RuntimeOutput.print("IoTMaster: Object with name: " + strObjName + " has existed!", BOOL_VERBOSE);
608 // If this is a new object ... then create one
609 // Get host address for IoTSlave from LoadBalancer
610 //strIoTSlaveObjectHostAdd = lbIoT.selectHost();
611 strIoTSlaveObjectHostAdd = routerConfig.getIPFromMACAddress(lbIoT.selectHost());
612 if (strIoTSlaveControllerHostAdd == null)
613 throw new Error("IoTMaster: Could not translate MAC to IP address! Please check the router's /tmp/dhcp.leases!");
614 RuntimeOutput.print("IoTMaster: Object name: " + strObjName, BOOL_VERBOSE);
615 // Add port connection and get port numbers
616 // Naming for objects ProximitySensor becomes ProximitySensor0, ProximitySensor1, etc.
617 commHan.addPortConnection(strIoTSlaveObjectHostAdd, strObjName);
618 commHan.addActiveControllerObject(strFieldObjectID, strObjName, strObjClassName, strObjClassInterfaceName,
619 strObjStubClsIntfaceName, strIoTSlaveObjectHostAdd, arrFieldValues, arrFieldClasses);
620 // ROUTING POLICY: IoTMaster and device/controller object
621 // Master-slave communication
622 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTMasterHostAdd,
623 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjName));
624 // ROUTING POLICY: Send the same routing policy to both the hosts
625 routerConfig.configureHostMainPolicies(strIoTMasterHostAdd, strIoTMasterHostAdd,
626 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjName));
627 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTMasterHostAdd,
628 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjName));
629 // Need to accommodate callback functions here - open ports for TCP
630 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveControllerHostAdd,
631 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
632 routerConfig.configureHostMainPolicies(strIoTSlaveControllerHostAdd, strIoTSlaveControllerHostAdd,
633 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
634 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveControllerHostAdd,
635 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
636 // Configure MAC policies for objects
637 //String strFileName = STR_MAC_POL_PATH + strObjClassName + STR_MAC_POLICY_EXT;
638 String strFileName = STR_MAC_POL_PATH + STR_JAVA + STR_MAC_POLICY_EXT;
639 processJailConfig.configureProcessJailDeviceDriverPolicies(strIoTSlaveObjectHostAdd, strObjName, strObjClassName,
640 strFileName, strIoTMasterHostAdd, commHan.getComPort(strObjName), commHan.getRMIRegPort(strObjName),
641 commHan.getRMIStubPort(strObjName));
642 processJailConfig.configureProcessJailContRMIPolicies(strObjControllerName, strIoTSlaveObjectHostAdd,
643 commHan.getRMIRegPort(strObjName), commHan.getRMIStubPort(strObjName));
644 // Instrument the IoTSet declarations inside the class file
645 instrumentObjectIoTSet(strFieldObjectID, strLanguage);
647 // Send routing policy to router for controller object
648 // ROUTING POLICY: RMI communication - RMI registry and stub ports
649 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
650 STR_TCP_PROTOCOL, commHan.getRMIRegPort(strObjName));
651 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
652 STR_TCP_PROTOCOL, commHan.getRMIStubPort(strObjName));
653 // Send the same set of routing policies to compute nodes
654 routerConfig.configureHostMainPolicies(strIoTSlaveControllerHostAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
655 STR_TCP_PROTOCOL, commHan.getRMIRegPort(strObjName));
656 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
657 STR_TCP_PROTOCOL, commHan.getRMIRegPort(strObjName));
658 routerConfig.configureHostMainPolicies(strIoTSlaveControllerHostAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
659 STR_TCP_PROTOCOL, commHan.getRMIStubPort(strObjName));
660 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
661 STR_TCP_PROTOCOL, commHan.getRMIStubPort(strObjName));
666 * A private method to set router policies for IoTDeviceAddress objects
668 * @params strFieldIdentifier String field name + object ID
669 * @params Map.Entry<String,Object> Entry of map IoTSet instrumentation
670 * @params strIoTSlaveObjectHostAdd String slave host address
673 private void setRouterPolicyIoTSetDevice(String strFieldIdentifier, Map.Entry<String,Object> map,
674 String strIoTSlaveObjectHostAdd) {
676 // Get information from the set
677 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
678 int iRows = setInstrumenter.numberOfRows();
679 RuntimeOutput.print("IoTMaster: Number of rows for IoTDeviceAddress: " + iRows, BOOL_VERBOSE);
680 // Transfer the address
681 for(int iRow=0; iRow<iRows; iRow++) {
682 arrFieldValues = setInstrumenter.fieldValues(iRow);
683 objAddInitHand.addField(strFieldIdentifier, arrFieldValues); // Save this for object instantiation
684 // Get device address - if 00:00:00:00:00:00 that means it needs the driver object address (self)
685 String strDeviceAddress = null;
686 String strDeviceAddressKey = null;
687 if (arrFieldValues[0].equals(STR_SELF_MAC_ADD)) {
688 strDeviceAddress = strIoTSlaveObjectHostAdd;
689 strDeviceAddressKey = strObjName + "-" + strIoTSlaveObjectHostAdd;
690 } else { // Concatenate object name and IP address to give unique key - for a case where there is one device for multiple drivers
691 strDeviceAddress = routerConfig.getIPFromMACAddress((String) arrFieldValues[0]);
692 strDeviceAddressKey = strObjName + "-" + strDeviceAddress;
694 int iDestDeviceDriverPort = (int) arrFieldValues[1];
695 String strProtocol = (String) arrFieldValues[2];
696 // Add the port connection into communication handler - if it's not assigned yet
697 if (commHan.getComPort(strDeviceAddressKey) == null)
698 commHan.addPortConnection(strIoTSlaveObjectHostAdd, strDeviceAddressKey);
699 boolean bDstPortWildCard = false;
700 // Recognize this and allocate different ports for it
701 if (arrFieldValues.length > 3) {
702 bDstPortWildCard = (boolean) arrFieldValues[4];
703 if (bDstPortWildCard) { // This needs a unique source port
704 String strUniqueDev = strDeviceAddressKey + ":" + iRow;
705 commHan.addAdditionalPort(strUniqueDev);
710 System.out.println("\n\n DEBUG: InstrumentPolicySetDevice: Object Name: " + strObjName);
711 System.out.println("DEBUG: InstrumentPolicySetDevice: Port number: " + commHan.getComPort(strDeviceAddressKey));
712 System.out.println("DEBUG: InstrumentPolicySetDevice: Device address: " + strDeviceAddressKey + "\n\n");
714 // Send routing policy to router for device drivers and devices
715 // ROUTING POLICY: RMI communication - RMI registry and stub ports
716 if((iDestDeviceDriverPort == -1) && (!strProtocol.equals(STR_NO_PROTOCOL))) {
717 // Port number -1 means that we don't set the policy strictly to port number level
718 // "nopro" = no protocol specified for just TCP or just UDP (can be both used as well)
719 // ROUTING POLICY: Device driver and device
720 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveObjectHostAdd, strDeviceAddress, strProtocol);
721 // ROUTING POLICY: Send to the compute node where the device driver is
722 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress, strProtocol);
723 } else if((iDestDeviceDriverPort == -1) && (strProtocol.equals(STR_NO_PROTOCOL))) {
724 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveObjectHostAdd, strDeviceAddress);
725 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress);
726 } else if(strProtocol.equals(STR_TCPGW_PROTOCOL)) {
727 // This is a TCP protocol that connects, e.g. a phone to our runtime system
728 // that provides a gateway access (accessed through destination port number)
729 commHan.addDevicePort(iDestDeviceDriverPort);
730 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveObjectHostAdd, strDeviceAddress, STR_TCP_PROTOCOL, iDestDeviceDriverPort);
731 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress, STR_TCP_PROTOCOL, iDestDeviceDriverPort);
732 routerConfig.configureRouterHTTPPolicies(STR_ROUTER_ADD, strIoTSlaveObjectHostAdd, strDeviceAddress);
733 routerConfig.configureHostHTTPPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress);
734 // Configure MAC policies
735 processJailConfig.configureProcessJailGWDevicePolicies(strIoTSlaveObjectHostAdd, STR_ROUTER_ADD, INT_DNS_PORT);
737 // Other port numbers...
738 commHan.addDevicePort(iDestDeviceDriverPort);
739 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveObjectHostAdd, strDeviceAddress, strProtocol,
740 commHan.getComPort(strDeviceAddressKey), iDestDeviceDriverPort);
741 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress, strProtocol,
742 commHan.getComPort(strDeviceAddressKey), iDestDeviceDriverPort);
743 // Configure MAC policies
744 processJailConfig.configureProcessJailDevicePolicies(strIoTSlaveObjectHostAdd, strProtocol,
745 commHan.getComPort(strDeviceAddressKey), strDeviceAddress, iDestDeviceDriverPort);
751 * A private method to set router policies for IoTAddress objects
753 * @params strFieldIdentifier String field name + object ID
754 * @params Map.Entry<String,Object> Entry of map IoTSet instrumentation
755 * @params strHostAddress String host address
758 private void setRouterPolicyIoTSetAddress(String strFieldIdentifier, Map.Entry<String,Object> map,
759 String strHostAddress, String strControllerName) {
761 // Get information from the set
762 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
763 int iRows = setInstrumenter.numberOfRows();
764 RuntimeOutput.print("IoTMaster: Number of rows for IoTAddress: " + iRows, BOOL_VERBOSE);
765 // Transfer the address
766 for(int iRow=0; iRow<iRows; iRow++) {
767 arrFieldValues = setInstrumenter.fieldValues(iRow);
768 objAddInitHand.addField(strFieldIdentifier, arrFieldValues); // Save this for object instantiation
769 // Get device address
770 String strAddress = (String) arrFieldValues[0];
771 // Setting up router policies for HTTP/HTTPs
772 if (strControllerName != null) {
773 processJailConfig.configureProcessJailInetAddressPolicies(strControllerName, strAddress);
775 processJailConfig.configureProcessJailInetAddressPolicies(strHostAddress, strAddress);
777 routerConfig.configureRouterHTTPPolicies(STR_ROUTER_ADD, strHostAddress, strAddress);
778 routerConfig.configureHostHTTPPolicies(strHostAddress, strHostAddress, strAddress);
783 * A private method to instrument an object's IoTSet and IoTRelation field to up policies
785 * Mostly the IoTSet fields would contain IoTDeviceAddress objects
787 * @params strFieldObjectID String field object ID
788 * @params strLanguage String language
791 private void instrumentObjectIoTSet(String strFieldObjectID, String strLanguage) throws IOException {
793 // If this is a new object ... then create one
794 // Instrument the class source code and look for IoTSet for device addresses
795 // e.g. @config private IoTSet<IoTDeviceAddress> lb_addresses;
796 HashMap<String,Object> hmObjectFieldObjects = null;
797 if(strLanguage.equals(STR_JAVA)) {
798 String strObjectClassNamePath = STR_IOT_CODE_PATH + strObjClassName + "/" + strObjClassName + STR_CLS_FILE_EXT;
799 FileInputStream fis = new FileInputStream(strObjectClassNamePath);
800 ClassReader cr = new ClassReader(fis);
801 ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
802 // We need Object ID to instrument IoTDeviceAddress
803 ClassRuntimeInstrumenterMaster crim = new ClassRuntimeInstrumenterMaster(cw, strFieldObjectID, BOOL_VERBOSE);
806 mapClassNameToCrim.put(strObjClassName + strFieldObjectID, crim);
807 hmObjectFieldObjects = crim.getFieldObjects();
809 String strObjectClassNamePath = STR_IOT_CODE_PATH + strObjClassName + "/" + strObjClassName + STR_CFG_FILE_EXT;
810 CRuntimeInstrumenterMaster crim = new CRuntimeInstrumenterMaster(strObjectClassNamePath, strFieldObjectID, BOOL_VERBOSE);
811 mapClassNameToCrim.put(strObjClassName + strFieldObjectID, crim);
812 hmObjectFieldObjects = crim.getFieldObjects();
814 // Get the object and the class names
815 // Build objects for IoTSet and IoTRelation fields in the device object classes
816 RuntimeOutput.print("IoTMaster: Going to instrument for " + strObjClassName + " with objectID " +
817 strFieldObjectID, BOOL_VERBOSE);
818 for(Map.Entry<String,Object> map : hmObjectFieldObjects.entrySet()) {
819 RuntimeOutput.print("IoTMaster: Object name: " + map.getValue().getClass().getName(), BOOL_VERBOSE);
820 // Iterate over HashMap and choose between processing
821 String strFieldName = map.getKey();
822 String strClassName = map.getValue().getClass().getName();
823 String strFieldIdentifier = strFieldName + strFieldObjectID;
824 if(strClassName.equals(STR_SET_INSTRUMENTER_CLS)) {
825 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
826 if(setInstrumenter.getObjTableName().equals(STR_IOT_DEV_ADD_CLS)) {
827 // Instrument the normal IoTDeviceAddress
828 setRouterPolicyIoTSetDevice(strFieldIdentifier, map, strIoTSlaveObjectHostAdd);
829 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ADD_CLS)) {
830 // Instrument the IoTAddress
831 setRouterPolicyIoTSetAddress(strFieldIdentifier, map, strIoTSlaveObjectHostAdd, null);
832 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ZB_ADD_CLS)) {
833 // Instrument the IoTZigbeeAddress - special feature for Zigbee device support
834 RuntimeOutput.print("IoTMaster: IoTZigbeeAddress found! No router policy is set here..",
837 String strErrMsg = "IoTMaster: Device driver object" +
838 " can only have IoTSet<IoTAddress>, IoTSet<IoTDeviceAddress>," +
839 " or IoTSet<IoTZigbeeAddress>!";
840 throw new Error(strErrMsg);
843 String strErrMsg = "IoTMaster: Device driver object can only have IoTSet for addresses!";
844 throw new Error(strErrMsg);
851 * A private method to send files to a Java slave driver
853 * @params serverSocket ServerSocket
854 * @params _inStream InputStream
855 * @params _outStream OutputStream
856 * @params strObjName String
857 * @params strObjClassName String
858 * @params strObjClassInterfaceName String
859 * @params strObjStubClsIntfaceName String
860 * @params strIoTSlaveObjectHostAdd String
861 * @params strFieldObjectID String
862 * @params arrFieldValues Object[]
863 * @params arrFieldClasses Class[]
866 private void sendFileToJavaSlaveDriver(ServerSocket serverSocket, InputStream _inStream, OutputStream _outStream,
867 String strObjName, String strObjClassName, String strObjClassInterfaceName, String strObjStubClsIntfaceName,
868 String strIoTSlaveObjectHostAdd, String strFieldObjectID, Object[] arrFieldValues, Class[] arrFieldClasses)
869 throws IOException, ClassNotFoundException {
871 ObjectInputStream inStream = (ObjectInputStream) _inStream;
872 ObjectOutputStream outStream = (ObjectOutputStream) _outStream;
873 // Create message to transfer file first
874 String sFileName = strObjClassName + STR_JAR_FILE_EXT;
875 String sPath = STR_IOT_CODE_PATH + strObjClassName + "/" + sFileName;
876 File file = new File(sPath);
877 commMasterToSlave(new MessageSendFile(IoTCommCode.TRANSFER_FILE, sFileName, file.length()),
878 "Sending file!", inStream, outStream);
879 // Send file - JAR file for object creation
880 sendFile(serverSocket.accept(), sPath, file.length());
881 Message msgReply = (Message) inStream.readObject();
882 RuntimeOutput.print("IoTMaster: Reply message: " + msgReply.getMessage(), BOOL_VERBOSE);
883 // Pack object information to create object on a IoTSlave
884 Message msgObjIoTSlave = new MessageCreateObject(IoTCommCode.CREATE_OBJECT, strIoTSlaveObjectHostAdd,
885 strObjClassName, strObjName, strObjClassInterfaceName, strObjStubClsIntfaceName, commHan.getRMIRegPort(strObjName),
886 commHan.getRMIStubPort(strObjName), arrFieldValues, arrFieldClasses);
888 commMasterToSlave(msgObjIoTSlave, "Sending object information", inStream, outStream);
893 * A private method to send files to a Java slave driver
897 private void sendFileToCppSlaveDriver(String strObjClassName, String strIoTSlaveObjectHostAdd)
898 throws IOException, ClassNotFoundException {
900 // Create message to transfer file first
901 String sFileName = strObjClassName + STR_ZIP_FILE_EXT;
902 String sFile = STR_IOT_CODE_PATH + strObjClassName + "/" + sFileName;
903 String strCmdSend = STR_SCP + " " + sFile + " " + STR_USERNAME + strIoTSlaveObjectHostAdd + ":" + STR_SLAVE_DIR;
904 runCommand(strCmdSend);
905 RuntimeOutput.print("IoTMaster: Executing: " + strCmdSend, BOOL_VERBOSE);
907 String strCmdUnzip = STR_SSH + " " + STR_USERNAME + strIoTSlaveObjectHostAdd + " cd " +
908 STR_SLAVE_DIR + " sudo unzip -o " + sFileName + ";";
909 runCommand(strCmdUnzip);
910 RuntimeOutput.print("IoTMaster: Executing: " + strCmdUnzip, BOOL_VERBOSE);
916 * Construct command line for Java IoTSlave
920 private String getCmdJavaDriverIoTSlave(String strIoTMasterHostAdd, String strIoTSlaveObjectHostAdd, String strObjName) {
922 // Create an Shell executable
923 String strJavaCommand = STR_SHELL_HEADER + "\nexec " + STR_JAVA_PATH + " " + STR_CLS_PATH + " " + STR_RMI_PATH + " " +
924 STR_RMI_HOSTNAME + strIoTSlaveObjectHostAdd + " " + STR_IOT_SLAVE_CLS + " " + strIoTMasterHostAdd + " " +
925 commHan.getComPort(strObjName) + " " + commHan.getRMIRegPort(strObjName) + " " +
926 commHan.getRMIStubPort(strObjName) + " > " + STR_LOG_FILE_PATH + strObjName + ".log &";
927 String shellFile = "./" + strObjName + STR_SHELL_FILE_EXT;
928 createWrapperShellScript(strJavaCommand, shellFile);
929 // Send the file to the compute node
930 String strCmdSend = "scp " + shellFile + " " + STR_USERNAME + strIoTSlaveObjectHostAdd + ":" + STR_RUNTIME_DIR;
931 runCommand(strCmdSend);
932 System.out.println("IoTMaster: Sending shell file: " + strCmdSend);
933 return STR_SSH + " " + STR_USERNAME + strIoTSlaveObjectHostAdd + " cd " + STR_RUNTIME_DIR + " " + shellFile;
938 * Construct command line for C++ IoTSlave
942 private String getCmdCppDriverIoTSlave(String strIoTMasterHostAdd, String strIoTSlaveObjectHostAdd, String strObjName) {
944 return STR_SSH + " " + STR_USERNAME + strIoTSlaveObjectHostAdd + " cd " +
945 STR_SLAVE_DIR + " sudo " + STR_IOTSLAVE_CPP + " " + strIoTMasterHostAdd + " " +
946 commHan.getComPort(strObjName) + " " + strObjName;
951 * createWrapperShellScript() gets a wrapper shell script
953 * @param strCommand String command
954 * @param strObjectName String object name
955 * @return PrintWriter
957 private void createWrapperShellScript(String strCommand, String strFileName) {
959 PrintWriter printWriter = getPrintWriter(strFileName);
960 printWriter.println(strCommand);
962 runCommand("chmod 755 " + strFileName);
967 * A private method to create an object on a specific machine
969 * @params strObjName String object name
970 * @params strObjClassName String object class name
971 * @params strObjClassInterfaceName String object class interface name
972 * @params strIoTSlaveObjectHostAdd String IoTSlave host address
973 * @params strFieldObjectID String field object ID
974 * @params arrFieldValues Array of field values
975 * @params arrFieldClasses Array of field classes
978 private void createObject(String strObjName, String strObjClassName, String strObjClassInterfaceName, String strObjStubClsIntfaceName,
979 String strIoTSlaveObjectHostAdd, String strFieldObjectID, Object[] arrFieldValues, Class[] arrFieldClasses)
980 throws IOException, FileNotFoundException, ClassNotFoundException, InterruptedException {
983 String sCfgFile = STR_IOT_CODE_PATH + strObjClassName + "/" + strObjClassName + STR_CFG_FILE_EXT;
984 String strLanguageDriver = parseConfigFile(sCfgFile, STR_LANGUAGE + "_" + strObjName);
985 if(strLanguageDriver == null) // Read just the field LANGUAGE if the first read is null
986 strLanguageDriver = parseConfigFile(sCfgFile, STR_LANGUAGE);
987 if(strLanguageDriver == null) // Check nullness for the second time - report if it is still null
988 throw new Error("IoTMaster: Language specification missing in config file: " + sCfgFile);
993 start = System.currentTimeMillis();
995 // Construct ssh command line
996 // e.g. ssh rtrimana@dw-2.eecs.uci.edu cd <path>;
997 // java -cp $CLASSPATH:./*.jar
998 // -Djava.rmi.server.codebase=file:./*.jar
999 // iotruntime.IoTSlave dw-1.eecs.uci.edu 46151 23829 42874 &
1000 // The In-Port for IoTMaster is the Out-Port for IoTSlave and vice versa
1001 String strSSHCommand = null;
1002 if(strLanguageDriver.equals(STR_JAVA))
1003 strSSHCommand = getCmdJavaDriverIoTSlave(strIoTMasterHostAdd, strIoTSlaveObjectHostAdd, strObjName);
1004 else if(strLanguageDriver.equals(STR_CPP))
1005 strSSHCommand = getCmdCppDriverIoTSlave(strIoTMasterHostAdd, strIoTSlaveObjectHostAdd, strObjName);
1007 throw new Error("IoTMaster: Language specification not recognized: " + strLanguageDriver);
1008 RuntimeOutput.print("IoTMaster: Language for " + strObjName + " is " + strLanguageDriver, BOOL_VERBOSE);
1010 RuntimeOutput.print(strSSHCommand, BOOL_VERBOSE);
1011 // Start a new thread to start a new JVM
1012 createThread(strSSHCommand);
1013 ServerSocket serverSocket = new ServerSocket(commHan.getComPort(strObjName));
1014 Socket socket = serverSocket.accept();
1015 //InputStream inStream = new ObjectInputStream(socket.getInputStream());
1016 //OutputStream outStream = new ObjectOutputStream(socket.getOutputStream());
1017 InputStream inStream = null;
1018 OutputStream outStream = null;
1019 if(strLanguageDriver.equals(STR_JAVA)) {
1020 inStream = new ObjectInputStream(socket.getInputStream());
1021 outStream = new ObjectOutputStream(socket.getOutputStream());
1022 } else { // At this point the language is certainly C++, otherwise would've complained above
1023 inStream = new BufferedInputStream(socket.getInputStream());
1024 outStream = new BufferedOutputStream(socket.getOutputStream());
1029 result = System.currentTimeMillis()-start;
1030 System.out.println("\n\n ==> Time needed to start JVM for " + strObjName + ": " + result + "\n\n");
1033 start = System.currentTimeMillis();
1035 if(strLanguageDriver.equals(STR_JAVA)) {
1036 sendFileToJavaSlaveDriver(serverSocket, inStream, outStream, strObjName,
1037 strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName,
1038 strIoTSlaveObjectHostAdd, strFieldObjectID, arrFieldValues, arrFieldClasses);
1040 sendFileToCppSlaveDriver(strObjClassName, strIoTSlaveObjectHostAdd);
1041 createObjectCpp(strObjName, strObjClassName, strObjClassInterfaceName, strIoTSlaveObjectHostAdd,
1042 commHan.getRMIRegPort(strObjName), commHan.getRMIStubPort(strObjName), arrFieldValues, arrFieldClasses,
1043 outStream, inStream);
1047 result = System.currentTimeMillis()-start;
1048 System.out.println("\n\n ==> Time needed to send JAR file for " + strObjName + ": " + result + "\n\n");
1051 start = System.currentTimeMillis();
1053 // Instrument the class source code and look for IoTSet for device addresses
1054 // e.g. @config private IoTSet<IoTDeviceAddress> lb_addresses;
1055 RuntimeOutput.print("IoTMaster: Instantiating for " + strObjClassName + " with objectID " + strFieldObjectID, BOOL_VERBOSE);
1056 // Get the object and the class names
1057 // Build objects for IoTSet and IoTRelation fields in the device object classes
1058 Object crimObj = mapClassNameToCrim.get(strObjClassName + strFieldObjectID);
1059 HashMap<String,Object> hmObjectFieldObjects = null;
1060 if (crimObj instanceof ClassRuntimeInstrumenterMaster) {
1061 ClassRuntimeInstrumenterMaster crim = (ClassRuntimeInstrumenterMaster) crimObj;
1062 hmObjectFieldObjects = crim.getFieldObjects();
1063 } else if (crimObj instanceof CRuntimeInstrumenterMaster) {
1064 CRuntimeInstrumenterMaster crim = (CRuntimeInstrumenterMaster) crimObj;
1065 hmObjectFieldObjects = crim.getFieldObjects();
1067 for(Map.Entry<String,Object> map : hmObjectFieldObjects.entrySet()) {
1068 RuntimeOutput.print("IoTMaster: Object name: " + map.getValue().getClass().getName(), BOOL_VERBOSE);
1069 // Iterate over HashMap and choose between processing
1070 String strFieldName = map.getKey();
1071 String strClassName = map.getValue().getClass().getName();
1072 String strFieldIdentifier = strFieldName + strFieldObjectID;
1073 if(strClassName.equals(STR_SET_INSTRUMENTER_CLS)) {
1074 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
1075 if(setInstrumenter.getObjTableName().equals(STR_IOT_DEV_ADD_CLS)) {
1076 // Instrument the normal IoTDeviceAddress
1077 synchronized(this) {
1078 instrumentIoTSetDevice(strFieldIdentifier, strObjName, strFieldName, strIoTSlaveObjectHostAdd, inStream, outStream, strLanguageDriver);
1080 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ZB_ADD_CLS)) {
1081 // Instrument the IoTZigbeeAddress - special feature for Zigbee device support
1082 synchronized(this) {
1083 instrumentIoTSetZBDevice(map, strObjName, strFieldName, strIoTSlaveObjectHostAdd, inStream, outStream, strLanguageDriver);
1085 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ADD_CLS)) {
1086 // Instrument the IoTAddress
1087 synchronized(this) {
1088 instrumentIoTSetAddress(strFieldIdentifier, strFieldName, inStream, outStream, strLanguageDriver);
1091 String strErrMsg = "IoTMaster: Device driver object can only have IoTSet<IoTAddress>, IoTSet<IoTDeviceAddress>," +
1092 " or IoTSet<IoTZigbeeAddress>!";
1093 throw new Error(strErrMsg);
1096 String strErrMsg = "IoTMaster: Device driver object can only have IoTSet for addresses!";
1097 throw new Error(strErrMsg);
1101 // TODO: Change this later
1102 if(strLanguageDriver.equals(STR_JAVA)) {
1103 ObjectOutputStream oStream = (ObjectOutputStream) outStream;
1104 oStream.writeObject(new MessageSimple(IoTCommCode.END_SESSION));
1105 } else { // C++ side for now will be running continuously because it's an infinite loop (not in a separate thread)
1106 createDriverObjectCpp(outStream, inStream);
1107 //endSessionCpp(outStream);
1111 result = System.currentTimeMillis()-start;
1112 System.out.println("\n\n ==> Time needed to create object " + strObjName + " and instrument IoTDeviceAddress: " + result + "\n\n");
1118 serverSocket.close();
1123 * A private method to create controller objects
1127 private void createDriverObjects() throws InterruptedException {
1129 // Create a list of threads
1130 List<Thread> threads = new ArrayList<Thread>();
1131 // Get the list of active controller objects and loop it
1132 List<String> listActiveControllerObject = commHan.getActiveControllerObjectList();
1133 for(String strObjName : listActiveControllerObject) {
1135 ObjectCreationInfo objCrtInfo = commHan.getObjectCreationInfo(strObjName);
1136 Thread objectThread = new Thread(new Runnable() {
1138 synchronized(this) {
1140 createObject(strObjName, objCrtInfo.getObjectClassName(), objCrtInfo.getObjectClassInterfaceName(),
1141 objCrtInfo.getObjectStubClassInterfaceName(), objCrtInfo.getIoTSlaveObjectHostAdd(),
1142 commHan.getFieldObjectID(strObjName), commHan.getArrayFieldValues(strObjName),
1143 commHan.getArrayFieldClasses(strObjName));
1144 } catch (IOException |
1145 ClassNotFoundException |
1146 InterruptedException ex) {
1147 ex.printStackTrace();
1152 threads.add(objectThread);
1153 objectThread.start();
1156 for (Thread thread : threads) {
1159 } catch (InterruptedException ex) {
1160 ex.printStackTrace();
1167 * A private method to instrument IoTSet
1169 * @params Map.Entry<String,Object> Entry of map IoTSet instrumentation
1170 * @params strFieldName String field name
1171 * @params strLanguage String language
1174 private void instrumentIoTSet(Map.Entry<String,Object> map, String strFieldName, String strObjControllerName, String strLanguage)
1175 throws IOException, ClassNotFoundException, InterruptedException {
1177 // Get information from the set
1178 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
1179 objInitHand.addField(strFieldName, IoTCommCode.CREATE_NEW_IOTSET);
1181 int iRows = setInstrumenter.numberOfRows();
1182 for(int iRow=0; iRow<iRows; iRow++) {
1183 // Get field classes and values
1184 arrFieldClasses = setInstrumenter.fieldClasses(iRow);
1185 arrFieldValues = setInstrumenter.fieldValues(iRow);
1186 // Get object ID and class name
1187 String strObjID = setInstrumenter.fieldObjectID(iRow);
1188 strObjClassName = setInstrumenter.fieldEntryType(strObjID);
1189 // Call the method to create an object
1190 instrumentObject(strObjID, strObjControllerName, strLanguage);
1191 objInitHand.addObjectIntoField(strFieldName, strIoTSlaveObjectHostAdd, strObjName,
1192 strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName, commHan.getRMIRegPort(strObjName),
1193 commHan.getRMIStubPort(strObjName));
1199 * A private method to instrument IoTRelation
1201 * @params Map.Entry<String,Object> Entry of map IoTRelation instrumentation
1202 * @params strFieldName String field name
1203 * @params strLanguage String language
1206 private void instrumentIoTRelation(Map.Entry<String,Object> map, String strFieldName, String strObjControllerName, String strLanguage)
1207 throws IOException, ClassNotFoundException, InterruptedException {
1209 // Get information from the set
1210 RelationInstrumenter relationInstrumenter = (RelationInstrumenter) map.getValue();
1211 int iRows = relationInstrumenter.numberOfRows();
1212 objInitHand.addField(strFieldName, IoTCommCode.CREATE_NEW_IOTRELATION);
1214 for(int iRow=0; iRow<iRows; iRow++) {
1215 // Operate on the first set first
1216 arrFieldClasses = relationInstrumenter.firstFieldClasses(iRow);
1217 arrFieldValues = relationInstrumenter.firstFieldValues(iRow);
1218 String strObjID = relationInstrumenter.firstFieldObjectID(iRow);
1219 strObjClassName = relationInstrumenter.firstEntryFieldType(strObjID);
1220 // Call the method to create an object
1221 instrumentObject(strObjID, strObjControllerName, strLanguage);
1222 // Get the first object controller host address
1223 String strFirstIoTSlaveObjectHostAdd = strIoTSlaveObjectHostAdd;
1224 objInitHand.addObjectIntoField(strFieldName, strIoTSlaveObjectHostAdd, strObjName,
1225 strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName,
1226 commHan.getRMIRegPort(strObjName), commHan.getRMIStubPort(strObjName));
1227 // Operate on the second set
1228 arrFieldClasses = relationInstrumenter.secondFieldClasses(iRow);
1229 arrFieldValues = relationInstrumenter.secondFieldValues(iRow);
1230 strObjID = relationInstrumenter.secondFieldObjectID(iRow);
1231 strObjClassName = relationInstrumenter.secondEntryFieldType(strObjID);
1232 // Call the method to create an object
1233 instrumentObject(strObjID, strObjControllerName, strLanguage);
1234 // Get the second object controller host address
1235 String strSecondIoTSlaveObjectHostAdd = strIoTSlaveObjectHostAdd;
1236 objInitHand.addSecondObjectIntoField(strFieldName, strIoTSlaveObjectHostAdd, strObjName,
1237 strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName,
1238 commHan.getRMIRegPort(strObjName), commHan.getRMIStubPort(strObjName));
1239 // ROUTING POLICY: first and second controller objects in IoTRelation
1240 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strFirstIoTSlaveObjectHostAdd,
1241 strSecondIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
1242 // ROUTING POLICY: Send the same routing policy to both the hosts
1243 routerConfig.configureHostMainPolicies(strFirstIoTSlaveObjectHostAdd, strFirstIoTSlaveObjectHostAdd,
1244 strSecondIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
1245 routerConfig.configureHostMainPolicies(strSecondIoTSlaveObjectHostAdd, strFirstIoTSlaveObjectHostAdd,
1246 strSecondIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
1251 * A method to reinitialize IoTSet and IoTRelation in the code based on ObjectInitHandler information
1253 * @params inStream ObjectInputStream communication
1254 * @params outStream ObjectOutputStream communication
1257 private void initializeSetsAndRelationsJava(InputStream inStream, OutputStream outStream)
1258 throws IOException, ClassNotFoundException {
1259 // Get list of fields
1260 List<String> strFields = objInitHand.getListOfFields();
1261 // Iterate on HostAddress
1262 for(String str : strFields) {
1263 IoTCommCode iotcommMsg = objInitHand.getFieldMessage(str);
1264 if (iotcommMsg == IoTCommCode.CREATE_NEW_IOTSET) {
1265 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO CREATE IOTSET
1266 Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, str);
1267 commMasterToSlave(msgCrtIoTSet, "Create new IoTSet!", inStream, outStream);
1268 List<ObjectInitInfo> listObject = objInitHand.getListObjectInitInfo(str);
1269 for (ObjectInitInfo objInitInfo : listObject) {
1270 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTSET
1271 commMasterToSlave(new MessageGetObject(IoTCommCode.GET_IOTSET_OBJECT, objInitInfo.getIoTSlaveObjectHostAdd(),
1272 objInitInfo.getObjectName(), objInitInfo.getObjectClassName(), objInitInfo.getObjectClassInterfaceName(),
1273 objInitInfo.getObjectStubClassInterfaceName(), objInitInfo.getRMIRegistryPort(), objInitInfo.getRMIStubPort()),
1274 "Get IoTSet object!", inStream, outStream);
1277 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO REINITIALIZE IOTSET FIELD
1278 commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTSET_FIELD),
1279 "Renitialize IoTSet field!", inStream, outStream);
1280 } else if (iotcommMsg == IoTCommCode.CREATE_NEW_IOTRELATION) {
1281 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO CREATE IOTRELATION
1282 Message msgCrtIoTRel = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTRELATION, str);
1283 commMasterToSlave(msgCrtIoTRel, "Create new IoTRelation!", inStream, outStream);
1284 List<ObjectInitInfo> listObject = objInitHand.getListObjectInitInfo(str);
1285 List<ObjectInitInfo> listSecondObject = objInitHand.getSecondObjectInitInfo(str);
1286 Iterator it = listSecondObject.iterator();
1287 for (ObjectInitInfo objInitInfo : listObject) {
1288 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTRELATION (FIRST OBJECT)
1289 commMasterToSlave(new MessageGetObject(IoTCommCode.GET_IOTRELATION_FIRST_OBJECT,
1290 objInitInfo.getIoTSlaveObjectHostAdd(), objInitInfo.getObjectName(), objInitInfo.getObjectClassName(),
1291 objInitInfo.getObjectClassInterfaceName(), objInitInfo.getObjectStubClassInterfaceName(),
1292 objInitInfo.getRMIRegistryPort(), objInitInfo.getRMIStubPort()),
1293 "Get IoTRelation first object!", inStream, outStream);
1294 ObjectInitInfo objSecObj = (ObjectInitInfo) it.next();
1295 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTRELATION (SECOND OBJECT)
1296 commMasterToSlave(new MessageGetObject(IoTCommCode.GET_IOTRELATION_SECOND_OBJECT,
1297 objSecObj.getIoTSlaveObjectHostAdd(), objSecObj.getObjectName(), objSecObj.getObjectClassName(),
1298 objSecObj.getObjectClassInterfaceName(), objSecObj.getObjectStubClassInterfaceName(),
1299 objSecObj.getRMIRegistryPort(), objSecObj.getRMIStubPort()),
1300 "Get IoTRelation second object!", inStream, outStream);
1302 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO REINITIALIZE IOTRELATION FIELD
1303 commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTRELATION_FIELD),
1304 "Renitialize IoTRelation field!", inStream, outStream);
1310 * A method to reinitialize IoTSet and IoTRelation in the code based on ObjectInitHandler information
1312 * @params inStream ObjectInputStream communication
1313 * @params outStream ObjectOutputStream communication
1316 private void initializeSetsAndRelationsCpp(InputStream inStream, OutputStream outStream)
1317 throws IOException, ClassNotFoundException {
1318 // Get list of fields
1319 List<String> strFields = objInitHand.getListOfFields();
1320 // Iterate on HostAddress
1321 for(String str : strFields) {
1322 IoTCommCode iotcommMsg = objInitHand.getFieldMessage(str);
1323 if (iotcommMsg == IoTCommCode.CREATE_NEW_IOTSET) {
1324 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO CREATE IOTSET
1325 createNewIoTSetCpp(str, outStream, inStream);
1326 List<ObjectInitInfo> listObject = objInitHand.getListObjectInitInfo(str);
1327 for (ObjectInitInfo objInitInfo : listObject) {
1328 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTSET
1329 getIoTSetRelationObjectCpp(IoTCommCode.GET_IOTSET_OBJECT, objInitInfo.getIoTSlaveObjectHostAdd(), objInitInfo.getObjectName(),
1330 objInitInfo.getObjectClassName(), objInitInfo.getObjectClassInterfaceName(), objInitInfo.getObjectStubClassInterfaceName(),
1331 objInitInfo.getRMIRegistryPort(), objInitInfo.getRMIStubPort(), outStream, inStream);
1333 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO REINITIALIZE IOTSET FIELD
1334 reinitializeIoTSetFieldCpp(outStream, inStream);
1335 } else if (iotcommMsg == IoTCommCode.CREATE_NEW_IOTRELATION) {
1336 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO CREATE IOTRELATION
1337 // TODO: createNewIoTRelation needs to be created here!
1338 createNewIoTRelationCpp(str, outStream, inStream);
1339 List<ObjectInitInfo> listObject = objInitHand.getListObjectInitInfo(str);
1340 List<ObjectInitInfo> listSecondObject = objInitHand.getSecondObjectInitInfo(str);
1341 Iterator it = listSecondObject.iterator();
1342 for (ObjectInitInfo objInitInfo : listObject) {
1343 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTRELATION (FIRST OBJECT)
1344 getIoTSetRelationObjectCpp(IoTCommCode.GET_IOTRELATION_FIRST_OBJECT, objInitInfo.getIoTSlaveObjectHostAdd(), objInitInfo.getObjectName(),
1345 objInitInfo.getObjectClassName(), objInitInfo.getObjectClassInterfaceName(), objInitInfo.getObjectStubClassInterfaceName(),
1346 objInitInfo.getRMIRegistryPort(), objInitInfo.getRMIStubPort(), outStream, inStream);
1347 ObjectInitInfo objSecObj = (ObjectInitInfo) it.next();
1348 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTRELATION (SECOND OBJECT)
1349 getIoTSetRelationObjectCpp(IoTCommCode.GET_IOTRELATION_SECOND_OBJECT, objSecObj.getIoTSlaveObjectHostAdd(), objSecObj.getObjectName(),
1350 objSecObj.getObjectClassName(), objSecObj.getObjectClassInterfaceName(), objSecObj.getObjectStubClassInterfaceName(),
1351 objSecObj.getRMIRegistryPort(), objSecObj.getRMIStubPort(), outStream, inStream);
1353 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO REINITIALIZE IOTRELATION FIELD
1354 reinitializeIoTRelationFieldCpp(outStream, inStream);
1360 * A method to set router basic policies at once
1362 * @param strRouter String router name
1365 private void setRouterBasicPolicies(String strRouter) {
1367 String strMonitorHost = routerConfig.getIPFromMACAddress(STR_MONITORING_HOST);
1368 routerConfig.configureRouterICMPPolicies(strRouter, strMonitorHost);
1369 routerConfig.configureRouterDHCPPolicies(strRouter);
1370 routerConfig.configureRouterDNSPolicies(strRouter);
1371 routerConfig.configureRouterSSHPolicies(strRouter, strMonitorHost);
1372 routerConfig.configureRejectPolicies(strRouter);
1376 * A method to set host basic policies at once
1378 * @param strHost String host name
1381 private void setHostBasicPolicies(String strHost) {
1383 String strMonitorHost = routerConfig.getIPFromMACAddress(STR_MONITORING_HOST);
1384 routerConfig.configureHostDHCPPolicies(strHost);
1385 routerConfig.configureHostDNSPolicies(strHost);
1386 if (strHost.equals(strMonitorHost)) {
1387 // Check if this is the monitoring host
1388 routerConfig.configureHostICMPPolicies(strHost);
1389 routerConfig.configureHostSSHPolicies(strHost);
1391 routerConfig.configureHostICMPPolicies(strHost, strMonitorHost);
1392 routerConfig.configureHostSSHPolicies(strHost, strMonitorHost);
1394 // Apply SQL allowance policies to master host
1395 if (strHost.equals(strIoTMasterHostAdd)) {
1396 routerConfig.configureHostSQLPolicies(strHost);
1398 routerConfig.configureRejectPolicies(strHost);
1402 * A method to create a thread for policy deployment
1404 * @param strRouterAddress String router address to configure
1405 * @param setHostAddresses Set of strings for host addresses to configure
1408 private void createPolicyThreads(String strRouterAddress, Set<String> setHostAddresses) throws IOException {
1410 // Create a list of threads
1411 List<Thread> threads = new ArrayList<Thread>();
1412 // Start threads for hosts
1413 for(String strAddress : setHostAddresses) {
1414 Thread policyThread = new Thread(new Runnable() {
1416 synchronized(this) {
1417 routerConfig.sendHostPolicies(strAddress);
1421 threads.add(policyThread);
1422 policyThread.start();
1423 RuntimeOutput.print("Deploying policies for: " + strAddress, BOOL_VERBOSE);
1425 // A thread for router
1426 Thread policyThread = new Thread(new Runnable() {
1428 synchronized(this) {
1429 routerConfig.sendRouterPolicies(strRouterAddress);
1433 threads.add(policyThread);
1434 policyThread.start();
1435 RuntimeOutput.print("Deploying policies on router: " + strRouterAddress, BOOL_VERBOSE);
1437 for (Thread thread : threads) {
1440 } catch (InterruptedException ex) {
1441 ex.printStackTrace();
1447 * A method to create a thread for policy deployment
1449 * @param setHostAddresses Set of strings for host addresses to configure
1452 private void createMACPolicyThreads(Set<String> setHostAddresses) throws IOException {
1454 // Create a list of threads
1455 List<Thread> threads = new ArrayList<Thread>();
1456 // Start threads for hosts
1457 for(String strAddress : setHostAddresses) {
1458 Thread policyThread = new Thread(new Runnable() {
1460 synchronized(this) {
1461 processJailConfig.sendMACPolicies(strAddress);
1465 threads.add(policyThread);
1466 policyThread.start();
1467 RuntimeOutput.print("Deploying MAC policies for: " + strAddress, BOOL_VERBOSE);
1470 for (Thread thread : threads) {
1473 } catch (InterruptedException ex) {
1474 ex.printStackTrace();
1481 * A method to send files to Java IoTSlave
1483 * @params strObjControllerName String
1484 * @params serverSocket ServerSocket
1485 * @params inStream ObjectInputStream communication
1486 * @params outStream ObjectOutputStream communication
1489 private void sendFileToJavaSlave(String strObjControllerName, ServerSocket serverSocket,
1490 InputStream _inStream, OutputStream _outStream) throws IOException, ClassNotFoundException {
1492 ObjectInputStream inStream = (ObjectInputStream) _inStream;
1493 ObjectOutputStream outStream = (ObjectOutputStream) _outStream;
1495 String strControllerJarName = strObjControllerName + STR_JAR_FILE_EXT;
1496 String strControllerJarNamePath = STR_CONT_PATH + strObjControllerName + "/" +
1497 strControllerJarName;
1498 File file = new File(strControllerJarNamePath);
1499 commMasterToSlave(new MessageSendFile(IoTCommCode.TRANSFER_FILE, strControllerJarName, file.length()),
1500 "Sending file!", inStream, outStream);
1501 // Send file - Class file for object creation
1502 sendFile(serverSocket.accept(), strControllerJarNamePath, file.length());
1503 Message msgReply = (Message) inStream.readObject();
1504 RuntimeOutput.print("IoTMaster: Reply message: " + msgReply.getMessage(), BOOL_VERBOSE);
1505 // Send .zip file if additional zip file is specified
1506 String strObjCfgFile = strObjControllerName + STR_CFG_FILE_EXT;
1507 String strObjCfgFilePath = STR_CONT_PATH + strObjControllerName + "/" + strObjCfgFile;
1508 String strAdditionalFile = parseConfigFile(strObjCfgFilePath, STR_FILE_TRF_CFG);
1509 if (strAdditionalFile.equals(STR_YES)) {
1510 String strControllerCmpName = strObjControllerName + STR_ZIP_FILE_EXT;
1511 String strControllerCmpNamePath = STR_CONT_PATH + strObjControllerName + "/" +
1512 strControllerCmpName;
1513 file = new File(strControllerCmpNamePath);
1514 commMasterToSlave(new MessageSendFile(IoTCommCode.TRANSFER_FILE, strControllerCmpName, file.length()),
1515 "Sending file!", inStream, outStream);
1516 // Send file - Class file for object creation
1517 sendFile(serverSocket.accept(), strControllerCmpNamePath, file.length());
1518 msgReply = (Message) inStream.readObject();
1519 RuntimeOutput.print("IoTMaster: Reply message: " + msgReply.getMessage(), BOOL_VERBOSE);
1525 * A method to send files to C++ IoTSlave
1528 * TODO: Need to look into this (as of now, file transferred retains the "data" format,
1529 * hence it is unreadable from outside world
1531 private void sendFileToCppSlave(String sFilePath, String sFileName, Socket fileSocket,
1532 InputStream inStream, OutputStream outStream) throws IOException {
1534 sendCommCode(IoTCommCode.TRANSFER_FILE, outStream, inStream);
1536 sendString(sFileName, outStream); recvAck(inStream);
1537 File file = new File(sFilePath + sFileName);
1538 int iFileLen = toIntExact(file.length());
1539 RuntimeOutput.print("IoTMaster: Sending file " + sFileName + " with length " + iFileLen + " bytes...", BOOL_VERBOSE);
1541 sendInteger(iFileLen, outStream); recvAck(inStream);
1542 RuntimeOutput.print("IoTMaster: Sent file size!", BOOL_VERBOSE);
1543 byte[] bytFile = new byte[iFileLen];
1544 InputStream inFileStream = new FileInputStream(file);
1545 RuntimeOutput.print("IoTMaster: Opened file!", BOOL_VERBOSE);
1547 OutputStream outFileStream = fileSocket.getOutputStream();
1548 RuntimeOutput.print("IoTMaster: Got output stream!", BOOL_VERBOSE);
1550 while ((iCount = inFileStream.read(bytFile)) > 0) {
1551 outFileStream.write(bytFile, 0, iCount);
1553 RuntimeOutput.print("IoTMaster: File sent!", BOOL_VERBOSE);
1559 * A method to send files to C++ IoTSlave (now master using Process() to start
1560 * file transfer using scp)
1564 private void sendFileToCppSlave(String sFilePath, String sFileName) throws IOException {
1566 // Construct shell command to transfer file
1567 String sFile = sFilePath + sFileName;
1568 String strCmdSend = STR_SCP + " " + sFile + " " + STR_USERNAME + strIoTSlaveControllerHostAdd + ":" + STR_SLAVE_DIR;
1569 runCommand(strCmdSend);
1570 RuntimeOutput.print("IoTMaster: Executing: " + strCmdSend, BOOL_VERBOSE);
1572 String strCmdUnzip = STR_SSH + " " + STR_USERNAME + strIoTSlaveControllerHostAdd + " cd " +
1573 STR_SLAVE_DIR + " sudo unzip -o " + sFileName + ";";
1574 runCommand(strCmdUnzip);
1575 RuntimeOutput.print("IoTMaster: Executing: " + strCmdUnzip, BOOL_VERBOSE);
1580 * runCommand() method runs shell command
1582 * @param strCommand String that contains command line
1585 private void runCommand(String strCommand) {
1588 Runtime runtime = Runtime.getRuntime();
1589 Process process = runtime.exec(strCommand);
1591 } catch (IOException ex) {
1592 System.out.println("RouterConfig: IOException: " + ex.getMessage());
1593 ex.printStackTrace();
1594 } catch (InterruptedException ex) {
1595 System.out.println("RouterConfig: InterruptException: " + ex.getMessage());
1596 ex.printStackTrace();
1602 * Construct command line for Java IoTSlave
1606 private String getCmdJavaIoTSlave(String strObjControllerName) {
1608 // Create an Shell executable
1609 String strJavaCommand = STR_SHELL_HEADER + "\nexec " + STR_JAVA_PATH + " " + STR_JVM_INIT_HEAP_SIZE + " " +
1610 STR_JVM_MAX_HEAP_SIZE + " " + STR_CLS_PATH + " " + STR_RMI_PATH + " " + STR_IOT_SLAVE_CLS + " " +
1611 strIoTMasterHostAdd + " " + commHan.getComPort(strObjControllerName) + " " +
1612 commHan.getRMIRegPort(strObjControllerName) + " " + commHan.getRMIStubPort(strObjControllerName) +
1613 " > " + STR_LOG_FILE_PATH + strObjControllerName + ".log &";
1614 String shellFile = "./" + strObjControllerName + STR_SHELL_FILE_EXT;
1615 createWrapperShellScript(strJavaCommand, shellFile);
1616 // Send the file to the compute node
1617 String strCmdSend = "scp " + shellFile + " " + STR_USERNAME + strIoTSlaveControllerHostAdd + ":" + STR_RUNTIME_DIR;
1618 runCommand(strCmdSend);
1619 System.out.println("IoTMaster: Sending main controller shell file: " + strCmdSend);
1620 return STR_SSH + " " + STR_USERNAME + strIoTSlaveControllerHostAdd + " cd " + STR_RUNTIME_DIR + " " + shellFile;
1625 * Construct command line for C++ IoTSlave
1629 private String getCmdCppIoTSlave(String strObjControllerName) {
1631 return STR_SSH + " " + STR_USERNAME + strIoTSlaveControllerHostAdd + " cd " +
1632 STR_SLAVE_DIR + " sudo " + STR_IOTSLAVE_CPP + " " + strIoTMasterHostAdd + " " +
1633 commHan.getComPort(strObjControllerName) + " " + strObjControllerName;
1638 * sendInteger() sends an integer in bytes
1640 public void sendInteger(int intSend, OutputStream outStream) throws IOException {
1642 BufferedOutputStream output = (BufferedOutputStream) outStream;
1643 // Transform integer into bytes
1644 ByteBuffer bb = ByteBuffer.allocate(INT_SIZE);
1646 // Send the byte array
1647 output.write(bb.array(), 0, INT_SIZE);
1653 * recvInteger() receives integer in bytes
1655 public int recvInteger(InputStream inStream) throws IOException {
1657 BufferedInputStream input = (BufferedInputStream) inStream;
1658 // Wait until input is available
1659 while(input.available() == 0);
1660 // Read integer - 4 bytes
1661 byte[] recvInt = new byte[INT_SIZE];
1662 input.read(recvInt, 0, INT_SIZE);
1663 int retVal = ByteBuffer.wrap(recvInt).getInt();
1670 * recvString() receives String in bytes
1672 public String recvString(InputStream inStream) throws IOException {
1674 BufferedInputStream input = (BufferedInputStream) inStream;
1675 int strLen = recvInteger(inStream);
1676 // Wait until input is available
1677 while(input.available() == 0);
1678 // Read String per strLen
1679 byte[] recvStr = new byte[strLen];
1680 input.read(recvStr, 0, strLen);
1681 String retVal = new String(recvStr);
1688 * sendString() sends a String in bytes
1690 public void sendString(String strSend, OutputStream outStream) throws IOException {
1692 BufferedOutputStream output = (BufferedOutputStream) outStream;
1693 // Transform String into bytes
1694 byte[] strSendBytes = strSend.getBytes();
1695 int strLen = strSend.length();
1696 // Send the string length first
1697 sendInteger(strLen, outStream);
1698 // Send the byte array
1699 output.write(strSendBytes, 0, strLen);
1705 * Convert integer to enum
1707 public IoTCommCode getCode(int intCode) throws IOException {
1709 IoTCommCode[] commCode = IoTCommCode.values();
1710 IoTCommCode retCode = commCode[intCode];
1719 public synchronized boolean recvAck(InputStream inStream) throws IOException {
1721 int intAck = recvInteger(inStream);
1722 IoTCommCode codeAck = getCode(intAck);
1723 if (codeAck == IoTCommCode.ACKNOWLEDGED)
1733 public void sendEndTransfer(OutputStream outStream) throws IOException {
1735 int endCode = IoTCommCode.END_TRANSFER.ordinal();
1736 sendInteger(endCode, outStream);
1741 * Send communication code to C++
1743 public void sendCommCode(IoTCommCode inpCommCode, OutputStream outStream, InputStream inStream) throws IOException {
1746 IoTCommCode commCode = inpCommCode;
1747 int intCode = commCode.ordinal();
1748 // TODO: delete this later
1749 System.out.println("DEBUG: Sending " + commCode + " with ordinal: " + intCode);
1750 sendInteger(intCode, outStream); recvAck(inStream);
1755 * Create a main controller object for C++
1757 public void createMainObjectCpp(String strObjControllerName, OutputStream outStream, InputStream inStream) throws IOException {
1759 sendCommCode(IoTCommCode.CREATE_MAIN_OBJECT, outStream, inStream);
1760 String strMainObjName = strObjControllerName;
1761 sendString(strMainObjName, outStream); recvAck(inStream);
1762 RuntimeOutput.print("IoTMaster: Create a main object: " + strMainObjName, BOOL_VERBOSE);
1767 * A helper function that converts Class into String
1769 * @param strDataType String MySQL data type
1772 public String getClassConverted(Class<?> cls) {
1774 if (cls == String.class) {
1776 } else if (cls == int.class) {
1785 * A helper function that converts Object into String for transfer to C++ slave
1787 * @param obj Object to be converted
1788 * @param strClassType String Java Class type
1791 public String getObjectConverted(Object obj) {
1793 if (obj instanceof String) {
1794 return (String) obj;
1795 } else if (obj instanceof Integer) {
1796 return Integer.toString((Integer) obj);
1804 * Create a driver object for C++
1806 public void createObjectCpp(String strObjName, String strObjClassName, String strObjClassInterfaceName, String strIoTSlaveObjectHostAdd,
1807 Integer iRMIRegistryPort, Integer iRMIStubPort, Object[] arrFieldValues, Class[] arrFieldClasses,
1808 OutputStream outStream, InputStream inStream) throws IOException {
1810 sendCommCode(IoTCommCode.CREATE_OBJECT, outStream, inStream);
1811 RuntimeOutput.print("IoTMaster: Send request to create a driver object... ", BOOL_VERBOSE);
1812 RuntimeOutput.print("IoTMaster: Driver object name: " + strObjName, BOOL_VERBOSE);
1813 sendString(strObjName, outStream); recvAck(inStream);
1814 RuntimeOutput.print("IoTMaster: Driver object class name: " + strObjClassName, BOOL_VERBOSE);
1815 sendString(strObjClassName, outStream); recvAck(inStream);
1816 RuntimeOutput.print("IoTMaster: Driver object interface name: " + strObjClassInterfaceName, BOOL_VERBOSE);
1817 sendString(strObjStubClsIntfaceName, outStream); recvAck(inStream);
1818 RuntimeOutput.print("IoTMaster: Driver object skeleton class name: " + strObjClassInterfaceName + STR_SKEL_CLASS_SUFFIX, BOOL_VERBOSE);
1819 sendString(strObjClassInterfaceName + STR_SKEL_CLASS_SUFFIX, outStream); recvAck(inStream);
1820 RuntimeOutput.print("IoTMaster: Driver object registry port: " + iRMIRegistryPort, BOOL_VERBOSE);
1821 sendInteger(iRMIRegistryPort, outStream); recvAck(inStream);
1822 RuntimeOutput.print("IoTMaster: Driver object stub port: " + iRMIStubPort, BOOL_VERBOSE);
1823 sendInteger(iRMIStubPort, outStream); recvAck(inStream);
1824 int numOfArgs = arrFieldValues.length;
1825 RuntimeOutput.print("IoTMaster: Send constructor arguments! Number of arguments: " + numOfArgs, BOOL_VERBOSE);
1826 sendInteger(numOfArgs, outStream); recvAck(inStream);
1827 for(Object obj : arrFieldValues) {
1828 String str = getObjectConverted(obj);
1829 sendString(str, outStream); recvAck(inStream);
1831 RuntimeOutput.print("IoTMaster: Send constructor argument classes!", BOOL_VERBOSE);
1832 for(Class cls : arrFieldClasses) {
1833 String str = getClassConverted(cls);
1834 sendString(str, outStream); recvAck(inStream);
1840 * Create new IoTSet for C++
1842 public void createNewIoTSetCpp(String strObjFieldName, OutputStream outStream, InputStream inStream) throws IOException {
1844 sendCommCode(IoTCommCode.CREATE_NEW_IOTSET, outStream, inStream);
1845 RuntimeOutput.print("IoTMaster: Creating new IoTSet...", BOOL_VERBOSE);
1846 RuntimeOutput.print("IoTMaster: Send object field name: " + strObjFieldName, BOOL_VERBOSE);
1847 sendString(strObjFieldName, outStream); recvAck(inStream);
1852 * Create new IoTRelation for C++
1854 public void createNewIoTRelationCpp(String strObjFieldName, OutputStream outStream, InputStream inStream) throws IOException {
1856 sendCommCode(IoTCommCode.CREATE_NEW_IOTRELATION, outStream, inStream);
1857 RuntimeOutput.print("IoTMaster: Creating new IoTRelation...", BOOL_VERBOSE);
1858 RuntimeOutput.print("IoTMaster: Send object field name: " + strObjFieldName, BOOL_VERBOSE);
1859 sendString(strObjFieldName, outStream); recvAck(inStream);
1864 * Get a IoTDeviceAddress object for C++
1866 public void getDeviceIoTSetObjectCpp(OutputStream outStream, InputStream inStream,
1867 String strDeviceAddress, int iSourcePort, int iDestPort, boolean bSourceWildCard, boolean bDestWildCard) throws IOException {
1869 sendCommCode(IoTCommCode.GET_DEVICE_IOTSET_OBJECT, outStream, inStream);
1870 RuntimeOutput.print("IoTMaster: Getting IoTDeviceAddress...", BOOL_VERBOSE);
1871 sendString(strDeviceAddress, outStream); recvAck(inStream);
1872 sendInteger(iSourcePort, outStream); recvAck(inStream);
1873 sendInteger(iDestPort, outStream); recvAck(inStream);
1874 int iSourceWildCard = (bSourceWildCard ? 1 : 0);
1875 sendInteger(iSourceWildCard, outStream); recvAck(inStream);
1876 int iDestWildCard = (bDestWildCard ? 1 : 0);
1877 sendInteger(iDestWildCard, outStream); recvAck(inStream);
1878 RuntimeOutput.print("IoTMaster: Send device address: " + strDeviceAddress, BOOL_VERBOSE);
1883 * Get a IoTSet content object for C++
1885 public void getIoTSetRelationObjectCpp(IoTCommCode iotCommCode, String strIoTSlaveHostAddress, String strObjectName, String strObjectClassName,
1886 String strObjectClassInterfaceName, String strObjectStubClassInterfaceName, int iRMIRegistryPort, int iRMIStubPort,
1887 OutputStream outStream, InputStream inStream) throws IOException {
1889 sendCommCode(iotCommCode, outStream, inStream);
1890 RuntimeOutput.print("IoTMaster: Getting IoTSet object content...", BOOL_VERBOSE);
1892 RuntimeOutput.print("IoTMaster: Send host address: " + strIoTSlaveHostAddress, BOOL_VERBOSE);
1893 sendString(strIoTSlaveHostAddress, outStream); recvAck(inStream);
1894 RuntimeOutput.print("IoTMaster: Driver object name: " + strObjectName, BOOL_VERBOSE);
1895 sendString(strObjectName, outStream); recvAck(inStream);
1896 RuntimeOutput.print("IoTMaster: Driver object class name: " + strObjectClassName, BOOL_VERBOSE);
1897 sendString(strObjectClassName, outStream); recvAck(inStream);
1898 RuntimeOutput.print("IoTMaster: Driver object interface name: " + strObjectClassInterfaceName, BOOL_VERBOSE);
1899 sendString(strObjectClassInterfaceName, outStream); recvAck(inStream);
1900 RuntimeOutput.print("IoTMaster: Driver object stub class name: " + strObjectStubClassInterfaceName + STR_STUB_CLASS_SUFFIX, BOOL_VERBOSE);
1901 sendString(strObjectStubClassInterfaceName + STR_STUB_CLASS_SUFFIX, outStream); recvAck(inStream);
1902 RuntimeOutput.print("IoTMaster: Driver object registry port: " + iRMIRegistryPort, BOOL_VERBOSE);
1903 sendInteger(iRMIRegistryPort, outStream); recvAck(inStream);
1904 RuntimeOutput.print("IoTMaster: Driver object stub port: " + iRMIStubPort, BOOL_VERBOSE);
1905 sendInteger(iRMIStubPort, outStream); recvAck(inStream);
1910 * Reinitialize IoTRelation field for C++
1912 private void reinitializeIoTRelationFieldCpp(OutputStream outStream, InputStream inStream) throws IOException {
1914 RuntimeOutput.print("IoTMaster: About to Reinitialize IoTRelation field!", BOOL_VERBOSE);
1915 sendCommCode(IoTCommCode.REINITIALIZE_IOTRELATION_FIELD, outStream, inStream);
1916 RuntimeOutput.print("IoTMaster: Reinitialize IoTRelation field!", BOOL_VERBOSE);
1921 * Reinitialize IoTSet field for C++
1923 private void reinitializeIoTSetFieldCpp(OutputStream outStream, InputStream inStream) throws IOException {
1925 RuntimeOutput.print("IoTMaster: About to Reinitialize IoTSet field!", BOOL_VERBOSE);
1926 sendCommCode(IoTCommCode.REINITIALIZE_IOTSET_FIELD, outStream, inStream);
1927 RuntimeOutput.print("IoTMaster: Reinitialize IoTSet field!", BOOL_VERBOSE);
1932 * Create driver object for C++
1934 private void createDriverObjectCpp(OutputStream outStream, InputStream inStream) throws IOException {
1936 sendCommCode(IoTCommCode.CREATE_DRIVER_OBJECT, outStream, inStream);
1937 RuntimeOutput.print("IoTMaster: Send command to create driver object!", BOOL_VERBOSE);
1942 * Invoke init() for C++
1944 private void invokeInitMethodCpp(OutputStream outStream, InputStream inStream) throws IOException {
1946 sendCommCode(IoTCommCode.INVOKE_INIT_METHOD, outStream, inStream);
1947 RuntimeOutput.print("IoTMaster: Invoke init method!", BOOL_VERBOSE);
1952 * End session for C++
1954 public void endSessionCpp(OutputStream outStream) throws IOException {
1956 // Send message to end session
1957 IoTCommCode endSessionCode = IoTCommCode.END_SESSION;
1958 int intCode = endSessionCode.ordinal();
1959 sendInteger(intCode, outStream);
1960 //RuntimeOutput.print("IoTMaster: Send request to create a main object: " + strObjName, BOOL_VERBOSE);
1961 RuntimeOutput.print("IoTMaster: Send request to end session!", BOOL_VERBOSE);
1966 * A method to assign objects to multiple JVMs, including
1967 * the controller/device object that uses other objects
1968 * in IoTSet and IoTRelation
1972 private void createObjects() {
1979 // Extract hostname for this IoTMaster from MySQL DB
1980 strIoTMasterHostAdd = routerConfig.getIPFromMACAddress(STR_MASTER_MAC_ADD);
1981 // Loop as we can still find controller/device classes
1982 for(int i=0; i<strObjectNames.length; i++) {
1984 start = System.currentTimeMillis();
1986 // Assign a new list of PrintWriter objects
1987 routerConfig.renewPrintWriter();
1988 // Get controller names one by one
1989 String strObjControllerName = strObjectNames[i];
1990 // Use LoadBalancer to assign a host address
1991 //strIoTSlaveControllerHostAdd = lbIoT.selectHost();
1992 strIoTSlaveControllerHostAdd = routerConfig.getIPFromMACAddress(lbIoT.selectHost());
1993 if (strIoTSlaveControllerHostAdd == null)
1994 throw new Error("IoTMaster: Could not translate MAC to IP address! Please check the router's /tmp/dhcp.leases!");
1995 // == START INITIALIZING CONTROLLER/DEVICE IOTSLAVE ==
1996 // Add port connection and get port numbers
1997 // Naming for objects ProximitySensor becomes ProximitySensor0, ProximitySensor1, etc.
1998 commHan.addPortConnection(strIoTSlaveControllerHostAdd, strObjControllerName);
1999 // ROUTING POLICY: IoTMaster and main controller object
2000 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTMasterHostAdd,
2001 strIoTSlaveControllerHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjControllerName));
2002 // ROUTING POLICY: Send the same routing policy to both the hosts
2003 routerConfig.configureHostMainPolicies(strIoTMasterHostAdd, strIoTMasterHostAdd,
2004 strIoTSlaveControllerHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjControllerName));
2005 routerConfig.configureHostMainPolicies(strIoTSlaveControllerHostAdd, strIoTMasterHostAdd,
2006 strIoTSlaveControllerHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjControllerName));
2008 String strControllerCfg = STR_CONT_PATH + strObjControllerName + "/" + strObjControllerName + STR_CFG_FILE_EXT;
2009 STR_LANGUAGE_CONTROLLER = parseConfigFile(strControllerCfg, STR_LANGUAGE);
2010 if(STR_LANGUAGE_CONTROLLER == null)
2011 throw new Error("IoTMaster: Language specification missing in config file: " + strControllerCfg);
2012 // Construct ssh command line and create a controller thread for e.g. AcmeProximity
2013 String strSSHCommand = null;
2014 if(STR_LANGUAGE_CONTROLLER.equals(STR_JAVA))
2015 strSSHCommand = getCmdJavaIoTSlave(strObjControllerName);
2016 else if(STR_LANGUAGE_CONTROLLER.equals(STR_CPP))
2017 strSSHCommand = getCmdCppIoTSlave(strObjControllerName);
2019 throw new Error("IoTMaster: Language specification not recognized: " + STR_LANGUAGE_CONTROLLER);
2020 RuntimeOutput.print(strSSHCommand, BOOL_VERBOSE);
2021 createThread(strSSHCommand);
2022 // Wait for connection
2023 // Create a new socket for communication
2024 ServerSocket serverSocket = new ServerSocket(commHan.getComPort(strObjControllerName));
2025 Socket socket = serverSocket.accept();
2026 InputStream inStream = null;
2027 OutputStream outStream = null;
2028 if(STR_LANGUAGE_CONTROLLER.equals(STR_JAVA)) {
2029 inStream = new ObjectInputStream(socket.getInputStream());
2030 outStream = new ObjectOutputStream(socket.getOutputStream());
2031 } else { // At this point the language is certainly C++, otherwise would've complained above
2032 inStream = new BufferedInputStream(socket.getInputStream());
2033 outStream = new BufferedOutputStream(socket.getOutputStream());
2036 RuntimeOutput.print("IoTMaster: Communication established!", BOOL_VERBOSE);
2039 result = System.currentTimeMillis()-start;
2040 System.out.println("\n\n ==> From start until after SSH for main controller: " + result);
2042 start = System.currentTimeMillis();
2044 // Send files for every controller class
2045 // e.g. AcmeProximity.jar and AcmeProximity.zip
2046 String strControllerClassName = strObjControllerName + STR_CLS_FILE_EXT;
2047 String strControllerClassNamePath = STR_CONT_PATH + strObjControllerName + "/" +
2048 strControllerClassName;
2050 if(STR_LANGUAGE_CONTROLLER.equals(STR_JAVA)) {
2051 sendFileToJavaSlave(strObjControllerName, serverSocket, inStream, outStream);
2052 // Create main controller/device object
2053 commMasterToSlave(new MessageCreateMainObject(IoTCommCode.CREATE_MAIN_OBJECT, strObjControllerName),
2054 "Create main object!", inStream, outStream);
2056 String strControllerZipFile = strObjControllerName + STR_ZIP_FILE_EXT;
2057 String strControllerFilePath = STR_CONT_PATH + strObjControllerName + "/";
2058 sendFileToCppSlave(strControllerFilePath, strControllerZipFile);
2059 createMainObjectCpp(strObjControllerName, outStream, inStream);
2061 // Write basic MAC policies for controller
2062 //String strFileName = STR_MAC_POL_PATH + strObjControllerName + STR_MAC_POLICY_EXT;
2063 String strFileName = STR_MAC_POL_PATH + STR_JAVA + STR_MAC_POLICY_EXT;
2064 processJailConfig.configureProcessJailControllerPolicies(strObjControllerName, strFileName,
2065 strIoTMasterHostAdd, commHan.getComPort(strObjControllerName));
2067 result = System.currentTimeMillis()-start;
2068 System.out.println("\n\n ==> From IoTSlave start until main controller object is created: " + result);
2069 System.out.println(" ==> Including file transfer times!\n\n");
2071 start = System.currentTimeMillis();
2073 // == END INITIALIZING CONTROLLER/DEVICE IOTSLAVE ==
2074 // Instrumenting one file
2075 RuntimeOutput.print("IoTMaster: Opening class file: " + strControllerClassName, BOOL_VERBOSE);
2076 RuntimeOutput.print("IoTMaster: Class file path: " + strControllerClassNamePath, BOOL_VERBOSE);
2077 HashMap<String,Object> hmControllerFieldObjects = null;
2078 if(STR_LANGUAGE_CONTROLLER.equals(STR_JAVA)) {
2079 FileInputStream fis = new FileInputStream(strControllerClassNamePath);
2080 ClassReader cr = new ClassReader(fis);
2081 ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
2082 ClassRuntimeInstrumenterMaster crim = new ClassRuntimeInstrumenterMaster(cw, null, BOOL_VERBOSE);
2085 hmControllerFieldObjects = crim.getFieldObjects();
2087 String strControllerConfigFile = STR_CONT_PATH + strObjControllerName + "/" + strObjControllerName + STR_CFG_FILE_EXT;
2088 CRuntimeInstrumenterMaster crim = new CRuntimeInstrumenterMaster(strControllerConfigFile, null, BOOL_VERBOSE);
2089 hmControllerFieldObjects = crim.getFieldObjects();
2091 // Get the object and the class names
2092 // Build objects for IoTSet and IoTRelation fields in the controller/device classes
2093 //HashMap<String,Object> hmControllerFieldObjects = crim.getFieldObjects();
2094 for(Map.Entry<String,Object> map : hmControllerFieldObjects.entrySet()) {
2095 RuntimeOutput.print("IoTMaster: Object name: " + map.getValue().getClass().getName(), BOOL_VERBOSE);
2096 // Iterate over HashMap and choose between processing
2097 // SetInstrumenter vs. RelationInstrumenter
2098 String strFieldName = map.getKey();
2099 String strClassName = map.getValue().getClass().getName();
2100 if(strClassName.equals(STR_SET_INSTRUMENTER_CLS)) {
2101 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
2102 if(setInstrumenter.getObjTableName().equals(STR_IOT_DEV_ADD_CLS)) {
2103 String strErrMsg = "IoTMaster: Controller object" +
2104 " cannot have IoTSet<IoTDeviceAddress>!";
2105 throw new Error(strErrMsg);
2106 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ZB_ADD_CLS)) {
2107 String strErrMsg = "IoTMaster: Controller object" +
2108 " cannot have IoTSet<ZigbeeAddress>!";
2109 throw new Error(strErrMsg);
2110 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ADD_CLS)) {
2111 // Instrument the IoTAddress
2112 setRouterPolicyIoTSetAddress(strFieldName, map, strIoTSlaveControllerHostAdd, strObjControllerName);
2113 instrumentIoTSetAddress(strFieldName, strFieldName, inStream, outStream, STR_LANGUAGE_CONTROLLER);
2116 instrumentIoTSet(map, strFieldName, strObjControllerName, STR_LANGUAGE_CONTROLLER);
2118 } else if (strClassName.equals(STR_REL_INSTRUMENTER_CLS)) {
2119 instrumentIoTRelation(map, strFieldName, strObjControllerName, STR_LANGUAGE_CONTROLLER);
2122 // Combine controller MAC policies with the main policy file for the host
2123 String strTempFileName = "./" + strObjControllerName + STR_MAC_POLICY_EXT;
2124 processJailConfig.combineControllerMACPolicies(strIoTSlaveControllerHostAdd, strObjControllerName, strTempFileName);
2125 processJailConfig.close();
2128 result = System.currentTimeMillis()-start;
2129 System.out.println("\n\n ==> Time needed to instrument device driver objects: " + result + "\n\n");
2130 System.out.println(" ==> #Objects: " + commHan.getActiveControllerObjectList().size() + "\n\n");
2133 start = System.currentTimeMillis();
2135 // ROUTING POLICY: Deploy basic policies if this is the last controller
2136 if (i == strObjectNames.length-1) {
2137 // ROUTING POLICY: implement basic policies to reject all other irrelevant traffics
2138 for(String s: commHan.getHosts()) {
2139 setHostBasicPolicies(s);
2141 // We retain all the basic policies for router,
2142 // but we delete the initial allowance policies for internal all TCP and UDP communications
2143 setRouterBasicPolicies(STR_ROUTER_ADD);
2145 // Close access to policy files and deploy policies
2146 routerConfig.close();
2147 // Deploy the policy
2148 HashSet<String> setAddresses = new HashSet<String>(commHan.getHosts());
2149 setAddresses.add(strIoTMasterHostAdd);
2150 createPolicyThreads(STR_ROUTER_ADD, setAddresses);
2153 result = System.currentTimeMillis()-start;
2154 System.out.println("\n\n ==> Time needed to send policy files and deploy them : " + result + "\n\n");
2157 start = System.currentTimeMillis();
2159 // Separating object creations and Set/Relation initializations
2160 createDriverObjects();
2163 result = System.currentTimeMillis()-start;
2164 System.out.println("\n\n ==> Time needed to instantiate objects: " + result + "\n\n");
2166 start = System.currentTimeMillis();
2168 // Sets and relations initializations
2169 if(STR_LANGUAGE_CONTROLLER.equals(STR_JAVA))
2170 initializeSetsAndRelationsJava(inStream, outStream);
2172 initializeSetsAndRelationsCpp(inStream, outStream);;
2175 result = System.currentTimeMillis()-start;
2176 System.out.println("\n\n ==> Time needed to initialize sets and relations: " + result + "\n\n");
2178 if(STR_LANGUAGE_CONTROLLER.equals(STR_JAVA))
2179 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO EXECUTE INIT METHOD
2180 commMasterToSlave(new MessageSimple(IoTCommCode.INVOKE_INIT_METHOD), "Invoke init() method!", inStream, outStream);
2182 invokeInitMethodCpp(outStream, inStream);
2183 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO END PROCESS
2184 if(STR_LANGUAGE_CONTROLLER.equals(STR_JAVA)) {
2185 ObjectOutputStream oStream = (ObjectOutputStream) outStream;
2186 oStream.writeObject(new MessageSimple(IoTCommCode.END_SESSION));
2187 } else // C++ side will wait until the program finishes, it's not generating a separate thread for now
2188 //endSessionCpp(outStream);
2192 serverSocket.close();
2193 commHan.printLists();
2194 lbIoT.printHostInfo();
2195 // TODO: Uncomment this - just for experiments!
2196 createMACPolicyThreads(setAddresses);
2199 } catch (IOException |
2200 InterruptedException |
2201 ClassNotFoundException ex) {
2202 System.out.println("IoTMaster: Exception: "
2204 ex.printStackTrace();
2208 public static void main(String args[]) {
2210 // Detect the available controller/device classes
2211 // Input args[] should be used to list the controllers/devices
2212 // e.g. java IoTMaster AcmeProximity AcmeThermostat AcmeVentController
2213 IoTMaster iotMaster = new IoTMaster(args);
2215 iotMaster.parseIoTMasterConfigFile();
2216 // Initialize CommunicationHandler, LoadBalancer, and RouterConfig
2217 iotMaster.initLiveDataStructure();
2219 iotMaster.createObjects();