1 package iotruntime.master;
4 import iotruntime.slave.IoTAddress;
5 import iotruntime.slave.IoTDeviceAddress;
6 import iotruntime.messages.*;
9 import org.objectweb.asm.ClassReader;
10 import org.objectweb.asm.ClassWriter;
11 import org.objectweb.asm.ClassVisitor;
16 import java.io.BufferedReader;
17 import java.io.InputStream;
18 import java.io.InputStreamReader;
20 import java.io.FileInputStream;
21 import java.io.FileOutputStream;
22 import java.io.OutputStream;
23 import java.io.ObjectInputStream;
24 import java.io.ObjectOutputStream;
25 import java.io.IOException;
26 import java.lang.ClassNotFoundException;
27 import java.lang.Class;
28 import java.lang.reflect.*;
29 import java.net.Socket;
30 import java.net.ServerSocket;
31 import java.nio.ByteBuffer;
33 import static java.lang.Math.toIntExact;
35 /** Class IoTMaster is responsible to use ClassRuntimeInstrumenterMaster
36 * to instrument the controller/device bytecode and starts multiple
37 * IoTSlave running on different JVM's in a distributed fashion.
39 * @author Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>
43 public class IoTMaster {
46 * IoTMaster class properties
48 * CommunicationHandler maintains the data structure for hostnames and ports
49 * LoadBalancer assigns a job onto a host based on certain metrics
51 private CommunicationHandler commHan;
52 private LoadBalancer lbIoT;
53 private RouterConfig routerConfig;
54 private ObjectInitHandler objInitHand;
55 private ObjectAddressInitHandler objAddInitHand;
56 private String[] strObjectNames;
57 // Now this can be either ClassRuntimeInstrumenterMaster or CRuntimeInstrumenterMaster
58 private Map<String,Object> mapClassNameToCrim;
61 * These properties hold information of a certain object
64 private String strObjName;
65 private String strObjClassName;
66 private String strObjClassInterfaceName;
67 private String strObjStubClsIntfaceName;
68 private String strIoTMasterHostAdd;
69 private String strIoTSlaveControllerHostAdd;
70 private String strIoTSlaveObjectHostAdd;
71 private Class[] arrFieldClasses;
72 private Object[] arrFieldValues;
73 private Socket filesocket;
76 * For connection with C++ IoTSlave
78 private ServerSocket serverSocketCpp;
79 private Socket socketCpp;
80 private BufferedInputStream inputCpp;
81 private BufferedOutputStream outputCpp;
83 // Constants that are to be extracted from config file
84 private static String STR_MASTER_MAC_ADD;
85 private static String STR_IOT_CODE_PATH;
86 private static String STR_CONT_PATH;
87 private static String STR_RUNTIME_DIR;
88 private static String STR_SLAVE_DIR;
89 private static String STR_CLS_PATH;
90 private static String STR_RMI_PATH;
91 private static String STR_RMI_HOSTNAME;
92 private static String STR_LOG_FILE_PATH;
93 private static String STR_USERNAME;
94 private static String STR_ROUTER_ADD;
95 private static String STR_MONITORING_HOST;
96 private static String STR_ZB_GATEWAY_ADDRESS;
97 private static String STR_ZB_GATEWAY_PORT;
98 private static String STR_ZB_IOTMASTER_PORT;
99 private static String STR_NUM_CALLBACK_PORTS;
100 private static String STR_JVM_INIT_HEAP_SIZE;
101 private static String STR_JVM_MAX_HEAP_SIZE;
102 private static String STR_LANGUAGE;
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_SO_FILE_EXT = ".so";
117 private static final String STR_ZIP_FILE_EXT = ".zip";
118 private static final String STR_TCP_PROTOCOL = "tcp";
119 private static final String STR_UDP_PROTOCOL = "udp";
120 private static final String STR_TCPGW_PROTOCOL = "tcpgw";
121 private static final String STR_NO_PROTOCOL = "nopro";
122 private static final String STR_SELF_MAC_ADD = "00:00:00:00:00:00";
123 private static final String STR_INTERFACE_CLS_CFG = "INTERFACE_CLASS";
124 private static final String STR_INT_STUB_CLS_CFG = "INTERFACE_STUB_CLASS";
125 private static final String STR_FILE_TRF_CFG = "ADDITIONAL_ZIP_FILE";
126 private static final String STR_YES = "Yes";
127 private static final String STR_NO = "No";
128 private static final String STR_JAVA = "Java";
129 private static final String STR_CPP = "C++";
130 private static final String STR_SSH = "ssh";
131 private static final String STR_SCP = "scp";
132 private static final String STR_IOTSLAVE_CPP = "./IoTSlave.o";
134 private static int INT_SIZE = 4; // send length in the size of integer (4 bytes)
137 * Runtime class name constants - not to be configured by users
139 private static final String STR_REL_INSTRUMENTER_CLS = "iotruntime.master.RelationInstrumenter";
140 private static final String STR_SET_INSTRUMENTER_CLS = "iotruntime.master.SetInstrumenter";
141 private static final String STR_IOT_SLAVE_CLS = "iotruntime.slave.IoTSlave";
142 private static final String STR_IOT_DEV_ADD_CLS = "IoTDeviceAddress";
143 private static final String STR_IOT_ZB_ADD_CLS = "IoTZigbeeAddress";
144 private static final String STR_IOT_ADD_CLS = "IoTAddress";
150 public IoTMaster(String[] argObjNms) {
156 objAddInitHand = null;
157 strObjectNames = argObjNms;
159 strObjClassName = null;
160 strObjClassInterfaceName = null;
161 strObjStubClsIntfaceName = null;
162 strIoTMasterHostAdd = null;
163 strIoTSlaveControllerHostAdd = null;
164 strIoTSlaveObjectHostAdd = null;
165 arrFieldClasses = null;
166 arrFieldValues = null;
168 mapClassNameToCrim = null;
169 // Connection with C++ IoTSlave
170 serverSocketCpp = null;
175 STR_MASTER_MAC_ADD = null;
176 STR_IOT_CODE_PATH = null;
177 STR_CONT_PATH = null;
178 STR_RUNTIME_DIR = null;
179 STR_SLAVE_DIR = null;
182 STR_RMI_HOSTNAME = null;
183 STR_LOG_FILE_PATH = null;
185 STR_ROUTER_ADD = null;
186 STR_MONITORING_HOST = null;
187 STR_ZB_GATEWAY_ADDRESS = null;
188 STR_ZB_GATEWAY_PORT = null;
189 STR_ZB_IOTMASTER_PORT = null;
190 STR_NUM_CALLBACK_PORTS = null;
191 STR_JVM_INIT_HEAP_SIZE = null;
192 STR_JVM_MAX_HEAP_SIZE = null;
194 BOOL_VERBOSE = false;
198 * A method to initialize CommunicationHandler, LoadBalancer, RouterConfig and ObjectInitHandler
202 private void initLiveDataStructure() {
204 commHan = new CommunicationHandler(BOOL_VERBOSE);
205 lbIoT = new LoadBalancer(BOOL_VERBOSE);
206 lbIoT.setupLoadBalancer();
207 routerConfig = new RouterConfig();
208 routerConfig.getAddressList(STR_ROUTER_ADD);
209 objInitHand = new ObjectInitHandler(BOOL_VERBOSE);
210 objAddInitHand = new ObjectAddressInitHandler(BOOL_VERBOSE);
211 mapClassNameToCrim = new HashMap<String,Object>();
215 * A method to initialize constants from config file
219 private void parseIoTMasterConfigFile() {
220 // Parse configuration file
221 Properties prop = new Properties();
222 String strCfgFileName = STR_IOT_MASTER_NAME + STR_CFG_FILE_EXT;
223 File file = new File(strCfgFileName);
224 FileInputStream fis = null;
226 fis = new FileInputStream(file);
229 } catch (IOException ex) {
230 System.out.println("IoTMaster: Error reading config file: " + strCfgFileName);
231 ex.printStackTrace();
233 // Initialize constants from config file
234 STR_MASTER_MAC_ADD = prop.getProperty("MAC_ADDRESS");
235 STR_IOT_CODE_PATH = prop.getProperty("IOT_CODE_PATH");
236 STR_CONT_PATH = prop.getProperty("CONTROLLERS_CODE_PATH");
237 STR_RUNTIME_DIR = prop.getProperty("RUNTIME_DIR");
238 STR_SLAVE_DIR = prop.getProperty("SLAVE_DIR");
239 STR_CLS_PATH = prop.getProperty("CLASS_PATH");
240 STR_RMI_PATH = prop.getProperty("RMI_PATH");
241 STR_RMI_HOSTNAME = prop.getProperty("RMI_HOSTNAME");
242 STR_LOG_FILE_PATH = prop.getProperty("LOG_FILE_PATH");
243 STR_USERNAME = prop.getProperty("USERNAME");
244 STR_ROUTER_ADD = prop.getProperty("ROUTER_ADD");
245 STR_MONITORING_HOST = prop.getProperty("MONITORING_HOST");
246 STR_ZB_GATEWAY_ADDRESS = prop.getProperty("ZIGBEE_GATEWAY_ADDRESS");
247 STR_ZB_GATEWAY_PORT = prop.getProperty("ZIGBEE_GATEWAY_PORT");
248 STR_ZB_IOTMASTER_PORT = prop.getProperty("ZIGBEE_IOTMASTER_PORT");
249 STR_NUM_CALLBACK_PORTS = prop.getProperty("NUMBER_CALLBACK_PORTS");
250 STR_JVM_INIT_HEAP_SIZE = prop.getProperty("JVM_INIT_HEAP_SIZE");
251 STR_JVM_MAX_HEAP_SIZE = prop.getProperty("JVM_MAX_HEAP_SIZE");
252 STR_LANGUAGE = prop.getProperty("LANGUAGE");
253 STR_SKEL_CLASS_SUFFIX = prop.getProperty("SKEL_CLASS_SUFFIX");
254 STR_STUB_CLASS_SUFFIX = prop.getProperty("STUB_CLASS_SUFFIX");
255 if(prop.getProperty("VERBOSE").equals(STR_YES)) {
259 RuntimeOutput.print("IoTMaster: Extracting information from config file: " + strCfgFileName, BOOL_VERBOSE);
260 RuntimeOutput.print("STR_MASTER_MAC_ADD=" + STR_MASTER_MAC_ADD, BOOL_VERBOSE);
261 RuntimeOutput.print("STR_IOT_CODE_PATH=" + STR_IOT_CODE_PATH, BOOL_VERBOSE);
262 RuntimeOutput.print("STR_CONT_PATH=" + STR_CONT_PATH, BOOL_VERBOSE);
263 RuntimeOutput.print("STR_RUNTIME_DIR=" + STR_RUNTIME_DIR, BOOL_VERBOSE);
264 RuntimeOutput.print("STR_SLAVE_DIR=" + STR_SLAVE_DIR, BOOL_VERBOSE);
265 RuntimeOutput.print("STR_CLS_PATH=" + STR_CLS_PATH, BOOL_VERBOSE);
266 RuntimeOutput.print("STR_RMI_PATH=" + STR_RMI_PATH, BOOL_VERBOSE);
267 RuntimeOutput.print("STR_RMI_HOSTNAME=" + STR_RMI_HOSTNAME, BOOL_VERBOSE);
268 RuntimeOutput.print("STR_LOG_FILE_PATH=" + STR_LOG_FILE_PATH, BOOL_VERBOSE);
269 RuntimeOutput.print("STR_USERNAME=" + STR_USERNAME, BOOL_VERBOSE);
270 RuntimeOutput.print("STR_ROUTER_ADD=" + STR_ROUTER_ADD, BOOL_VERBOSE);
271 RuntimeOutput.print("STR_MONITORING_HOST=" + STR_MONITORING_HOST, BOOL_VERBOSE);
272 RuntimeOutput.print("STR_ZB_GATEWAY_ADDRESS=" + STR_ZB_GATEWAY_ADDRESS, BOOL_VERBOSE);
273 RuntimeOutput.print("STR_ZB_GATEWAY_PORT=" + STR_ZB_GATEWAY_PORT, BOOL_VERBOSE);
274 RuntimeOutput.print("STR_ZB_IOTMASTER_PORT=" + STR_ZB_IOTMASTER_PORT, BOOL_VERBOSE);
275 RuntimeOutput.print("STR_NUM_CALLBACK_PORTS=" + STR_NUM_CALLBACK_PORTS, BOOL_VERBOSE);
276 RuntimeOutput.print("STR_JVM_INIT_HEAP_SIZE=" + STR_JVM_INIT_HEAP_SIZE, BOOL_VERBOSE);
277 RuntimeOutput.print("STR_JVM_MAX_HEAP_SIZE=" + STR_JVM_MAX_HEAP_SIZE, BOOL_VERBOSE);
278 RuntimeOutput.print("STR_LANGUAGE=" + STR_LANGUAGE, BOOL_VERBOSE);
279 RuntimeOutput.print("STR_SKEL_CLASS_SUFFIX=" + STR_SKEL_CLASS_SUFFIX, BOOL_VERBOSE);
280 RuntimeOutput.print("STR_STUB_CLASS_SUFFIX=" + STR_STUB_CLASS_SUFFIX, BOOL_VERBOSE);
281 RuntimeOutput.print("BOOL_VERBOSE=" + BOOL_VERBOSE, BOOL_VERBOSE);
282 RuntimeOutput.print("IoTMaster: Information extracted successfully!", BOOL_VERBOSE);
286 * A method to parse information from a config file
288 * @param strCfgFileName Config file name
289 * @param strCfgField Config file field name
292 private String parseConfigFile(String strCfgFileName, String strCfgField) {
293 // Parse configuration file
294 Properties prop = new Properties();
295 File file = new File(strCfgFileName);
296 FileInputStream fis = null;
298 fis = new FileInputStream(file);
301 } catch (IOException ex) {
302 System.out.println("IoTMaster: Error reading config file: " + strCfgFileName);
303 ex.printStackTrace();
305 System.out.println("IoTMaster: Reading " + strCfgField +
306 " from config file: " + strCfgFileName + " with value: " +
307 prop.getProperty(strCfgField, null));
308 // NULL is returned if the property isn't found
309 return prop.getProperty(strCfgField, null);
313 * A method to send files from IoTMaster
315 * @param filesocket File socket object
316 * @param sFileName File name
317 * @param lFLength File length
320 private void sendFile(Socket filesocket, String sFileName, long lFLength) throws IOException {
322 File file = new File(sFileName);
323 byte[] bytFile = new byte[toIntExact(lFLength)];
324 InputStream inFileStream = new FileInputStream(file);
326 OutputStream outFileStream = filesocket.getOutputStream();
328 while ((iCount = inFileStream.read(bytFile)) > 0) {
329 outFileStream.write(bytFile, 0, iCount);
332 RuntimeOutput.print("IoTMaster: File sent!", BOOL_VERBOSE);
336 * A method to create a thread
338 * @param sSSHCmd SSH command
341 private void createThread(String sSSHCmd) throws IOException {
343 // Start a new thread to start a new JVM
345 Runtime runtime = Runtime.getRuntime();
346 Process process = runtime.exec(sSSHCmd);
348 RuntimeOutput.print("Executing: " + sSSHCmd, BOOL_VERBOSE);
352 * A method to send command from master and receive reply from slave
354 * @params msgSend Message object
355 * @params strPurpose String that prints purpose message
356 * @params inStream Input stream
357 * @params outStream Output stream
360 private void commMasterToSlave(Message msgSend, String strPurpose,
361 InputStream _inStream, OutputStream _outStream)
362 throws IOException, ClassNotFoundException {
364 // Send message/command from master
365 ObjectOutputStream outStream = (ObjectOutputStream) _outStream;
366 outStream.writeObject(msgSend);
367 RuntimeOutput.print("IoTMaster: Send message: " + strPurpose, BOOL_VERBOSE);
369 // Get reply from slave as acknowledgment
370 ObjectInputStream inStream = (ObjectInputStream) _inStream;
371 Message msgReply = (Message) inStream.readObject();
372 RuntimeOutput.print("IoTMaster: Reply message: " + msgReply.getMessage(), BOOL_VERBOSE);
376 * A private method to instrument IoTSet device
378 * @params strFieldIdentifier String field name + object ID
379 * @params strFieldName String field name
380 * @params strIoTSlaveObjectHostAdd String slave host address
381 * @params inStream ObjectInputStream communication
382 * @params inStream ObjectOutputStream communication
385 private void instrumentIoTSetDevice(String strFieldIdentifier, String strObjName, String strFieldName, String strIoTSlaveObjectHostAdd,
386 InputStream inStream, OutputStream outStream)
387 throws IOException, ClassNotFoundException, InterruptedException {
389 // Get information from the set
390 List<Object[]> listObject = objAddInitHand.getFields(strFieldIdentifier);
391 // Create a new IoTSet
392 if(STR_LANGUAGE.equals(STR_JAVA)) {
393 Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, strFieldName);
394 commMasterToSlave(msgCrtIoTSet, "Create new IoTSet for IoTDeviceAddress!", inStream, outStream);
396 createNewIoTSetCpp(strFieldName, outStream, inStream);
397 int iRows = listObject.size();
398 RuntimeOutput.print("IoTMaster: Number of rows for IoTDeviceAddress: " + iRows, BOOL_VERBOSE);
399 // Transfer the address
400 for(int iRow=0; iRow<iRows; iRow++) {
401 arrFieldValues = listObject.get(iRow);
402 // Get device address - if 00:00:00:00:00:00 that means it needs the driver object address (self)
403 String strDeviceAddress = null;
404 String strDeviceAddressKey = null;
405 if (arrFieldValues[0].equals(STR_SELF_MAC_ADD)) {
406 strDeviceAddress = strIoTSlaveObjectHostAdd;
407 strDeviceAddressKey = strObjName + "-" + strIoTSlaveObjectHostAdd;
409 strDeviceAddress = routerConfig.getIPFromMACAddress((String) arrFieldValues[0]);
410 strDeviceAddressKey = strObjName + "-" + strDeviceAddress;
412 int iDestDeviceDriverPort = (int) arrFieldValues[1];
413 String strProtocol = (String) arrFieldValues[2];
414 // Check for wildcard feature
415 boolean bSrcPortWildCard = false;
416 boolean bDstPortWildCard = false;
417 if (arrFieldValues.length > 3) {
418 bSrcPortWildCard = (boolean) arrFieldValues[3];
419 bDstPortWildCard = (boolean) arrFieldValues[4];
421 // Add the port connection into communication handler - if it's not assigned yet
422 if (commHan.getComPort(strDeviceAddressKey) == null) {
423 commHan.addPortConnection(strIoTSlaveObjectHostAdd, strDeviceAddressKey);
427 System.out.println("\n\n DEBUG: InstrumentSetDevice: Object Name: " + strObjName);
428 System.out.println("DEBUG: InstrumentSetDevice: Port number: " + commHan.getComPort(strDeviceAddressKey));
429 System.out.println("DEBUG: InstrumentSetDevice: Device address: " + strDeviceAddressKey + "\n\n");
431 // Send address one by one
432 if(STR_LANGUAGE.equals(STR_JAVA)) {
433 Message msgGetIoTSetObj = null;
434 if (bDstPortWildCard) {
435 String strUniqueDev = strDeviceAddressKey + ":" + iRow;
436 msgGetIoTSetObj = new MessageGetDeviceObject(IoTCommCode.GET_DEVICE_IOTSET_OBJECT,
437 strDeviceAddress, commHan.getAdditionalPort(strUniqueDev), iDestDeviceDriverPort, bSrcPortWildCard, bDstPortWildCard);
439 msgGetIoTSetObj = new MessageGetDeviceObject(IoTCommCode.GET_DEVICE_IOTSET_OBJECT,
440 strDeviceAddress, commHan.getComPort(strDeviceAddressKey), iDestDeviceDriverPort, bSrcPortWildCard, bDstPortWildCard);
441 commMasterToSlave(msgGetIoTSetObj, "Get IoTSet objects!", inStream, outStream);
443 getDeviceIoTSetObjectCpp(outStream, inStream, strDeviceAddress, commHan.getComPort(strDeviceAddressKey), iDestDeviceDriverPort,
444 bSrcPortWildCard, bDstPortWildCard);
446 // Reinitialize IoTSet on device object
447 if(STR_LANGUAGE.equals(STR_JAVA))
448 commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTSET_FIELD), "Reinitialize IoTSet fields!", inStream, outStream);
450 reinitializeIoTSetFieldCpp(outStream, inStream);
455 * A private method to instrument IoTSet Zigbee device
457 * @params Map.Entry<String,Object> Entry of map IoTSet instrumentation
458 * @params strFieldName String field name
459 * @params strIoTSlaveObjectHostAdd String slave host address
460 * @params inStream ObjectInputStream communication
461 * @params inStream ObjectOutputStream communication
464 private void instrumentIoTSetZBDevice(Map.Entry<String,Object> map, String strObjName, String strFieldName, String strIoTSlaveObjectHostAdd,
465 InputStream inStream, OutputStream outStream)
466 throws IOException, ClassNotFoundException, InterruptedException {
468 // Get information from the set
469 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
470 // Create a new IoTSet
471 if(STR_LANGUAGE.equals(STR_JAVA)) {
472 Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, strFieldName);
473 commMasterToSlave(msgCrtIoTSet, "Create new IoTSet for IoTZigbeeAddress!", inStream, outStream);
474 } else // TODO: will need to implement IoTSet Zigbee for C++ later
476 // Prepare ZigbeeConfig
477 String strZigbeeGWAddress = routerConfig.getIPFromMACAddress(STR_ZB_GATEWAY_ADDRESS);
478 String strZigbeeGWAddressKey = strObjName + "-" + strZigbeeGWAddress;
479 int iZigbeeGWPort = Integer.parseInt(STR_ZB_GATEWAY_PORT);
480 int iZigbeeIoTMasterPort = Integer.parseInt(STR_ZB_IOTMASTER_PORT);
481 commHan.addDevicePort(iZigbeeIoTMasterPort);
482 ZigbeeConfig zbConfig = new ZigbeeConfig(strZigbeeGWAddress, iZigbeeGWPort, iZigbeeIoTMasterPort,
484 // Add the port connection into communication handler - if it's not assigned yet
485 if (commHan.getComPort(strZigbeeGWAddressKey) == null) {
486 commHan.addPortConnection(strIoTSlaveObjectHostAdd, strZigbeeGWAddressKey);
488 int iRows = setInstrumenter.numberOfRows();
489 RuntimeOutput.print("IoTMaster: Number of rows for IoTZigbeeAddress: " + iRows, BOOL_VERBOSE);
492 System.out.println("\n\n DEBUG: InstrumentZigbeeDevice: Object Name: " + strObjName);
493 System.out.println("DEBUG: InstrumentZigbeeDevice: Port number: " + commHan.getComPort(strZigbeeGWAddressKey));
494 System.out.println("DEBUG: InstrumentZigbeeDevice: Device address: " + strZigbeeGWAddress + "\n\n");
496 // Transfer the address
497 for(int iRow=0; iRow<iRows; iRow++) {
498 arrFieldValues = setInstrumenter.fieldValues(iRow);
499 // Get device address
500 String strZBDevAddress = (String) arrFieldValues[0];
501 // Send policy to Zigbee gateway - TODO: Need to clear policy first?
502 zbConfig.setPolicy(strIoTSlaveObjectHostAdd, commHan.getComPort(strZigbeeGWAddressKey), strZBDevAddress);
503 // Send address one by one
504 if(STR_LANGUAGE.equals(STR_JAVA)) {
505 Message msgGetIoTSetZBObj = new MessageGetSimpleDeviceObject(IoTCommCode.GET_ZB_DEV_IOTSET_OBJECT, strZBDevAddress);
506 commMasterToSlave(msgGetIoTSetZBObj, "Get IoTSet objects!", inStream, outStream);
507 } else // TODO: Implement IoTSet Zigbee for C++
510 zbConfig.closeConnection();
511 // Reinitialize IoTSet on device object
512 commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTSET_FIELD), "Reinitialize IoTSet fields!", inStream, outStream);
517 * A private method to instrument IoTSet of addresses
519 * @params strFieldIdentifier String field name + object ID
520 * @params strFieldName String field name
521 * @params inStream ObjectInputStream communication
522 * @params inStream ObjectOutputStream communication
525 private void instrumentIoTSetAddress(String strFieldIdentifier, String strFieldName,
526 InputStream inStream, OutputStream outStream)
527 throws IOException, ClassNotFoundException, InterruptedException {
529 // Get information from the set
530 List<Object[]> listObject = objAddInitHand.getFields(strFieldIdentifier);
531 // Create a new IoTSet
532 if(STR_LANGUAGE.equals(STR_JAVA)) {
533 Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, strFieldName);
534 commMasterToSlave(msgCrtIoTSet, "Create new IoTSet for IoTAddress!", inStream, outStream);
537 int iRows = listObject.size();
538 RuntimeOutput.print("IoTMaster: Number of rows for IoTAddress: " + iRows, BOOL_VERBOSE);
539 // Transfer the address
540 for(int iRow=0; iRow<iRows; iRow++) {
541 arrFieldValues = listObject.get(iRow);
542 // Get device address
543 String strAddress = (String) arrFieldValues[0];
544 // Send address one by one
545 if(STR_LANGUAGE.equals(STR_JAVA)) {
546 Message msgGetIoTSetAddObj = new MessageGetSimpleDeviceObject(IoTCommCode.GET_ADD_IOTSET_OBJECT, strAddress);
547 commMasterToSlave(msgGetIoTSetAddObj, "Get IoTSet objects!", inStream, outStream);
548 } else // TODO: Implement IoTSet Address for C++
551 // Reinitialize IoTSet on device object
552 commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTSET_FIELD),
553 "Reinitialize IoTSet fields!", inStream, outStream);
558 * A private method to instrument an object on a specific machine and setting up policies
560 * @params strFieldObjectID String field object ID
563 private void instrumentObject(String strFieldObjectID) throws IOException {
565 // Extract the interface name for RMI
566 // e.g. ProximitySensorInterface, TempSensorInterface, etc.
568 String strObjCfgFile = STR_IOT_CODE_PATH + strObjClassName + "/" + strObjClassName + STR_CFG_FILE_EXT;
569 strObjClassInterfaceName = parseConfigFile(strObjCfgFile, STR_INTERFACE_CLS_CFG);
570 strObjStubClsIntfaceName = parseConfigFile(strObjCfgFile, STR_INT_STUB_CLS_CFG);
571 // Create an object name, e.g. ProximitySensorImplPS1
572 strObjName = strObjClassName + strFieldObjectID;
573 // Check first if host exists
574 if(commHan.objectExists(strObjName)) {
575 // If this object exists already ...
576 // Re-read IoTSlave object hostname for further reference
577 strIoTSlaveObjectHostAdd = commHan.getHostAddress(strObjName);
578 RuntimeOutput.print("IoTMaster: Object with name: " + strObjName + " has existed!", BOOL_VERBOSE);
580 // If this is a new object ... then create one
581 // Get host address for IoTSlave from LoadBalancer
582 //strIoTSlaveObjectHostAdd = lbIoT.selectHost();
583 strIoTSlaveObjectHostAdd = routerConfig.getIPFromMACAddress(lbIoT.selectHost());
584 if (strIoTSlaveControllerHostAdd == null)
585 throw new Error("IoTMaster: Could not translate MAC to IP address! Please check the router's /tmp/dhcp.leases!");
586 RuntimeOutput.print("IoTMaster: Object name: " + strObjName, BOOL_VERBOSE);
587 // Add port connection and get port numbers
588 // Naming for objects ProximitySensor becomes ProximitySensor0, ProximitySensor1, etc.
589 commHan.addPortConnection(strIoTSlaveObjectHostAdd, strObjName);
590 commHan.addActiveControllerObject(strFieldObjectID, strObjName, strObjClassName, strObjClassInterfaceName,
591 strObjStubClsIntfaceName, strIoTSlaveObjectHostAdd, arrFieldValues, arrFieldClasses);
592 // ROUTING POLICY: IoTMaster and device/controller object
593 // Master-slave communication
594 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTMasterHostAdd,
595 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjName));
596 // ROUTING POLICY: Send the same routing policy to both the hosts
597 routerConfig.configureHostMainPolicies(strIoTMasterHostAdd, strIoTMasterHostAdd,
598 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjName));
599 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTMasterHostAdd,
600 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjName));
601 // Need to accommodate callback functions here - open ports for TCP
602 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveControllerHostAdd,
603 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
604 routerConfig.configureHostMainPolicies(strIoTSlaveControllerHostAdd, strIoTSlaveControllerHostAdd,
605 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
606 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveControllerHostAdd,
607 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
608 // Instrument the IoTSet declarations inside the class file
609 instrumentObjectIoTSet(strFieldObjectID);
611 // Send routing policy to router for controller object
612 // ROUTING POLICY: RMI communication - RMI registry and stub ports
613 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
614 STR_TCP_PROTOCOL, commHan.getRMIRegPort(strObjName));
615 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
616 STR_TCP_PROTOCOL, commHan.getRMIStubPort(strObjName));
617 // Send the same set of routing policies to compute nodes
618 routerConfig.configureHostMainPolicies(strIoTSlaveControllerHostAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
619 STR_TCP_PROTOCOL, commHan.getRMIRegPort(strObjName));
620 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
621 STR_TCP_PROTOCOL, commHan.getRMIRegPort(strObjName));
622 routerConfig.configureHostMainPolicies(strIoTSlaveControllerHostAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
623 STR_TCP_PROTOCOL, commHan.getRMIStubPort(strObjName));
624 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
625 STR_TCP_PROTOCOL, commHan.getRMIStubPort(strObjName));
626 // Send the same set of routing policies for callback ports
627 setCallbackPortsPolicy(strObjName, STR_ROUTER_ADD, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
631 * A private method to set router policies for callback ports
633 * @params strRouterAdd String router address
634 * @params strIoTSlaveControllerHostAdd String slave controller host address
635 * @params strIoTSlaveObjectHostAdd String slave object host address
636 * @params strProtocol String protocol
637 * @return iPort Integer port number
639 private void setCallbackPortsPolicy(String strObjName, String strRouterAdd, String strIoTSlaveControllerHostAdd,
640 String strIoTSlaveObjectHostAdd, String strProtocol) {
642 int iNumCallbackPorts = Integer.parseInt(STR_NUM_CALLBACK_PORTS);
643 Integer[] rmiCallbackPorts = commHan.getCallbackPorts(strObjName, iNumCallbackPorts);
645 // Iterate over port numbers and set up policies
646 for (int i=0; i<iNumCallbackPorts; i++) {
647 routerConfig.configureRouterMainPolicies(strRouterAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
648 strProtocol, rmiCallbackPorts[i]);
649 routerConfig.configureHostMainPolicies(strIoTSlaveControllerHostAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
650 strProtocol, rmiCallbackPorts[i]);
651 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
652 strProtocol, rmiCallbackPorts[i]);
657 * A private method to set router policies for IoTDeviceAddress objects
659 * @params strFieldIdentifier String field name + object ID
660 * @params Map.Entry<String,Object> Entry of map IoTSet instrumentation
661 * @params strIoTSlaveObjectHostAdd String slave host address
664 private void setRouterPolicyIoTSetDevice(String strFieldIdentifier, Map.Entry<String,Object> map,
665 String strIoTSlaveObjectHostAdd) {
667 // Get information from the set
668 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
669 int iRows = setInstrumenter.numberOfRows();
670 RuntimeOutput.print("IoTMaster: Number of rows for IoTDeviceAddress: " + iRows, BOOL_VERBOSE);
671 // Transfer the address
672 for(int iRow=0; iRow<iRows; iRow++) {
673 arrFieldValues = setInstrumenter.fieldValues(iRow);
674 objAddInitHand.addField(strFieldIdentifier, arrFieldValues); // Save this for object instantiation
675 // Get device address - if 00:00:00:00:00:00 that means it needs the driver object address (self)
676 String strDeviceAddress = null;
677 String strDeviceAddressKey = null;
678 if (arrFieldValues[0].equals(STR_SELF_MAC_ADD)) {
679 strDeviceAddress = strIoTSlaveObjectHostAdd;
680 strDeviceAddressKey = strObjName + "-" + strIoTSlaveObjectHostAdd;
681 } else { // Concatenate object name and IP address to give unique key - for a case where there is one device for multiple drivers
682 strDeviceAddress = routerConfig.getIPFromMACAddress((String) arrFieldValues[0]);
683 strDeviceAddressKey = strObjName + "-" + strDeviceAddress;
685 int iDestDeviceDriverPort = (int) arrFieldValues[1];
686 String strProtocol = (String) arrFieldValues[2];
687 // Add the port connection into communication handler - if it's not assigned yet
688 if (commHan.getComPort(strDeviceAddressKey) == null)
689 commHan.addPortConnection(strIoTSlaveObjectHostAdd, strDeviceAddressKey);
690 boolean bDstPortWildCard = false;
691 // Recognize this and allocate different ports for it
692 if (arrFieldValues.length > 3) {
693 bDstPortWildCard = (boolean) arrFieldValues[4];
694 if (bDstPortWildCard) { // This needs a unique source port
695 String strUniqueDev = strDeviceAddressKey + ":" + iRow;
696 commHan.addAdditionalPort(strUniqueDev);
701 System.out.println("\n\n DEBUG: InstrumentPolicySetDevice: Object Name: " + strObjName);
702 System.out.println("DEBUG: InstrumentPolicySetDevice: Port number: " + commHan.getComPort(strDeviceAddressKey));
703 System.out.println("DEBUG: InstrumentPolicySetDevice: Device address: " + strDeviceAddressKey + "\n\n");
705 // Send routing policy to router for device drivers and devices
706 // ROUTING POLICY: RMI communication - RMI registry and stub ports
707 if((iDestDeviceDriverPort == -1) && (!strProtocol.equals(STR_NO_PROTOCOL))) {
708 // Port number -1 means that we don't set the policy strictly to port number level
709 // "nopro" = no protocol specified for just TCP or just UDP (can be both used as well)
710 // ROUTING POLICY: Device driver and device
711 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveObjectHostAdd, strDeviceAddress, strProtocol);
712 // ROUTING POLICY: Send to the compute node where the device driver is
713 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress, strProtocol);
714 } else if((iDestDeviceDriverPort == -1) && (strProtocol.equals(STR_NO_PROTOCOL))) {
715 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveObjectHostAdd, strDeviceAddress);
716 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress);
717 } else if(strProtocol.equals(STR_TCPGW_PROTOCOL)) {
718 // This is a TCP protocol that connects, e.g. a phone to our runtime system
719 // that provides a gateway access (accessed through destination port number)
720 commHan.addDevicePort(iDestDeviceDriverPort);
721 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveObjectHostAdd, strDeviceAddress, STR_TCP_PROTOCOL, iDestDeviceDriverPort);
722 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress, STR_TCP_PROTOCOL, iDestDeviceDriverPort);
723 routerConfig.configureRouterHTTPPolicies(STR_ROUTER_ADD, strIoTSlaveObjectHostAdd, strDeviceAddress);
724 routerConfig.configureHostHTTPPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress);
726 // Other port numbers...
727 commHan.addDevicePort(iDestDeviceDriverPort);
728 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveObjectHostAdd, strDeviceAddress, strProtocol,
729 commHan.getComPort(strDeviceAddressKey), iDestDeviceDriverPort);
730 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress, strProtocol,
731 commHan.getComPort(strDeviceAddressKey), iDestDeviceDriverPort);
737 * A private method to set router policies for IoTAddress objects
739 * @params strFieldIdentifier String field name + object ID
740 * @params Map.Entry<String,Object> Entry of map IoTSet instrumentation
741 * @params strHostAddress String host address
744 private void setRouterPolicyIoTSetAddress(String strFieldIdentifier, Map.Entry<String,Object> map,
745 String strHostAddress) {
747 // Get information from the set
748 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
749 int iRows = setInstrumenter.numberOfRows();
750 RuntimeOutput.print("IoTMaster: Number of rows for IoTAddress: " + iRows, BOOL_VERBOSE);
751 // Transfer the address
752 for(int iRow=0; iRow<iRows; iRow++) {
753 arrFieldValues = setInstrumenter.fieldValues(iRow);
754 objAddInitHand.addField(strFieldIdentifier, arrFieldValues); // Save this for object instantiation
755 // Get device address
756 String strAddress = (String) arrFieldValues[0];
757 // Setting up router policies for HTTP/HTTPs
758 routerConfig.configureRouterHTTPPolicies(STR_ROUTER_ADD, strHostAddress, strAddress);
759 routerConfig.configureHostHTTPPolicies(strHostAddress, strHostAddress, strAddress);
764 * A private method to instrument an object's IoTSet and IoTRelation field to up policies
766 * Mostly the IoTSet fields would contain IoTDeviceAddress objects
768 * @params strFieldObjectID String field object ID
771 private void instrumentObjectIoTSet(String strFieldObjectID) throws IOException {
773 // If this is a new object ... then create one
774 // Instrument the class source code and look for IoTSet for device addresses
775 // e.g. @config private IoTSet<IoTDeviceAddress> lb_addresses;
776 HashMap<String,Object> hmObjectFieldObjects = null;
777 if(STR_LANGUAGE.equals(STR_JAVA)) {
778 String strObjectClassNamePath = STR_IOT_CODE_PATH + strObjClassName + "/" + strObjClassName + STR_CLS_FILE_EXT;
779 FileInputStream fis = new FileInputStream(strObjectClassNamePath);
780 ClassReader cr = new ClassReader(fis);
781 ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
782 // We need Object ID to instrument IoTDeviceAddress
783 ClassRuntimeInstrumenterMaster crim = new ClassRuntimeInstrumenterMaster(cw, strFieldObjectID, BOOL_VERBOSE);
786 mapClassNameToCrim.put(strObjClassName + strFieldObjectID, crim);
787 hmObjectFieldObjects = crim.getFieldObjects();
789 String strObjectClassNamePath = STR_IOT_CODE_PATH + strObjClassName + "/" + strObjClassName + STR_CFG_FILE_EXT;
790 CRuntimeInstrumenterMaster crim = new CRuntimeInstrumenterMaster(strObjectClassNamePath, strFieldObjectID, BOOL_VERBOSE);
791 mapClassNameToCrim.put(strObjClassName + strFieldObjectID, crim);
792 hmObjectFieldObjects = crim.getFieldObjects();
794 // Get the object and the class names
795 // Build objects for IoTSet and IoTRelation fields in the device object classes
796 RuntimeOutput.print("IoTMaster: Going to instrument for " + strObjClassName + " with objectID " +
797 strFieldObjectID, BOOL_VERBOSE);
798 for(Map.Entry<String,Object> map : hmObjectFieldObjects.entrySet()) {
799 RuntimeOutput.print("IoTMaster: Object name: " + map.getValue().getClass().getName(), BOOL_VERBOSE);
800 // Iterate over HashMap and choose between processing
801 String strFieldName = map.getKey();
802 String strClassName = map.getValue().getClass().getName();
803 String strFieldIdentifier = strFieldName + strFieldObjectID;
804 if(strClassName.equals(STR_SET_INSTRUMENTER_CLS)) {
805 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
806 if(setInstrumenter.getObjTableName().equals(STR_IOT_DEV_ADD_CLS)) {
807 // Instrument the normal IoTDeviceAddress
808 setRouterPolicyIoTSetDevice(strFieldIdentifier, map, strIoTSlaveObjectHostAdd);
809 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ADD_CLS)) {
810 // Instrument the IoTAddress
811 setRouterPolicyIoTSetAddress(strFieldIdentifier, map, strIoTSlaveObjectHostAdd);
812 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ZB_ADD_CLS)) {
813 // Instrument the IoTZigbeeAddress - special feature for Zigbee device support
814 RuntimeOutput.print("IoTMaster: IoTZigbeeAddress found! No router policy is set here..",
817 String strErrMsg = "IoTMaster: Device driver object" +
818 " can only have IoTSet<IoTAddress>, IoTSet<IoTDeviceAddress>," +
819 " or IoTSet<IoTZigbeeAddress>!";
820 throw new Error(strErrMsg);
823 String strErrMsg = "IoTMaster: Device driver object can only have IoTSet for addresses!";
824 throw new Error(strErrMsg);
831 * A private method to send files to a Java slave driver
833 * @params serverSocket ServerSocket
834 * @params _inStream InputStream
835 * @params _outStream OutputStream
836 * @params strObjName String
837 * @params strObjClassName String
838 * @params strObjClassInterfaceName String
839 * @params strObjStubClsIntfaceName String
840 * @params strIoTSlaveObjectHostAdd String
841 * @params strFieldObjectID String
842 * @params arrFieldValues Object[]
843 * @params arrFieldClasses Class[]
846 private void sendFileToJavaSlaveDriver(ServerSocket serverSocket, InputStream _inStream, OutputStream _outStream,
847 String strObjName, String strObjClassName, String strObjClassInterfaceName, String strObjStubClsIntfaceName,
848 String strIoTSlaveObjectHostAdd, String strFieldObjectID, Object[] arrFieldValues, Class[] arrFieldClasses)
849 throws IOException, ClassNotFoundException {
851 ObjectInputStream inStream = (ObjectInputStream) _inStream;
852 ObjectOutputStream outStream = (ObjectOutputStream) _outStream;
853 // Create message to transfer file first
854 String sFileName = strObjClassName + STR_JAR_FILE_EXT;
855 String sPath = STR_IOT_CODE_PATH + strObjClassName + "/" + sFileName;
856 File file = new File(sPath);
857 commMasterToSlave(new MessageSendFile(IoTCommCode.TRANSFER_FILE, sFileName, file.length()),
858 "Sending file!", inStream, outStream);
859 // Send file - JAR file for object creation
860 sendFile(serverSocket.accept(), sPath, file.length());
861 Message msgReply = (Message) inStream.readObject();
862 RuntimeOutput.print("IoTMaster: Reply message: " + msgReply.getMessage(), BOOL_VERBOSE);
863 // Pack object information to create object on a IoTSlave
864 Message msgObjIoTSlave = new MessageCreateObject(IoTCommCode.CREATE_OBJECT, strIoTSlaveObjectHostAdd,
865 strObjClassName, strObjName, strObjClassInterfaceName, strObjStubClsIntfaceName, commHan.getRMIRegPort(strObjName),
866 commHan.getRMIStubPort(strObjName), arrFieldValues, arrFieldClasses);
868 commMasterToSlave(msgObjIoTSlave, "Sending object information", inStream, outStream);
873 * A private method to send files to a Java slave driver
877 private void sendFileToCppSlaveDriver(String strObjClassName, String strIoTSlaveObjectHostAdd)
878 throws IOException, ClassNotFoundException {
880 // Create message to transfer file first
881 String sFileName = strObjClassName + STR_ZIP_FILE_EXT;
882 String sFile = STR_IOT_CODE_PATH + strObjClassName + "/" + sFileName;
883 String strCmdSend = STR_SCP + " " + sFile + " " + STR_USERNAME + strIoTSlaveObjectHostAdd + ":" + STR_SLAVE_DIR;
884 runCommand(strCmdSend);
885 RuntimeOutput.print("IoTMaster: Executing: " + strCmdSend, BOOL_VERBOSE);
887 String strCmdUnzip = STR_SSH + " " + STR_USERNAME + strIoTSlaveObjectHostAdd + " cd " +
888 STR_SLAVE_DIR + " sudo unzip -o " + sFileName + ";";
889 runCommand(strCmdUnzip);
890 RuntimeOutput.print("IoTMaster: Executing: " + strCmdUnzip, BOOL_VERBOSE);
896 * Construct command line for Java IoTSlave
900 private String getCmdJavaDriverIoTSlave(String strIoTMasterHostAdd, String strIoTSlaveObjectHostAdd, String strObjName) {
902 return STR_SSH + " " + STR_USERNAME + strIoTSlaveObjectHostAdd + " cd " + STR_RUNTIME_DIR + " sudo java " +
903 STR_CLS_PATH + " " + STR_RMI_PATH + " " + STR_RMI_HOSTNAME +
904 strIoTSlaveObjectHostAdd + " " + STR_IOT_SLAVE_CLS + " " + strIoTMasterHostAdd + " " +
905 commHan.getComPort(strObjName) + " " + commHan.getRMIRegPort(strObjName) + " " +
906 commHan.getRMIStubPort(strObjName) + " >& " + STR_LOG_FILE_PATH + strObjName + ".log &";
911 * Construct command line for C++ IoTSlave
915 private String getCmdCppDriverIoTSlave(String strIoTMasterHostAdd, String strIoTSlaveObjectHostAdd, String strObjName) {
917 return STR_SSH + " " + STR_USERNAME + strIoTSlaveObjectHostAdd + " cd " +
918 STR_SLAVE_DIR + " sudo " + STR_IOTSLAVE_CPP + " " + strIoTMasterHostAdd + " " +
919 commHan.getComPort(strObjName) + " " + strObjName;
924 * A private method to create an object on a specific machine
926 * @params strObjName String object name
927 * @params strObjClassName String object class name
928 * @params strObjClassInterfaceName String object class interface name
929 * @params strIoTSlaveObjectHostAdd String IoTSlave host address
930 * @params strFieldObjectID String field object ID
931 * @params arrFieldValues Array of field values
932 * @params arrFieldClasses Array of field classes
935 private void createObject(String strObjName, String strObjClassName, String strObjClassInterfaceName, String strObjStubClsIntfaceName,
936 String strIoTSlaveObjectHostAdd, String strFieldObjectID, Object[] arrFieldValues, Class[] arrFieldClasses)
937 throws IOException, FileNotFoundException, ClassNotFoundException, InterruptedException {
944 start = System.currentTimeMillis();
946 // Construct ssh command line
947 // e.g. ssh rtrimana@dw-2.eecs.uci.edu cd <path>;
948 // java -cp $CLASSPATH:./*.jar
949 // -Djava.rmi.server.codebase=file:./*.jar
950 // iotruntime.IoTSlave dw-1.eecs.uci.edu 46151 23829 42874 &
951 // The In-Port for IoTMaster is the Out-Port for IoTSlave and vice versa
952 String strSSHCommand = null;
953 if(STR_LANGUAGE.equals(STR_JAVA))
954 strSSHCommand = getCmdJavaDriverIoTSlave(strIoTMasterHostAdd, strIoTSlaveObjectHostAdd, strObjName);
956 strSSHCommand = getCmdCppDriverIoTSlave(strIoTMasterHostAdd, strIoTSlaveObjectHostAdd, strObjName);
958 RuntimeOutput.print(strSSHCommand, BOOL_VERBOSE);
959 // Start a new thread to start a new JVM
960 createThread(strSSHCommand);
961 ServerSocket serverSocket = new ServerSocket(commHan.getComPort(strObjName));
962 Socket socket = serverSocket.accept();
963 //InputStream inStream = new ObjectInputStream(socket.getInputStream());
964 //OutputStream outStream = new ObjectOutputStream(socket.getOutputStream());
965 InputStream inStream = null;
966 OutputStream outStream = null;
967 if(STR_LANGUAGE.equals(STR_JAVA)) {
968 inStream = new ObjectInputStream(socket.getInputStream());
969 outStream = new ObjectOutputStream(socket.getOutputStream());
970 } else { // At this point the language is certainly C++, otherwise would've complained above
971 inStream = new BufferedInputStream(socket.getInputStream());
972 outStream = new BufferedOutputStream(socket.getOutputStream());
977 result = System.currentTimeMillis()-start;
978 System.out.println("\n\n ==> Time needed to start JVM for " + strObjName + ": " + result + "\n\n");
981 start = System.currentTimeMillis();
983 if(STR_LANGUAGE.equals(STR_JAVA)) {
984 sendFileToJavaSlaveDriver(serverSocket, inStream, outStream, strObjName,
985 strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName,
986 strIoTSlaveObjectHostAdd, strFieldObjectID, arrFieldValues, arrFieldClasses);
988 sendFileToCppSlaveDriver(strObjClassName, strIoTSlaveObjectHostAdd);
989 createObjectCpp(strObjName, strObjClassName, strObjClassInterfaceName, strIoTSlaveObjectHostAdd,
990 commHan.getRMIRegPort(strObjName), commHan.getRMIStubPort(strObjName), arrFieldValues, arrFieldClasses,
991 outStream, inStream);
995 result = System.currentTimeMillis()-start;
996 System.out.println("\n\n ==> Time needed to send JAR file for " + strObjName + ": " + result + "\n\n");
999 start = System.currentTimeMillis();
1001 // Instrument the class source code and look for IoTSet for device addresses
1002 // e.g. @config private IoTSet<IoTDeviceAddress> lb_addresses;
1003 RuntimeOutput.print("IoTMaster: Instantiating for " + strObjClassName + " with objectID " + strFieldObjectID, BOOL_VERBOSE);
1004 // Get the object and the class names
1005 // Build objects for IoTSet and IoTRelation fields in the device object classes
1006 Object crimObj = mapClassNameToCrim.get(strObjClassName + strFieldObjectID);
1007 HashMap<String,Object> hmObjectFieldObjects = null;
1008 if (crimObj instanceof ClassRuntimeInstrumenterMaster) {
1009 ClassRuntimeInstrumenterMaster crim = (ClassRuntimeInstrumenterMaster) crimObj;
1010 hmObjectFieldObjects = crim.getFieldObjects();
1011 } else if (crimObj instanceof CRuntimeInstrumenterMaster) {
1012 CRuntimeInstrumenterMaster crim = (CRuntimeInstrumenterMaster) crimObj;
1013 hmObjectFieldObjects = crim.getFieldObjects();
1015 for(Map.Entry<String,Object> map : hmObjectFieldObjects.entrySet()) {
1016 RuntimeOutput.print("IoTMaster: Object name: " + map.getValue().getClass().getName(), BOOL_VERBOSE);
1017 // Iterate over HashMap and choose between processing
1018 String strFieldName = map.getKey();
1019 String strClassName = map.getValue().getClass().getName();
1020 String strFieldIdentifier = strFieldName + strFieldObjectID;
1021 if(strClassName.equals(STR_SET_INSTRUMENTER_CLS)) {
1022 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
1023 if(setInstrumenter.getObjTableName().equals(STR_IOT_DEV_ADD_CLS)) {
1024 // Instrument the normal IoTDeviceAddress
1025 synchronized(this) {
1026 instrumentIoTSetDevice(strFieldIdentifier, strObjName, strFieldName, strIoTSlaveObjectHostAdd, inStream, outStream);
1028 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ZB_ADD_CLS)) {
1029 // Instrument the IoTZigbeeAddress - special feature for Zigbee device support
1030 synchronized(this) {
1031 instrumentIoTSetZBDevice(map, strObjName, strFieldName, strIoTSlaveObjectHostAdd, inStream, outStream);
1033 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ADD_CLS)) {
1034 // Instrument the IoTAddress
1035 synchronized(this) {
1036 instrumentIoTSetAddress(strFieldIdentifier, strFieldName, inStream, outStream);
1039 String strErrMsg = "IoTMaster: Device driver object can only have IoTSet<IoTAddress>, IoTSet<IoTDeviceAddress>," +
1040 " or IoTSet<IoTZigbeeAddress>!";
1041 throw new Error(strErrMsg);
1044 String strErrMsg = "IoTMaster: Device driver object can only have IoTSet for addresses!";
1045 throw new Error(strErrMsg);
1049 // TODO: Change this later
1051 if(STR_LANGUAGE.equals(STR_JAVA)) {
1052 ObjectOutputStream oStream = (ObjectOutputStream) outStream;
1053 oStream.writeObject(new MessageSimple(IoTCommCode.END_SESSION));
1054 } else { // C++ side for now will be running continuously because it's an infinite loop (not in a separate thread)
1055 createDriverObjectCpp(outStream, inStream);
1056 //endSessionCpp(outStream);
1060 result = System.currentTimeMillis()-start;
1061 System.out.println("\n\n ==> Time needed to create object " + strObjName + " and instrument IoTDeviceAddress: " + result + "\n\n");
1067 serverSocket.close();
1072 * A private method to create controller objects
1076 private void createControllerObjects() throws InterruptedException {
1078 // Create a list of threads
1079 List<Thread> threads = new ArrayList<Thread>();
1080 // Get the list of active controller objects and loop it
1081 List<String> listActiveControllerObject = commHan.getActiveControllerObjectList();
1082 for(String strObjName : listActiveControllerObject) {
1084 ObjectCreationInfo objCrtInfo = commHan.getObjectCreationInfo(strObjName);
1085 Thread objectThread = new Thread(new Runnable() {
1087 synchronized(this) {
1089 createObject(strObjName, objCrtInfo.getObjectClassName(), objCrtInfo.getObjectClassInterfaceName(),
1090 objCrtInfo.getObjectStubClassInterfaceName(), objCrtInfo.getIoTSlaveObjectHostAdd(),
1091 commHan.getFieldObjectID(strObjName), commHan.getArrayFieldValues(strObjName),
1092 commHan.getArrayFieldClasses(strObjName));
1093 } catch (IOException |
1094 ClassNotFoundException |
1095 InterruptedException ex) {
1096 ex.printStackTrace();
1101 threads.add(objectThread);
1102 objectThread.start();
1105 for (Thread thread : threads) {
1108 } catch (InterruptedException ex) {
1109 ex.printStackTrace();
1116 * A private method to instrument IoTSet
1118 * @params Map.Entry<String,Object> Entry of map IoTSet instrumentation
1119 * @params strFieldName String field name
1122 private void instrumentIoTSet(Map.Entry<String,Object> map, String strFieldName)
1123 throws IOException, ClassNotFoundException, InterruptedException {
1125 // Get information from the set
1126 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
1127 objInitHand.addField(strFieldName, IoTCommCode.CREATE_NEW_IOTSET);
1129 int iRows = setInstrumenter.numberOfRows();
1130 for(int iRow=0; iRow<iRows; iRow++) {
1131 // Get field classes and values
1132 arrFieldClasses = setInstrumenter.fieldClasses(iRow);
1133 arrFieldValues = setInstrumenter.fieldValues(iRow);
1134 // Get object ID and class name
1135 String strObjID = setInstrumenter.fieldObjectID(iRow);
1136 strObjClassName = setInstrumenter.fieldEntryType(strObjID);
1137 // Call the method to create an object
1138 instrumentObject(strObjID);
1139 int iNumOfPorts = Integer.parseInt(STR_NUM_CALLBACK_PORTS);
1140 objInitHand.addObjectIntoField(strFieldName, strIoTSlaveObjectHostAdd, strObjName,
1141 strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName, commHan.getRMIRegPort(strObjName),
1142 commHan.getRMIStubPort(strObjName), commHan.getCallbackPorts(strObjName, iNumOfPorts));
1148 * A private method to instrument IoTRelation
1150 * @params Map.Entry<String,Object> Entry of map IoTRelation instrumentation
1151 * @params strFieldName String field name
1154 private void instrumentIoTRelation(Map.Entry<String,Object> map, String strFieldName)
1155 throws IOException, ClassNotFoundException, InterruptedException {
1157 // Get information from the set
1158 RelationInstrumenter relationInstrumenter = (RelationInstrumenter) map.getValue();
1159 int iRows = relationInstrumenter.numberOfRows();
1160 objInitHand.addField(strFieldName, IoTCommCode.CREATE_NEW_IOTRELATION);
1162 for(int iRow=0; iRow<iRows; iRow++) {
1163 // Operate on the first set first
1164 arrFieldClasses = relationInstrumenter.firstFieldClasses(iRow);
1165 arrFieldValues = relationInstrumenter.firstFieldValues(iRow);
1166 String strObjID = relationInstrumenter.firstFieldObjectID(iRow);
1167 strObjClassName = relationInstrumenter.firstEntryFieldType(strObjID);
1168 // Call the method to create an object
1169 instrumentObject(strObjID);
1170 // Get the first object controller host address
1171 String strFirstIoTSlaveObjectHostAdd = strIoTSlaveObjectHostAdd;
1172 int iNumOfPorts = Integer.parseInt(STR_NUM_CALLBACK_PORTS);
1173 objInitHand.addObjectIntoField(strFieldName, strIoTSlaveObjectHostAdd, strObjName,
1174 strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName,
1175 commHan.getRMIRegPort(strObjName), commHan.getRMIStubPort(strObjName),
1176 commHan.getCallbackPorts(strObjName, iNumOfPorts));
1177 // Operate on the second set
1178 arrFieldClasses = relationInstrumenter.secondFieldClasses(iRow);
1179 arrFieldValues = relationInstrumenter.secondFieldValues(iRow);
1180 strObjID = relationInstrumenter.secondFieldObjectID(iRow);
1181 strObjClassName = relationInstrumenter.secondEntryFieldType(strObjID);
1182 // Call the method to create an object
1183 instrumentObject(strObjID);
1184 // Get the second object controller host address
1185 String strSecondIoTSlaveObjectHostAdd = strIoTSlaveObjectHostAdd;
1186 objInitHand.addSecondObjectIntoField(strFieldName, strIoTSlaveObjectHostAdd, strObjName,
1187 strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName,
1188 commHan.getRMIRegPort(strObjName), commHan.getRMIStubPort(strObjName),
1189 commHan.getCallbackPorts(strObjName, iNumOfPorts));
1190 // ROUTING POLICY: first and second controller objects in IoTRelation
1191 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strFirstIoTSlaveObjectHostAdd,
1192 strSecondIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
1193 // ROUTING POLICY: Send the same routing policy to both the hosts
1194 routerConfig.configureHostMainPolicies(strFirstIoTSlaveObjectHostAdd, strFirstIoTSlaveObjectHostAdd,
1195 strSecondIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
1196 routerConfig.configureHostMainPolicies(strSecondIoTSlaveObjectHostAdd, strFirstIoTSlaveObjectHostAdd,
1197 strSecondIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
1202 * A method to reinitialize IoTSet and IoTRelation in the code based on ObjectInitHandler information
1204 * @params inStream ObjectInputStream communication
1205 * @params outStream ObjectOutputStream communication
1208 private void initializeSetsAndRelationsJava(InputStream inStream, OutputStream outStream)
1209 throws IOException, ClassNotFoundException {
1210 // Get list of fields
1211 List<String> strFields = objInitHand.getListOfFields();
1212 // Iterate on HostAddress
1213 for(String str : strFields) {
1214 IoTCommCode iotcommMsg = objInitHand.getFieldMessage(str);
1215 if (iotcommMsg == IoTCommCode.CREATE_NEW_IOTSET) {
1216 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO CREATE IOTSET
1217 Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, str);
1218 commMasterToSlave(msgCrtIoTSet, "Create new IoTSet!", inStream, outStream);
1219 List<ObjectInitInfo> listObject = objInitHand.getListObjectInitInfo(str);
1220 for (ObjectInitInfo objInitInfo : listObject) {
1221 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTSET
1222 commMasterToSlave(new MessageGetObject(IoTCommCode.GET_IOTSET_OBJECT, objInitInfo.getIoTSlaveObjectHostAdd(),
1223 objInitInfo.getObjectName(), objInitInfo.getObjectClassName(), objInitInfo.getObjectClassInterfaceName(),
1224 objInitInfo.getObjectStubClassInterfaceName(), objInitInfo.getRMIRegistryPort(), objInitInfo.getRMIStubPort(),
1225 objInitInfo.getRMICallbackPorts()), "Get IoTSet object!", inStream, outStream);
1228 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO REINITIALIZE IOTSET FIELD
1229 commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTSET_FIELD),
1230 "Renitialize IoTSet field!", inStream, outStream);
1231 } else if (iotcommMsg == IoTCommCode.CREATE_NEW_IOTRELATION) {
1232 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO CREATE IOTRELATION
1233 Message msgCrtIoTRel = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTRELATION, str);
1234 commMasterToSlave(msgCrtIoTRel, "Create new IoTRelation!", inStream, outStream);
1235 List<ObjectInitInfo> listObject = objInitHand.getListObjectInitInfo(str);
1236 List<ObjectInitInfo> listSecondObject = objInitHand.getSecondObjectInitInfo(str);
1237 Iterator it = listSecondObject.iterator();
1238 for (ObjectInitInfo objInitInfo : listObject) {
1239 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTRELATION (FIRST OBJECT)
1240 commMasterToSlave(new MessageGetObject(IoTCommCode.GET_IOTRELATION_FIRST_OBJECT,
1241 objInitInfo.getIoTSlaveObjectHostAdd(), objInitInfo.getObjectName(), objInitInfo.getObjectClassName(),
1242 objInitInfo.getObjectClassInterfaceName(), objInitInfo.getObjectStubClassInterfaceName(),
1243 objInitInfo.getRMIRegistryPort(), objInitInfo.getRMIStubPort(), objInitInfo.getRMICallbackPorts()),
1244 "Get IoTRelation first object!", inStream, outStream);
1245 ObjectInitInfo objSecObj = (ObjectInitInfo) it.next();
1246 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTRELATION (SECOND OBJECT)
1247 commMasterToSlave(new MessageGetObject(IoTCommCode.GET_IOTRELATION_SECOND_OBJECT,
1248 objSecObj.getIoTSlaveObjectHostAdd(), objSecObj.getObjectName(), objSecObj.getObjectClassName(),
1249 objSecObj.getObjectClassInterfaceName(), objSecObj.getObjectStubClassInterfaceName(),
1250 objSecObj.getRMIRegistryPort(), objSecObj.getRMIStubPort(), objSecObj.getRMICallbackPorts()),
1251 "Get IoTRelation second object!", inStream, outStream);
1253 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO REINITIALIZE IOTRELATION FIELD
1254 commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTRELATION_FIELD),
1255 "Renitialize IoTRelation field!", inStream, outStream);
1261 * A method to reinitialize IoTSet and IoTRelation in the code based on ObjectInitHandler information
1263 * @params inStream ObjectInputStream communication
1264 * @params outStream ObjectOutputStream communication
1267 private void initializeSetsAndRelationsCpp(InputStream inStream, OutputStream outStream)
1268 throws IOException, ClassNotFoundException {
1269 // Get list of fields
1270 List<String> strFields = objInitHand.getListOfFields();
1271 // Iterate on HostAddress
1272 for(String str : strFields) {
1273 IoTCommCode iotcommMsg = objInitHand.getFieldMessage(str);
1274 if (iotcommMsg == IoTCommCode.CREATE_NEW_IOTSET) {
1275 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO CREATE IOTSET
1276 createNewIoTSetCpp(str, outStream, inStream);
1277 List<ObjectInitInfo> listObject = objInitHand.getListObjectInitInfo(str);
1278 for (ObjectInitInfo objInitInfo : listObject) {
1279 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTSET
1280 getIoTSetRelationObjectCpp(IoTCommCode.GET_IOTSET_OBJECT, objInitInfo.getIoTSlaveObjectHostAdd(), objInitInfo.getObjectName(),
1281 objInitInfo.getObjectClassName(), objInitInfo.getObjectClassInterfaceName(), objInitInfo.getObjectStubClassInterfaceName(),
1282 objInitInfo.getRMIRegistryPort(), objInitInfo.getRMIStubPort(), objInitInfo.getRMICallbackPorts(), outStream, inStream);
1284 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO REINITIALIZE IOTSET FIELD
1285 reinitializeIoTSetFieldCpp(outStream, inStream);
1286 } else if (iotcommMsg == IoTCommCode.CREATE_NEW_IOTRELATION) {
1287 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO CREATE IOTRELATION
1288 // TODO: createNewIoTRelation needs to be created here!
1289 createNewIoTRelationCpp(str, outStream, inStream);
1290 List<ObjectInitInfo> listObject = objInitHand.getListObjectInitInfo(str);
1291 List<ObjectInitInfo> listSecondObject = objInitHand.getSecondObjectInitInfo(str);
1292 Iterator it = listSecondObject.iterator();
1293 for (ObjectInitInfo objInitInfo : listObject) {
1294 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTRELATION (FIRST OBJECT)
1295 getIoTSetRelationObjectCpp(IoTCommCode.GET_IOTRELATION_FIRST_OBJECT, objInitInfo.getIoTSlaveObjectHostAdd(), objInitInfo.getObjectName(),
1296 objInitInfo.getObjectClassName(), objInitInfo.getObjectClassInterfaceName(), objInitInfo.getObjectStubClassInterfaceName(),
1297 objInitInfo.getRMIRegistryPort(), objInitInfo.getRMIStubPort(), objInitInfo.getRMICallbackPorts(), outStream, inStream);
1298 ObjectInitInfo objSecObj = (ObjectInitInfo) it.next();
1299 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTRELATION (SECOND OBJECT)
1300 getIoTSetRelationObjectCpp(IoTCommCode.GET_IOTRELATION_SECOND_OBJECT, objSecObj.getIoTSlaveObjectHostAdd(), objSecObj.getObjectName(),
1301 objSecObj.getObjectClassName(), objSecObj.getObjectClassInterfaceName(), objSecObj.getObjectStubClassInterfaceName(),
1302 objSecObj.getRMIRegistryPort(), objSecObj.getRMIStubPort(), objSecObj.getRMICallbackPorts(), outStream, inStream);
1304 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO REINITIALIZE IOTRELATION FIELD
1305 reinitializeIoTRelationFieldCpp(outStream, inStream);
1311 * A method to set router basic policies at once
1313 * @param strRouter String router name
1316 private void setRouterBasicPolicies(String strRouter) {
1318 String strMonitorHost = routerConfig.getIPFromMACAddress(STR_MONITORING_HOST);
1319 routerConfig.configureRouterICMPPolicies(strRouter, strMonitorHost);
1320 routerConfig.configureRouterDHCPPolicies(strRouter);
1321 routerConfig.configureRouterDNSPolicies(strRouter);
1322 routerConfig.configureRouterSSHPolicies(strRouter, strMonitorHost);
1323 routerConfig.configureRejectPolicies(strRouter);
1327 * A method to set host basic policies at once
1329 * @param strHost String host name
1332 private void setHostBasicPolicies(String strHost) {
1334 String strMonitorHost = routerConfig.getIPFromMACAddress(STR_MONITORING_HOST);
1335 routerConfig.configureHostDHCPPolicies(strHost);
1336 routerConfig.configureHostDNSPolicies(strHost);
1337 if (strHost.equals(strMonitorHost)) {
1338 // Check if this is the monitoring host
1339 routerConfig.configureHostICMPPolicies(strHost);
1340 routerConfig.configureHostSSHPolicies(strHost);
1342 routerConfig.configureHostICMPPolicies(strHost, strMonitorHost);
1343 routerConfig.configureHostSSHPolicies(strHost, strMonitorHost);
1345 // Apply SQL allowance policies to master host
1346 if (strHost.equals(strIoTMasterHostAdd)) {
1347 routerConfig.configureHostSQLPolicies(strHost);
1349 routerConfig.configureRejectPolicies(strHost);
1353 * A method to create a thread for policy deployment
1355 * @param strRouterAddress String router address to configure
1356 * @param setHostAddresses Set of strings for host addresses to configure
1359 private void createPolicyThreads(String strRouterAddress, Set<String> setHostAddresses) throws IOException {
1361 // Create a list of threads
1362 List<Thread> threads = new ArrayList<Thread>();
1363 // Start threads for hosts
1364 for(String strAddress : setHostAddresses) {
1365 Thread policyThread = new Thread(new Runnable() {
1367 synchronized(this) {
1368 routerConfig.sendHostPolicies(strAddress);
1372 threads.add(policyThread);
1373 policyThread.start();
1374 RuntimeOutput.print("Deploying policies for: " + strAddress, BOOL_VERBOSE);
1376 // A thread for router
1377 Thread policyThread = new Thread(new Runnable() {
1379 synchronized(this) {
1380 routerConfig.sendRouterPolicies(strRouterAddress);
1384 threads.add(policyThread);
1385 policyThread.start();
1386 RuntimeOutput.print("Deploying policies on router: " + strRouterAddress, BOOL_VERBOSE);
1388 for (Thread thread : threads) {
1391 } catch (InterruptedException ex) {
1392 ex.printStackTrace();
1399 * A method to send files to Java IoTSlave
1401 * @params strObjControllerName String
1402 * @params serverSocket ServerSocket
1403 * @params inStream ObjectInputStream communication
1404 * @params outStream ObjectOutputStream communication
1407 private void sendFileToJavaSlave(String strObjControllerName, ServerSocket serverSocket,
1408 InputStream _inStream, OutputStream _outStream) throws IOException, ClassNotFoundException {
1410 ObjectInputStream inStream = (ObjectInputStream) _inStream;
1411 ObjectOutputStream outStream = (ObjectOutputStream) _outStream;
1413 String strControllerJarName = strObjControllerName + STR_JAR_FILE_EXT;
1414 String strControllerJarNamePath = STR_CONT_PATH + strObjControllerName + "/" +
1415 strControllerJarName;
1416 File file = new File(strControllerJarNamePath);
1417 commMasterToSlave(new MessageSendFile(IoTCommCode.TRANSFER_FILE, strControllerJarName, file.length()),
1418 "Sending file!", inStream, outStream);
1419 // Send file - Class file for object creation
1420 sendFile(serverSocket.accept(), strControllerJarNamePath, file.length());
1421 Message msgReply = (Message) inStream.readObject();
1422 RuntimeOutput.print("IoTMaster: Reply message: " + msgReply.getMessage(), BOOL_VERBOSE);
1423 // Send .zip file if additional zip file is specified
1424 String strObjCfgFile = strObjControllerName + STR_CFG_FILE_EXT;
1425 String strObjCfgFilePath = STR_CONT_PATH + strObjControllerName + "/" + strObjCfgFile;
1426 String strAdditionalFile = parseConfigFile(strObjCfgFilePath, STR_FILE_TRF_CFG);
1427 if (strAdditionalFile.equals(STR_YES)) {
1428 String strControllerCmpName = strObjControllerName + STR_ZIP_FILE_EXT;
1429 String strControllerCmpNamePath = STR_CONT_PATH + strObjControllerName + "/" +
1430 strControllerCmpName;
1431 file = new File(strControllerCmpNamePath);
1432 commMasterToSlave(new MessageSendFile(IoTCommCode.TRANSFER_FILE, strControllerCmpName, file.length()),
1433 "Sending file!", inStream, outStream);
1434 // Send file - Class file for object creation
1435 sendFile(serverSocket.accept(), strControllerCmpNamePath, file.length());
1436 msgReply = (Message) inStream.readObject();
1437 RuntimeOutput.print("IoTMaster: Reply message: " + msgReply.getMessage(), BOOL_VERBOSE);
1443 * A method to send files to C++ IoTSlave
1446 * TODO: Need to look into this (as of now, file transferred retains the "data" format,
1447 * hence it is unreadable from outside world
1449 private void sendFileToCppSlave(String sFilePath, String sFileName, Socket fileSocket,
1450 InputStream inStream, OutputStream outStream) throws IOException {
1452 sendCommCode(IoTCommCode.TRANSFER_FILE, outStream, inStream);
1454 sendString(sFileName, outStream); recvAck(inStream);
1455 File file = new File(sFilePath + sFileName);
1456 int iFileLen = toIntExact(file.length());
1457 RuntimeOutput.print("IoTMaster: Sending file " + sFileName + " with length " + iFileLen + " bytes...", BOOL_VERBOSE);
1459 sendInteger(iFileLen, outStream); recvAck(inStream);
1460 RuntimeOutput.print("IoTMaster: Sent file size!", BOOL_VERBOSE);
1461 byte[] bytFile = new byte[iFileLen];
1462 InputStream inFileStream = new FileInputStream(file);
1463 RuntimeOutput.print("IoTMaster: Opened file!", BOOL_VERBOSE);
1465 OutputStream outFileStream = fileSocket.getOutputStream();
1466 RuntimeOutput.print("IoTMaster: Got output stream!", BOOL_VERBOSE);
1468 while ((iCount = inFileStream.read(bytFile)) > 0) {
1469 outFileStream.write(bytFile, 0, iCount);
1471 RuntimeOutput.print("IoTMaster: File sent!", BOOL_VERBOSE);
1477 * A method to send files to C++ IoTSlave (now master using Process() to start
1478 * file transfer using scp)
1482 private void sendFileToCppSlave(String sFilePath, String sFileName) throws IOException {
1484 // Construct shell command to transfer file
1485 String sFile = sFilePath + sFileName;
1486 String strCmdSend = STR_SCP + " " + sFile + " " + STR_USERNAME + strIoTSlaveControllerHostAdd + ":" + STR_SLAVE_DIR;
1487 runCommand(strCmdSend);
1488 RuntimeOutput.print("IoTMaster: Executing: " + strCmdSend, BOOL_VERBOSE);
1490 String strCmdUnzip = STR_SSH + " " + STR_USERNAME + strIoTSlaveControllerHostAdd + " cd " +
1491 STR_SLAVE_DIR + " sudo unzip -o " + sFileName + ";";
1492 runCommand(strCmdUnzip);
1493 RuntimeOutput.print("IoTMaster: Executing: " + strCmdUnzip, BOOL_VERBOSE);
1498 * runCommand() method runs shell command
1500 * @param strCommand String that contains command line
1503 private void runCommand(String strCommand) {
1506 Runtime runtime = Runtime.getRuntime();
1507 Process process = runtime.exec(strCommand);
1509 } catch (IOException ex) {
1510 System.out.println("RouterConfig: IOException: " + ex.getMessage());
1511 ex.printStackTrace();
1512 } catch (InterruptedException ex) {
1513 System.out.println("RouterConfig: InterruptException: " + ex.getMessage());
1514 ex.printStackTrace();
1520 * Construct command line for Java IoTSlave
1524 private String getCmdJavaIoTSlave(String strObjControllerName) {
1526 return STR_SSH + " " + STR_USERNAME + strIoTSlaveControllerHostAdd + " cd " +
1527 STR_RUNTIME_DIR + " sudo java " + STR_JVM_INIT_HEAP_SIZE + " " +
1528 STR_JVM_MAX_HEAP_SIZE + " " + STR_CLS_PATH + " " +
1529 STR_RMI_PATH + " " + STR_IOT_SLAVE_CLS + " " + strIoTMasterHostAdd + " " +
1530 commHan.getComPort(strObjControllerName) + " " +
1531 commHan.getRMIRegPort(strObjControllerName) + " " +
1532 commHan.getRMIStubPort(strObjControllerName) + " >& " +
1533 STR_LOG_FILE_PATH + strObjControllerName + ".log &";
1538 * Construct command line for C++ IoTSlave
1542 private String getCmdCppIoTSlave(String strObjControllerName) {
1544 return STR_SSH + " " + STR_USERNAME + strIoTSlaveControllerHostAdd + " cd " +
1545 STR_SLAVE_DIR + " sudo " + STR_IOTSLAVE_CPP + " " + strIoTMasterHostAdd + " " +
1546 commHan.getComPort(strObjControllerName) + " " + strObjControllerName;
1551 * sendInteger() sends an integer in bytes
1553 public void sendInteger(int intSend, OutputStream outStream) throws IOException {
1555 BufferedOutputStream output = (BufferedOutputStream) outStream;
1556 // Transform integer into bytes
1557 ByteBuffer bb = ByteBuffer.allocate(INT_SIZE);
1559 // Send the byte array
1560 output.write(bb.array(), 0, INT_SIZE);
1566 * recvInteger() receives integer in bytes
1568 public int recvInteger(InputStream inStream) throws IOException {
1570 BufferedInputStream input = (BufferedInputStream) inStream;
1571 // Wait until input is available
1572 while(input.available() == 0);
1573 // Read integer - 4 bytes
1574 byte[] recvInt = new byte[INT_SIZE];
1575 input.read(recvInt, 0, INT_SIZE);
1576 int retVal = ByteBuffer.wrap(recvInt).getInt();
1583 * recvString() receives String in bytes
1585 public String recvString(InputStream inStream) throws IOException {
1587 BufferedInputStream input = (BufferedInputStream) inStream;
1588 int strLen = recvInteger(inStream);
1589 // Wait until input is available
1590 while(input.available() == 0);
1591 // Read String per strLen
1592 byte[] recvStr = new byte[strLen];
1593 input.read(recvStr, 0, strLen);
1594 String retVal = new String(recvStr);
1601 * sendString() sends a String in bytes
1603 public void sendString(String strSend, OutputStream outStream) throws IOException {
1605 BufferedOutputStream output = (BufferedOutputStream) outStream;
1606 // Transform String into bytes
1607 byte[] strSendBytes = strSend.getBytes();
1608 int strLen = strSend.length();
1609 // Send the string length first
1610 sendInteger(strLen, outStream);
1611 // Send the byte array
1612 output.write(strSendBytes, 0, strLen);
1618 * Convert integer to enum
1620 public IoTCommCode getCode(int intCode) throws IOException {
1622 IoTCommCode[] commCode = IoTCommCode.values();
1623 IoTCommCode retCode = commCode[intCode];
1632 public boolean recvAck(InputStream inStream) throws IOException {
1634 int intAck = recvInteger(inStream);
1635 IoTCommCode codeAck = getCode(intAck);
1636 if (codeAck == IoTCommCode.ACKNOWLEDGED)
1646 public void sendEndTransfer(OutputStream outStream) throws IOException {
1648 int endCode = IoTCommCode.END_TRANSFER.ordinal();
1649 sendInteger(endCode, outStream);
1654 * Send communication code to C++
1656 public void sendCommCode(IoTCommCode inpCommCode, OutputStream outStream, InputStream inStream) throws IOException {
1659 IoTCommCode commCode = inpCommCode;
1660 int intCode = commCode.ordinal();
1661 // TODO: delete this later
1662 System.out.println("DEBUG: Sending " + commCode + " with ordinal: " + intCode);
1663 sendInteger(intCode, outStream); recvAck(inStream);
1668 * Create a main controller object for C++
1670 public void createMainObjectCpp(String strObjControllerName, OutputStream outStream, InputStream inStream) throws IOException {
1672 sendCommCode(IoTCommCode.CREATE_MAIN_OBJECT, outStream, inStream);
1673 String strMainObjName = strObjControllerName;
1674 sendString(strMainObjName, outStream); recvAck(inStream);
1675 RuntimeOutput.print("IoTMaster: Create a main object: " + strMainObjName, BOOL_VERBOSE);
1680 * A helper function that converts Class into String
1682 * @param strDataType String MySQL data type
1685 public String getClassConverted(Class<?> cls) {
1687 if (cls == String.class) {
1689 } else if (cls == int.class) {
1698 * A helper function that converts Object into String for transfer to C++ slave
1700 * @param obj Object to be converted
1701 * @param strClassType String Java Class type
1704 public String getObjectConverted(Object obj) {
1706 if (obj instanceof String) {
1707 return (String) obj;
1708 } else if (obj instanceof Integer) {
1709 return Integer.toString((Integer) obj);
1717 * Create a driver object for C++
1719 public void createObjectCpp(String strObjName, String strObjClassName, String strObjClassInterfaceName, String strIoTSlaveObjectHostAdd,
1720 Integer iRMIRegistryPort, Integer iRMIStubPort, Object[] arrFieldValues, Class[] arrFieldClasses,
1721 OutputStream outStream, InputStream inStream) throws IOException {
1723 sendCommCode(IoTCommCode.CREATE_OBJECT, outStream, inStream);
1724 RuntimeOutput.print("IoTMaster: Send request to create a driver object... ", BOOL_VERBOSE);
1725 RuntimeOutput.print("IoTMaster: Driver object name: " + strObjName, BOOL_VERBOSE);
1726 sendString(strObjName, outStream); recvAck(inStream);
1727 RuntimeOutput.print("IoTMaster: Driver object class name: " + strObjClassName, BOOL_VERBOSE);
1728 sendString(strObjClassName, outStream); recvAck(inStream);
1729 RuntimeOutput.print("IoTMaster: Driver object interface name: " + strObjClassInterfaceName, BOOL_VERBOSE);
1730 sendString(strObjStubClsIntfaceName, outStream); recvAck(inStream);
1731 RuntimeOutput.print("IoTMaster: Driver object skeleton class name: " + strObjClassInterfaceName + STR_SKEL_CLASS_SUFFIX, BOOL_VERBOSE);
1732 sendString(strObjClassInterfaceName + STR_SKEL_CLASS_SUFFIX, outStream); recvAck(inStream);
1733 RuntimeOutput.print("IoTMaster: Driver object registry port: " + iRMIRegistryPort, BOOL_VERBOSE);
1734 sendInteger(iRMIRegistryPort, outStream); recvAck(inStream);
1735 RuntimeOutput.print("IoTMaster: Driver object stub port: " + iRMIStubPort, BOOL_VERBOSE);
1736 sendInteger(iRMIStubPort, outStream); recvAck(inStream);
1737 int numOfArgs = arrFieldValues.length;
1738 RuntimeOutput.print("IoTMaster: Send constructor arguments! Number of arguments: " + numOfArgs, BOOL_VERBOSE);
1739 sendInteger(numOfArgs, outStream); recvAck(inStream);
1740 for(Object obj : arrFieldValues) {
1741 String str = getObjectConverted(obj);
1742 sendString(str, outStream); recvAck(inStream);
1744 RuntimeOutput.print("IoTMaster: Send constructor argument classes!", BOOL_VERBOSE);
1745 for(Class cls : arrFieldClasses) {
1746 String str = getClassConverted(cls);
1747 sendString(str, outStream); recvAck(inStream);
1753 * Create new IoTSet for C++
1755 public void createNewIoTSetCpp(String strObjFieldName, OutputStream outStream, InputStream inStream) throws IOException {
1757 sendCommCode(IoTCommCode.CREATE_NEW_IOTSET, outStream, inStream);
1758 RuntimeOutput.print("IoTMaster: Creating new IoTSet...", BOOL_VERBOSE);
1759 RuntimeOutput.print("IoTMaster: Send object field name: " + strObjFieldName, BOOL_VERBOSE);
1760 sendString(strObjFieldName, outStream); recvAck(inStream);
1765 * Create new IoTRelation for C++
1767 public void createNewIoTRelationCpp(String strObjFieldName, OutputStream outStream, InputStream inStream) throws IOException {
1769 sendCommCode(IoTCommCode.CREATE_NEW_IOTRELATION, outStream, inStream);
1770 RuntimeOutput.print("IoTMaster: Creating new IoTRelation...", BOOL_VERBOSE);
1771 RuntimeOutput.print("IoTMaster: Send object field name: " + strObjFieldName, BOOL_VERBOSE);
1772 sendString(strObjFieldName, outStream); recvAck(inStream);
1777 * Get a IoTDeviceAddress object for C++
1779 public void getDeviceIoTSetObjectCpp(OutputStream outStream, InputStream inStream,
1780 String strDeviceAddress, int iSourcePort, int iDestPort, boolean bSourceWildCard, boolean bDestWildCard) throws IOException {
1782 sendCommCode(IoTCommCode.GET_DEVICE_IOTSET_OBJECT, outStream, inStream);
1783 RuntimeOutput.print("IoTMaster: Getting IoTDeviceAddress...", BOOL_VERBOSE);
1784 sendString(strDeviceAddress, outStream); recvAck(inStream);
1785 sendInteger(iSourcePort, outStream); recvAck(inStream);
1786 sendInteger(iDestPort, outStream); recvAck(inStream);
1787 int iSourceWildCard = (bSourceWildCard ? 1 : 0);
1788 sendInteger(iSourceWildCard, outStream); recvAck(inStream);
1789 int iDestWildCard = (bDestWildCard ? 1 : 0);
1790 sendInteger(iDestWildCard, outStream); recvAck(inStream);
1791 RuntimeOutput.print("IoTMaster: Send device address: " + strDeviceAddress, BOOL_VERBOSE);
1796 * Get a IoTSet content object for C++
1798 public void getIoTSetRelationObjectCpp(IoTCommCode iotCommCode, String strIoTSlaveHostAddress, String strObjectName, String strObjectClassName,
1799 String strObjectClassInterfaceName, String strObjectStubClassInterfaceName, int iRMIRegistryPort, int iRMIStubPort,
1800 Integer[] iCallbackPorts, OutputStream outStream, InputStream inStream) throws IOException {
1802 sendCommCode(iotCommCode, outStream, inStream);
1803 RuntimeOutput.print("IoTMaster: Getting IoTSet object content...", BOOL_VERBOSE);
1805 RuntimeOutput.print("IoTMaster: Send host address: " + strIoTSlaveHostAddress, BOOL_VERBOSE);
1806 sendString(strIoTSlaveHostAddress, outStream); recvAck(inStream);
1807 RuntimeOutput.print("IoTMaster: Driver object name: " + strObjectName, BOOL_VERBOSE);
1808 sendString(strObjectName, outStream); recvAck(inStream);
1809 RuntimeOutput.print("IoTMaster: Driver object class name: " + strObjectClassName, BOOL_VERBOSE);
1810 sendString(strObjectClassName, outStream); recvAck(inStream);
1811 RuntimeOutput.print("IoTMaster: Driver object interface name: " + strObjectClassInterfaceName, BOOL_VERBOSE);
1812 sendString(strObjectClassInterfaceName, outStream); recvAck(inStream);
1813 RuntimeOutput.print("IoTMaster: Driver object stub class name: " + strObjectStubClassInterfaceName + STR_STUB_CLASS_SUFFIX, BOOL_VERBOSE);
1814 sendString(strObjectStubClassInterfaceName + STR_STUB_CLASS_SUFFIX, outStream); recvAck(inStream);
1815 RuntimeOutput.print("IoTMaster: Driver object registry port: " + iRMIRegistryPort, BOOL_VERBOSE);
1816 sendInteger(iRMIRegistryPort, outStream); recvAck(inStream);
1817 RuntimeOutput.print("IoTMaster: Driver object stub port: " + iRMIStubPort, BOOL_VERBOSE);
1818 sendInteger(iRMIStubPort, outStream); recvAck(inStream);
1819 sendInteger(iCallbackPorts.length, outStream); recvAck(inStream);
1820 for(Integer i : iCallbackPorts) {
1821 sendInteger(i, outStream); recvAck(inStream);
1827 * Reinitialize IoTRelation field for C++
1829 private void reinitializeIoTRelationFieldCpp(OutputStream outStream, InputStream inStream) throws IOException {
1831 RuntimeOutput.print("IoTMaster: About to Reinitialize IoTRelation field!", BOOL_VERBOSE);
1832 sendCommCode(IoTCommCode.REINITIALIZE_IOTRELATION_FIELD, outStream, inStream);
1833 RuntimeOutput.print("IoTMaster: Reinitialize IoTRelation field!", BOOL_VERBOSE);
1838 * Reinitialize IoTSet field for C++
1840 private void reinitializeIoTSetFieldCpp(OutputStream outStream, InputStream inStream) throws IOException {
1842 RuntimeOutput.print("IoTMaster: About to Reinitialize IoTSet field!", BOOL_VERBOSE);
1843 sendCommCode(IoTCommCode.REINITIALIZE_IOTSET_FIELD, outStream, inStream);
1844 RuntimeOutput.print("IoTMaster: Reinitialize IoTSet field!", BOOL_VERBOSE);
1849 * Create driver object for C++
1851 private void createDriverObjectCpp(OutputStream outStream, InputStream inStream) throws IOException {
1853 sendCommCode(IoTCommCode.CREATE_DRIVER_OBJECT, outStream, inStream);
1854 RuntimeOutput.print("IoTMaster: Send command to create driver object!", BOOL_VERBOSE);
1859 * Invoke init() for C++
1861 private void invokeInitMethodCpp(OutputStream outStream, InputStream inStream) throws IOException {
1863 sendCommCode(IoTCommCode.INVOKE_INIT_METHOD, outStream, inStream);
1864 RuntimeOutput.print("IoTMaster: Invoke init method!", BOOL_VERBOSE);
1869 * End session for C++
1871 public void endSessionCpp(OutputStream outStream) throws IOException {
1873 // Send message to end session
1874 IoTCommCode endSessionCode = IoTCommCode.END_SESSION;
1875 int intCode = endSessionCode.ordinal();
1876 sendInteger(intCode, outStream);
1877 //RuntimeOutput.print("IoTMaster: Send request to create a main object: " + strObjName, BOOL_VERBOSE);
1878 RuntimeOutput.print("IoTMaster: Send request to end session!", BOOL_VERBOSE);
1883 * A method to assign objects to multiple JVMs, including
1884 * the controller/device object that uses other objects
1885 * in IoTSet and IoTRelation
1889 private void createObjects() {
1896 // Extract hostname for this IoTMaster from MySQL DB
1897 strIoTMasterHostAdd = routerConfig.getIPFromMACAddress(STR_MASTER_MAC_ADD);
1898 // Loop as we can still find controller/device classes
1899 for(int i=0; i<strObjectNames.length; i++) {
1901 start = System.currentTimeMillis();
1903 // Assign a new list of PrintWriter objects
1904 routerConfig.renewPrintWriter();
1905 // Get controller names one by one
1906 String strObjControllerName = strObjectNames[i];
1907 // Use LoadBalancer to assign a host address
1908 //strIoTSlaveControllerHostAdd = lbIoT.selectHost();
1909 strIoTSlaveControllerHostAdd = routerConfig.getIPFromMACAddress(lbIoT.selectHost());
1910 if (strIoTSlaveControllerHostAdd == null)
1911 throw new Error("IoTMaster: Could not translate MAC to IP address! Please check the router's /tmp/dhcp.leases!");
1912 // == START INITIALIZING CONTROLLER/DEVICE IOTSLAVE ==
1913 // Add port connection and get port numbers
1914 // Naming for objects ProximitySensor becomes ProximitySensor0, ProximitySensor1, etc.
1915 commHan.addPortConnection(strIoTSlaveControllerHostAdd, strObjControllerName);
1916 // ROUTING POLICY: IoTMaster and main controller object
1917 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTMasterHostAdd,
1918 strIoTSlaveControllerHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjControllerName));
1919 // ROUTING POLICY: Send the same routing policy to both the hosts
1920 routerConfig.configureHostMainPolicies(strIoTMasterHostAdd, strIoTMasterHostAdd,
1921 strIoTSlaveControllerHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjControllerName));
1922 routerConfig.configureHostMainPolicies(strIoTSlaveControllerHostAdd, strIoTMasterHostAdd,
1923 strIoTSlaveControllerHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjControllerName));
1925 // Construct ssh command line and create a controller thread for e.g. AcmeProximity
1926 String strSSHCommand = null;
1927 if(STR_LANGUAGE.equals(STR_JAVA))
1928 strSSHCommand = getCmdJavaIoTSlave(strObjControllerName);
1929 else if(STR_LANGUAGE.equals(STR_CPP))
1930 strSSHCommand = getCmdCppIoTSlave(strObjControllerName);
1932 throw new Error("IoTMaster: Language specification not recognized: " + STR_LANGUAGE);
1933 RuntimeOutput.print(strSSHCommand, BOOL_VERBOSE);
1934 createThread(strSSHCommand);
1935 // Wait for connection
1936 // Create a new socket for communication
1937 ServerSocket serverSocket = new ServerSocket(commHan.getComPort(strObjControllerName));
1938 Socket socket = serverSocket.accept();
1939 InputStream inStream = null;
1940 OutputStream outStream = null;
1941 if(STR_LANGUAGE.equals(STR_JAVA)) {
1942 inStream = new ObjectInputStream(socket.getInputStream());
1943 outStream = new ObjectOutputStream(socket.getOutputStream());
1944 } else { // At this point the language is certainly C++, otherwise would've complained above
1945 inStream = new BufferedInputStream(socket.getInputStream());
1946 outStream = new BufferedOutputStream(socket.getOutputStream());
1949 RuntimeOutput.print("IoTMaster: Communication established!", BOOL_VERBOSE);
1952 result = System.currentTimeMillis()-start;
1953 System.out.println("\n\n ==> From start until after SSH for main controller: " + result);
1955 start = System.currentTimeMillis();
1957 // Send files for every controller class
1958 // e.g. AcmeProximity.jar and AcmeProximity.zip
1959 String strControllerClassName = strObjControllerName + STR_CLS_FILE_EXT;
1960 String strControllerClassNamePath = STR_CONT_PATH + strObjControllerName + "/" +
1961 strControllerClassName;
1963 if(STR_LANGUAGE.equals(STR_JAVA)) {
1964 sendFileToJavaSlave(strObjControllerName, serverSocket, inStream, outStream);
1965 // Create main controller/device object
1966 commMasterToSlave(new MessageCreateMainObject(IoTCommCode.CREATE_MAIN_OBJECT, strObjControllerName),
1967 "Create main object!", inStream, outStream);
1969 String strControllerZipFile = strObjControllerName + STR_ZIP_FILE_EXT;
1970 String strControllerFilePath = STR_CONT_PATH + strObjControllerName + "/";
1971 sendFileToCppSlave(strControllerFilePath, strControllerZipFile);
1972 createMainObjectCpp(strObjControllerName, outStream, inStream);
1976 result = System.currentTimeMillis()-start;
1977 System.out.println("\n\n ==> From IoTSlave start until main controller object is created: " + result);
1978 System.out.println(" ==> Including file transfer times!\n\n");
1980 start = System.currentTimeMillis();
1982 // == END INITIALIZING CONTROLLER/DEVICE IOTSLAVE ==
1983 // Instrumenting one file
1984 RuntimeOutput.print("IoTMaster: Opening class file: " + strControllerClassName, BOOL_VERBOSE);
1985 RuntimeOutput.print("IoTMaster: Class file path: " + strControllerClassNamePath, BOOL_VERBOSE);
1986 HashMap<String,Object> hmControllerFieldObjects = null;
1987 if(STR_LANGUAGE.equals(STR_JAVA)) {
1988 FileInputStream fis = new FileInputStream(strControllerClassNamePath);
1989 ClassReader cr = new ClassReader(fis);
1990 ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
1991 ClassRuntimeInstrumenterMaster crim = new ClassRuntimeInstrumenterMaster(cw, null, BOOL_VERBOSE);
1994 hmControllerFieldObjects = crim.getFieldObjects();
1996 String strControllerConfigFile = STR_CONT_PATH + strObjControllerName + "/" + strObjControllerName + STR_CFG_FILE_EXT;
1997 CRuntimeInstrumenterMaster crim = new CRuntimeInstrumenterMaster(strControllerConfigFile, null, BOOL_VERBOSE);
1998 hmControllerFieldObjects = crim.getFieldObjects();
2000 // Get the object and the class names
2001 // Build objects for IoTSet and IoTRelation fields in the controller/device classes
2002 //HashMap<String,Object> hmControllerFieldObjects = crim.getFieldObjects();
2003 for(Map.Entry<String,Object> map : hmControllerFieldObjects.entrySet()) {
2004 RuntimeOutput.print("IoTMaster: Object name: " + map.getValue().getClass().getName(), BOOL_VERBOSE);
2005 // Iterate over HashMap and choose between processing
2006 // SetInstrumenter vs. RelationInstrumenter
2007 String strFieldName = map.getKey();
2008 String strClassName = map.getValue().getClass().getName();
2009 if(strClassName.equals(STR_SET_INSTRUMENTER_CLS)) {
2010 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
2011 if(setInstrumenter.getObjTableName().equals(STR_IOT_DEV_ADD_CLS)) {
2012 String strErrMsg = "IoTMaster: Controller object" +
2013 " cannot have IoTSet<IoTDeviceAddress>!";
2014 throw new Error(strErrMsg);
2015 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ZB_ADD_CLS)) {
2016 String strErrMsg = "IoTMaster: Controller object" +
2017 " cannot have IoTSet<ZigbeeAddress>!";
2018 throw new Error(strErrMsg);
2019 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ADD_CLS)) {
2020 // Instrument the IoTAddress
2021 setRouterPolicyIoTSetAddress(strFieldName, map, strIoTSlaveControllerHostAdd);
2022 instrumentIoTSetAddress(strFieldName, strFieldName, inStream, outStream);
2025 instrumentIoTSet(map, strFieldName);
2027 } else if (strClassName.equals(STR_REL_INSTRUMENTER_CLS)) {
2028 instrumentIoTRelation(map, strFieldName);
2032 result = System.currentTimeMillis()-start;
2033 System.out.println("\n\n ==> Time needed to instrument device driver objects: " + result + "\n\n");
2034 System.out.println(" ==> #Objects: " + commHan.getActiveControllerObjectList().size() + "\n\n");
2037 start = System.currentTimeMillis();
2039 // ROUTING POLICY: Deploy basic policies if this is the last controller
2040 if (i == strObjectNames.length-1) {
2041 // ROUTING POLICY: implement basic policies to reject all other irrelevant traffics
2042 for(String s: commHan.getHosts()) {
2043 setHostBasicPolicies(s);
2045 // We retain all the basic policies for router,
2046 // but we delete the initial allowance policies for internal all TCP and UDP communications
2047 setRouterBasicPolicies(STR_ROUTER_ADD);
2049 // Close access to policy files and deploy policies
2050 routerConfig.close();
2051 // Deploy the policy
2052 HashSet<String> setAddresses = new HashSet<String>(commHan.getHosts());
2053 setAddresses.add(strIoTMasterHostAdd);
2054 createPolicyThreads(STR_ROUTER_ADD, setAddresses);
2057 result = System.currentTimeMillis()-start;
2058 System.out.println("\n\n ==> Time needed to send policy files and deploy them : " + result + "\n\n");
2061 start = System.currentTimeMillis();
2063 // Separating object creations and Set/Relation initializations
2064 createControllerObjects();
2067 result = System.currentTimeMillis()-start;
2068 System.out.println("\n\n ==> Time needed to instantiate objects: " + result + "\n\n");
2070 start = System.currentTimeMillis();
2072 // Sets and relations initializations
2073 if(STR_LANGUAGE.equals(STR_JAVA))
2074 initializeSetsAndRelationsJava(inStream, outStream);
2076 initializeSetsAndRelationsCpp(inStream, outStream);;
2079 result = System.currentTimeMillis()-start;
2080 System.out.println("\n\n ==> Time needed to initialize sets and relations: " + result + "\n\n");
2082 if(STR_LANGUAGE.equals(STR_JAVA))
2083 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO EXECUTE INIT METHOD
2084 commMasterToSlave(new MessageSimple(IoTCommCode.INVOKE_INIT_METHOD), "Invoke init() method!", inStream, outStream);
2086 invokeInitMethodCpp(outStream, inStream);
2087 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO END PROCESS
2088 if(STR_LANGUAGE.equals(STR_JAVA)) {
2089 ObjectOutputStream oStream = (ObjectOutputStream) outStream;
2090 oStream.writeObject(new MessageSimple(IoTCommCode.END_SESSION));
2091 } else // C++ side will wait until the program finishes, it's not generating a separate thread for now
2092 //endSessionCpp(outStream);
2096 serverSocket.close();
2097 commHan.printLists();
2098 lbIoT.printHostInfo();
2101 } catch (IOException |
2102 InterruptedException |
2103 ClassNotFoundException ex) {
2104 System.out.println("IoTMaster: Exception: "
2106 ex.printStackTrace();
2110 public static void main(String args[]) {
2112 // Detect the available controller/device classes
2113 // Input args[] should be used to list the controllers/devices
2114 // e.g. java IoTMaster AcmeProximity AcmeThermostat AcmeVentController
2115 IoTMaster iotMaster = new IoTMaster(args);
2117 iotMaster.parseIoTMasterConfigFile();
2118 // Initialize CommunicationHandler, LoadBalancer, and RouterConfig
2119 iotMaster.initLiveDataStructure();
2121 iotMaster.createObjects();