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.ObjectInputStream;
23 import java.io.ObjectOutputStream;
24 import java.io.IOException;
25 import java.lang.ClassNotFoundException;
26 import java.lang.Class;
27 import java.lang.reflect.*;
28 import java.net.Socket;
29 import java.net.ServerSocket;
31 import static java.lang.Math.toIntExact;
33 /** Class IoTMaster is responsible to use ClassRuntimeInstrumenterMaster
34 * to instrument the controller/device bytecode and starts multiple
35 * IoTSlave running on different JVM's in a distributed fashion.
37 * @author Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>
41 public class IoTMaster {
44 * IoTMaster class properties
46 * CommunicationHandler maintains the data structure for hostnames and ports
47 * LoadBalancer assigns a job onto a host based on certain metrics
49 private CommunicationHandler commHan;
50 private LoadBalancer lbIoT;
51 private RouterConfig routerConfig;
52 private ObjectInitHandler objInitHand;
53 private ObjectAddressInitHandler objAddInitHand;
54 private String[] strObjectNames;
55 // Now this can be either ClassRuntimeInstrumenterMaster or CRuntimeInstrumenterMaster
56 private Map<String,Object> mapClassNameToCrim;
59 * These properties hold information of a certain object
62 private String strObjName;
63 private String strObjClassName;
64 private String strObjClassInterfaceName;
65 private String strObjStubClsIntfaceName;
66 private String strIoTMasterHostAdd;
67 private String strIoTSlaveControllerHostAdd;
68 private String strIoTSlaveObjectHostAdd;
69 private Class[] arrFieldClasses;
70 private Object[] arrFieldValues;
71 private Socket filesocket;
74 * For connection with C++ IoTSlave
76 private ServerSocket serverSocketCpp;
77 private Socket socketCpp;
78 private BufferedInputStream inputCpp;
79 private BufferedOutputStream outputCpp;
81 // Constants that are to be extracted from config file
82 private static String STR_MASTER_MAC_ADD;
83 private static String STR_IOT_CODE_PATH;
84 private static String STR_CONT_PATH;
85 private static String STR_RUNTIME_DIR;
86 private static String STR_CLS_PATH;
87 private static String STR_RMI_PATH;
88 private static String STR_RMI_HOSTNAME;
89 private static String STR_LOG_FILE_PATH;
90 private static String STR_SSH_USERNAME;
91 private static String STR_ROUTER_ADD;
92 private static String STR_MONITORING_HOST;
93 private static String STR_ZB_GATEWAY_ADDRESS;
94 private static String STR_ZB_GATEWAY_PORT;
95 private static String STR_ZB_IOTMASTER_PORT;
96 private static String STR_NUM_CALLBACK_PORTS;
97 private static String STR_JVM_INIT_HEAP_SIZE;
98 private static String STR_JVM_MAX_HEAP_SIZE;
99 private static String STR_LANGUAGE;
100 private static boolean BOOL_VERBOSE;
103 * IoTMaster class constants
105 * Name constants - not to be configured by users
107 private static final String STR_IOT_MASTER_NAME = "IoTMaster";
108 private static final String STR_CFG_FILE_EXT = ".config";
109 private static final String STR_CLS_FILE_EXT = ".class";
110 private static final String STR_JAR_FILE_EXT = ".jar";
111 private static final String STR_ZIP_FILE_EXT = ".zip";
112 private static final String STR_TCP_PROTOCOL = "tcp";
113 private static final String STR_UDP_PROTOCOL = "udp";
114 private static final String STR_TCPGW_PROTOCOL = "tcpgw";
115 private static final String STR_NO_PROTOCOL = "nopro";
116 private static final String STR_SELF_MAC_ADD = "00:00:00:00:00:00";
117 private static final String STR_INTERFACE_CLS_CFG = "INTERFACE_CLASS";
118 private static final String STR_INT_STUB_CLS_CFG = "INTERFACE_STUB_CLASS";
119 private static final String STR_FILE_TRF_CFG = "ADDITIONAL_ZIP_FILE";
120 private static final String STR_YES = "Yes";
121 private static final String STR_NO = "No";
122 private static final String STR_JAVA = "Java";
123 private static final String STR_CPP = "C++";
126 * Runtime class name constants - not to be configured by users
128 private static final String STR_REL_INSTRUMENTER_CLS = "iotruntime.master.RelationInstrumenter";
129 private static final String STR_SET_INSTRUMENTER_CLS = "iotruntime.master.SetInstrumenter";
130 private static final String STR_IOT_SLAVE_CLS = "iotruntime.slave.IoTSlave";
131 private static final String STR_IOT_DEV_ADD_CLS = "IoTDeviceAddress";
132 private static final String STR_IOT_ZB_ADD_CLS = "IoTZigbeeAddress";
133 private static final String STR_IOT_ADD_CLS = "IoTAddress";
139 public IoTMaster(String[] argObjNms) {
145 objAddInitHand = null;
146 strObjectNames = argObjNms;
148 strObjClassName = null;
149 strObjClassInterfaceName = null;
150 strObjStubClsIntfaceName = null;
151 strIoTMasterHostAdd = null;
152 strIoTSlaveControllerHostAdd = null;
153 strIoTSlaveObjectHostAdd = null;
154 arrFieldClasses = null;
155 arrFieldValues = null;
157 mapClassNameToCrim = null;
158 // Connection with C++ IoTSlave
159 serverSocketCpp = null;
164 STR_MASTER_MAC_ADD = null;
165 STR_IOT_CODE_PATH = null;
166 STR_CONT_PATH = null;
167 STR_RUNTIME_DIR = null;
170 STR_RMI_HOSTNAME = null;
171 STR_LOG_FILE_PATH = null;
172 STR_SSH_USERNAME = null;
173 STR_ROUTER_ADD = null;
174 STR_MONITORING_HOST = null;
175 STR_ZB_GATEWAY_ADDRESS = null;
176 STR_ZB_GATEWAY_PORT = null;
177 STR_ZB_IOTMASTER_PORT = null;
178 STR_NUM_CALLBACK_PORTS = null;
179 STR_JVM_INIT_HEAP_SIZE = null;
180 STR_JVM_MAX_HEAP_SIZE = null;
182 BOOL_VERBOSE = false;
186 * A method to initialize CommunicationHandler, LoadBalancer, RouterConfig and ObjectInitHandler
190 private void initLiveDataStructure() {
192 commHan = new CommunicationHandler(BOOL_VERBOSE);
193 lbIoT = new LoadBalancer(BOOL_VERBOSE);
194 lbIoT.setupLoadBalancer();
195 routerConfig = new RouterConfig();
196 routerConfig.getAddressList(STR_ROUTER_ADD);
197 objInitHand = new ObjectInitHandler(BOOL_VERBOSE);
198 objAddInitHand = new ObjectAddressInitHandler(BOOL_VERBOSE);
199 mapClassNameToCrim = new HashMap<String,Object>();
203 * A method to initialize constants from config file
207 private void parseIoTMasterConfigFile() {
208 // Parse configuration file
209 Properties prop = new Properties();
210 String strCfgFileName = STR_IOT_MASTER_NAME + STR_CFG_FILE_EXT;
211 File file = new File(strCfgFileName);
212 FileInputStream fis = null;
214 fis = new FileInputStream(file);
217 } catch (IOException ex) {
218 System.out.println("IoTMaster: Error reading config file: " + strCfgFileName);
219 ex.printStackTrace();
221 // Initialize constants from config file
222 STR_MASTER_MAC_ADD = prop.getProperty("MAC_ADDRESS");
223 STR_IOT_CODE_PATH = prop.getProperty("IOT_CODE_PATH");
224 STR_CONT_PATH = prop.getProperty("CONTROLLERS_CODE_PATH");
225 STR_RUNTIME_DIR = prop.getProperty("RUNTIME_DIR");
226 STR_CLS_PATH = prop.getProperty("CLASS_PATH");
227 STR_RMI_PATH = prop.getProperty("RMI_PATH");
228 STR_RMI_HOSTNAME = prop.getProperty("RMI_HOSTNAME");
229 STR_LOG_FILE_PATH = prop.getProperty("LOG_FILE_PATH");
230 STR_SSH_USERNAME = prop.getProperty("SSH_USERNAME");
231 STR_ROUTER_ADD = prop.getProperty("ROUTER_ADD");
232 STR_MONITORING_HOST = prop.getProperty("MONITORING_HOST");
233 STR_ZB_GATEWAY_ADDRESS = prop.getProperty("ZIGBEE_GATEWAY_ADDRESS");
234 STR_ZB_GATEWAY_PORT = prop.getProperty("ZIGBEE_GATEWAY_PORT");
235 STR_ZB_IOTMASTER_PORT = prop.getProperty("ZIGBEE_IOTMASTER_PORT");
236 STR_NUM_CALLBACK_PORTS = prop.getProperty("NUMBER_CALLBACK_PORTS");
237 STR_JVM_INIT_HEAP_SIZE = prop.getProperty("JVM_INIT_HEAP_SIZE");
238 STR_JVM_MAX_HEAP_SIZE = prop.getProperty("JVM_MAX_HEAP_SIZE");
239 STR_LANGUAGE = prop.getProperty("LANGUAGE");
240 if(prop.getProperty("VERBOSE").equals(STR_YES)) {
244 RuntimeOutput.print("IoTMaster: Extracting information from config file: " + strCfgFileName, BOOL_VERBOSE);
245 RuntimeOutput.print("STR_MASTER_MAC_ADD=" + STR_MASTER_MAC_ADD, BOOL_VERBOSE);
246 RuntimeOutput.print("STR_IOT_CODE_PATH=" + STR_IOT_CODE_PATH, BOOL_VERBOSE);
247 RuntimeOutput.print("STR_CONT_PATH=" + STR_CONT_PATH, BOOL_VERBOSE);
248 RuntimeOutput.print("STR_RUNTIME_DIR=" + STR_RUNTIME_DIR, BOOL_VERBOSE);
249 RuntimeOutput.print("STR_CLS_PATH=" + STR_CLS_PATH, BOOL_VERBOSE);
250 RuntimeOutput.print("STR_RMI_PATH=" + STR_RMI_PATH, BOOL_VERBOSE);
251 RuntimeOutput.print("STR_RMI_HOSTNAME=" + STR_RMI_HOSTNAME, BOOL_VERBOSE);
252 RuntimeOutput.print("STR_LOG_FILE_PATH=" + STR_LOG_FILE_PATH, BOOL_VERBOSE);
253 RuntimeOutput.print("STR_SSH_USERNAME=" + STR_SSH_USERNAME, BOOL_VERBOSE);
254 RuntimeOutput.print("STR_ROUTER_ADD=" + STR_ROUTER_ADD, BOOL_VERBOSE);
255 RuntimeOutput.print("STR_MONITORING_HOST=" + STR_MONITORING_HOST, BOOL_VERBOSE);
256 RuntimeOutput.print("STR_ZB_GATEWAY_ADDRESS=" + STR_ZB_GATEWAY_ADDRESS, BOOL_VERBOSE);
257 RuntimeOutput.print("STR_ZB_GATEWAY_PORT=" + STR_ZB_GATEWAY_PORT, BOOL_VERBOSE);
258 RuntimeOutput.print("STR_ZB_IOTMASTER_PORT=" + STR_ZB_IOTMASTER_PORT, BOOL_VERBOSE);
259 RuntimeOutput.print("STR_NUM_CALLBACK_PORTS=" + STR_NUM_CALLBACK_PORTS, BOOL_VERBOSE);
260 RuntimeOutput.print("STR_JVM_INIT_HEAP_SIZE=" + STR_JVM_INIT_HEAP_SIZE, BOOL_VERBOSE);
261 RuntimeOutput.print("STR_JVM_MAX_HEAP_SIZE=" + STR_JVM_MAX_HEAP_SIZE, BOOL_VERBOSE);
262 RuntimeOutput.print("STR_LANGUAGE=" + STR_LANGUAGE, BOOL_VERBOSE);
263 RuntimeOutput.print("BOOL_VERBOSE=" + BOOL_VERBOSE, BOOL_VERBOSE);
264 RuntimeOutput.print("IoTMaster: Information extracted successfully!", BOOL_VERBOSE);
268 * A method to parse information from a config file
270 * @param strCfgFileName Config file name
271 * @param strCfgField Config file field name
274 private String parseConfigFile(String strCfgFileName, String strCfgField) {
275 // Parse configuration file
276 Properties prop = new Properties();
277 File file = new File(strCfgFileName);
278 FileInputStream fis = null;
280 fis = new FileInputStream(file);
283 } catch (IOException ex) {
284 System.out.println("IoTMaster: Error reading config file: " + strCfgFileName);
285 ex.printStackTrace();
287 System.out.println("IoTMaster: Reading " + strCfgField +
288 " from config file: " + strCfgFileName + " with value: " +
289 prop.getProperty(strCfgField, null));
290 // NULL is returned if the property isn't found
291 return prop.getProperty(strCfgField, null);
295 * A method to send files from IoTMaster
297 * @param filesocket File socket object
298 * @param sFileName File name
299 * @param lFLength File length
302 private void sendFile(Socket filesocket, String sFileName, long lFLength) throws IOException {
304 File file = new File(sFileName);
305 byte[] bytFile = new byte[toIntExact(lFLength)];
306 InputStream inFileStream = new FileInputStream(file);
308 OutputStream outFileStream = filesocket.getOutputStream();
310 while ((iCount = inFileStream.read(bytFile)) > 0) {
311 outFileStream.write(bytFile, 0, iCount);
314 RuntimeOutput.print("IoTMaster: File sent!", BOOL_VERBOSE);
318 * A method to create a thread
320 * @param sSSHCmd SSH command
323 private void createThread(String sSSHCmd) throws IOException {
325 // Start a new thread to start a new JVM
327 Runtime runtime = Runtime.getRuntime();
328 Process process = runtime.exec(sSSHCmd);
330 RuntimeOutput.print("Executing: " + sSSHCmd, BOOL_VERBOSE);
334 * A method to send command from master and receive reply from slave
336 * @params msgSend Message object
337 * @params strPurpose String that prints purpose message
338 * @params inStream Input stream
339 * @params outStream Output stream
342 private void commMasterToSlave(Message msgSend, String strPurpose,
343 ObjectInputStream inStream, ObjectOutputStream outStream)
344 throws IOException, ClassNotFoundException {
346 // Send message/command from master
347 outStream.writeObject(msgSend);
348 RuntimeOutput.print("IoTMaster: Send message: " + strPurpose, BOOL_VERBOSE);
350 // Get reply from slave as acknowledgment
351 Message msgReply = (Message) inStream.readObject();
352 RuntimeOutput.print("IoTMaster: Reply message: " + msgReply.getMessage(), BOOL_VERBOSE);
356 * A private method to instrument IoTSet device
358 * @params strFieldIdentifier String field name + object ID
359 * @params strFieldName String field name
360 * @params strIoTSlaveObjectHostAdd String slave host address
361 * @params inStream ObjectInputStream communication
362 * @params inStream ObjectOutputStream communication
365 private void instrumentIoTSetDevice(String strFieldIdentifier, String strObjName, String strFieldName, String strIoTSlaveObjectHostAdd,
366 ObjectInputStream inStream, ObjectOutputStream outStream)
367 throws IOException, ClassNotFoundException, InterruptedException {
369 // Get information from the set
370 List<Object[]> listObject = objAddInitHand.getFields(strFieldIdentifier);
371 // Create a new IoTSet
372 if(STR_LANGUAGE.equals(STR_JAVA)) {
373 Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, strFieldName);
374 commMasterToSlave(msgCrtIoTSet, "Create new IoTSet for IoTDeviceAddress!", inStream, outStream);
377 int iRows = listObject.size();
378 RuntimeOutput.print("IoTMaster: Number of rows for IoTDeviceAddress: " + iRows, BOOL_VERBOSE);
379 // Transfer the address
380 for(int iRow=0; iRow<iRows; iRow++) {
381 arrFieldValues = listObject.get(iRow);
382 // Get device address - if 00:00:00:00:00:00 that means it needs the driver object address (self)
383 String strDeviceAddress = null;
384 String strDeviceAddressKey = null;
385 if (arrFieldValues[0].equals(STR_SELF_MAC_ADD)) {
386 strDeviceAddress = strIoTSlaveObjectHostAdd;
387 strDeviceAddressKey = strObjName + "-" + strIoTSlaveObjectHostAdd;
389 strDeviceAddress = routerConfig.getIPFromMACAddress((String) arrFieldValues[0]);
390 strDeviceAddressKey = strObjName + "-" + strDeviceAddress;
392 int iDestDeviceDriverPort = (int) arrFieldValues[1];
393 String strProtocol = (String) arrFieldValues[2];
394 // Check for wildcard feature
395 boolean bSrcPortWildCard = false;
396 boolean bDstPortWildCard = false;
397 if (arrFieldValues.length > 3) {
398 bSrcPortWildCard = (boolean) arrFieldValues[3];
399 bDstPortWildCard = (boolean) arrFieldValues[4];
401 // Add the port connection into communication handler - if it's not assigned yet
402 if (commHan.getComPort(strDeviceAddressKey) == null) {
403 commHan.addPortConnection(strIoTSlaveObjectHostAdd, strDeviceAddressKey);
407 System.out.println("\n\n DEBUG: InstrumentSetDevice: Object Name: " + strObjName);
408 System.out.println("DEBUG: InstrumentSetDevice: Port number: " + commHan.getComPort(strDeviceAddressKey));
409 System.out.println("DEBUG: InstrumentSetDevice: Device address: " + strDeviceAddressKey + "\n\n");
411 // Send address one by one
412 if(STR_LANGUAGE.equals(STR_JAVA)) {
413 Message msgGetIoTSetObj = null;
414 if (bDstPortWildCard) {
415 String strUniqueDev = strDeviceAddressKey + ":" + iRow;
416 msgGetIoTSetObj = new MessageGetDeviceObject(IoTCommCode.GET_DEVICE_IOTSET_OBJECT,
417 strDeviceAddress, commHan.getAdditionalPort(strUniqueDev), iDestDeviceDriverPort, bSrcPortWildCard, bDstPortWildCard);
419 msgGetIoTSetObj = new MessageGetDeviceObject(IoTCommCode.GET_DEVICE_IOTSET_OBJECT,
420 strDeviceAddress, commHan.getComPort(strDeviceAddressKey), iDestDeviceDriverPort, bSrcPortWildCard, bDstPortWildCard);
421 commMasterToSlave(msgGetIoTSetObj, "Get IoTSet objects!", inStream, outStream);
425 // Reinitialize IoTSet on device object
426 if(STR_LANGUAGE.equals(STR_JAVA))
427 commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTSET_FIELD), "Reinitialize IoTSet fields!", inStream, outStream);
434 * A private method to instrument IoTSet Zigbee device
436 * @params Map.Entry<String,Object> Entry of map IoTSet instrumentation
437 * @params strFieldName String field name
438 * @params strIoTSlaveObjectHostAdd String slave host address
439 * @params inStream ObjectInputStream communication
440 * @params inStream ObjectOutputStream communication
443 private void instrumentIoTSetZBDevice(Map.Entry<String,Object> map, String strObjName, String strFieldName, String strIoTSlaveObjectHostAdd,
444 ObjectInputStream inStream, ObjectOutputStream outStream)
445 throws IOException, ClassNotFoundException, InterruptedException {
447 // Get information from the set
448 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
449 // Create a new IoTSet
450 if(STR_LANGUAGE.equals(STR_JAVA)) {
451 Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, strFieldName);
452 commMasterToSlave(msgCrtIoTSet, "Create new IoTSet for IoTZigbeeAddress!", inStream, outStream);
453 } else // TODO: will need to implement IoTSet Zigbee for C++ later
455 // Prepare ZigbeeConfig
456 String strZigbeeGWAddress = routerConfig.getIPFromMACAddress(STR_ZB_GATEWAY_ADDRESS);
457 String strZigbeeGWAddressKey = strObjName + "-" + strZigbeeGWAddress;
458 int iZigbeeGWPort = Integer.parseInt(STR_ZB_GATEWAY_PORT);
459 int iZigbeeIoTMasterPort = Integer.parseInt(STR_ZB_IOTMASTER_PORT);
460 commHan.addDevicePort(iZigbeeIoTMasterPort);
461 ZigbeeConfig zbConfig = new ZigbeeConfig(strZigbeeGWAddress, iZigbeeGWPort, iZigbeeIoTMasterPort,
463 // Add the port connection into communication handler - if it's not assigned yet
464 if (commHan.getComPort(strZigbeeGWAddressKey) == null) {
465 commHan.addPortConnection(strIoTSlaveObjectHostAdd, strZigbeeGWAddressKey);
467 int iRows = setInstrumenter.numberOfRows();
468 RuntimeOutput.print("IoTMaster: Number of rows for IoTZigbeeAddress: " + iRows, BOOL_VERBOSE);
471 System.out.println("\n\n DEBUG: InstrumentZigbeeDevice: Object Name: " + strObjName);
472 System.out.println("DEBUG: InstrumentZigbeeDevice: Port number: " + commHan.getComPort(strZigbeeGWAddressKey));
473 System.out.println("DEBUG: InstrumentZigbeeDevice: Device address: " + strZigbeeGWAddress + "\n\n");
475 // Transfer the address
476 for(int iRow=0; iRow<iRows; iRow++) {
477 arrFieldValues = setInstrumenter.fieldValues(iRow);
478 // Get device address
479 String strZBDevAddress = (String) arrFieldValues[0];
480 // Send policy to Zigbee gateway - TODO: Need to clear policy first?
481 zbConfig.setPolicy(strIoTSlaveObjectHostAdd, commHan.getComPort(strZigbeeGWAddressKey), strZBDevAddress);
482 // Send address one by one
483 if(STR_LANGUAGE.equals(STR_JAVA)) {
484 Message msgGetIoTSetZBObj = new MessageGetSimpleDeviceObject(IoTCommCode.GET_ZB_DEV_IOTSET_OBJECT, strZBDevAddress);
485 commMasterToSlave(msgGetIoTSetZBObj, "Get IoTSet objects!", inStream, outStream);
489 zbConfig.closeConnection();
490 // Reinitialize IoTSet on device object
491 commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTSET_FIELD), "Reinitialize IoTSet fields!", inStream, outStream);
496 * A private method to instrument IoTSet of addresses
498 * @params strFieldIdentifier String field name + object ID
499 * @params strFieldName String field name
500 * @params inStream ObjectInputStream communication
501 * @params inStream ObjectOutputStream communication
504 private void instrumentIoTSetAddress(String strFieldIdentifier, String strFieldName,
505 ObjectInputStream inStream, ObjectOutputStream outStream)
506 throws IOException, ClassNotFoundException, InterruptedException {
508 // Get information from the set
509 List<Object[]> listObject = objAddInitHand.getFields(strFieldIdentifier);
510 // Create a new IoTSet
511 if(STR_LANGUAGE.equals(STR_JAVA)) {
512 Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, strFieldName);
513 commMasterToSlave(msgCrtIoTSet, "Create new IoTSet for IoTAddress!", inStream, outStream);
516 int iRows = listObject.size();
517 RuntimeOutput.print("IoTMaster: Number of rows for IoTAddress: " + iRows, BOOL_VERBOSE);
518 // Transfer the address
519 for(int iRow=0; iRow<iRows; iRow++) {
520 arrFieldValues = listObject.get(iRow);
521 // Get device address
522 String strAddress = (String) arrFieldValues[0];
523 // Send address one by one
524 if(STR_LANGUAGE.equals(STR_JAVA)) {
525 Message msgGetIoTSetAddObj = new MessageGetSimpleDeviceObject(IoTCommCode.GET_ADD_IOTSET_OBJECT, strAddress);
526 commMasterToSlave(msgGetIoTSetAddObj, "Get IoTSet objects!", inStream, outStream);
530 // Reinitialize IoTSet on device object
531 commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTSET_FIELD),
532 "Reinitialize IoTSet fields!", inStream, outStream);
537 * A private method to instrument an object on a specific machine and setting up policies
539 * @params strFieldObjectID String field object ID
542 private void instrumentObject(String strFieldObjectID) throws IOException {
544 // Extract the interface name for RMI
545 // e.g. ProximitySensorInterface, TempSensorInterface, etc.
547 String strObjCfgFile = STR_IOT_CODE_PATH + strObjClassName + "/" + strObjClassName + STR_CFG_FILE_EXT;
548 strObjClassInterfaceName = parseConfigFile(strObjCfgFile, STR_INTERFACE_CLS_CFG);
549 strObjStubClsIntfaceName = parseConfigFile(strObjCfgFile, STR_INT_STUB_CLS_CFG);
550 // Create an object name, e.g. ProximitySensorImplPS1
551 strObjName = strObjClassName + strFieldObjectID;
552 // Check first if host exists
553 if(commHan.objectExists(strObjName)) {
554 // If this object exists already ...
555 // Re-read IoTSlave object hostname for further reference
556 strIoTSlaveObjectHostAdd = commHan.getHostAddress(strObjName);
557 RuntimeOutput.print("IoTMaster: Object with name: " + strObjName + " has existed!", BOOL_VERBOSE);
559 // If this is a new object ... then create one
560 // Get host address for IoTSlave from LoadBalancer
561 //strIoTSlaveObjectHostAdd = lbIoT.selectHost();
562 strIoTSlaveObjectHostAdd = routerConfig.getIPFromMACAddress(lbIoT.selectHost());
563 if (strIoTSlaveControllerHostAdd == null)
564 throw new Error("IoTMaster: Could not translate MAC to IP address! Please check the router's /tmp/dhcp.leases!");
565 RuntimeOutput.print("IoTMaster: Object name: " + strObjName, BOOL_VERBOSE);
566 // Add port connection and get port numbers
567 // Naming for objects ProximitySensor becomes ProximitySensor0, ProximitySensor1, etc.
568 commHan.addPortConnection(strIoTSlaveObjectHostAdd, strObjName);
569 commHan.addActiveControllerObject(strFieldObjectID, strObjName, strObjClassName, strObjClassInterfaceName,
570 strObjStubClsIntfaceName, strIoTSlaveObjectHostAdd, arrFieldValues, arrFieldClasses);
571 // ROUTING POLICY: IoTMaster and device/controller object
572 // Master-slave communication
573 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTMasterHostAdd,
574 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjName));
575 // ROUTING POLICY: Send the same routing policy to both the hosts
576 routerConfig.configureHostMainPolicies(strIoTMasterHostAdd, strIoTMasterHostAdd,
577 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjName));
578 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTMasterHostAdd,
579 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjName));
580 // Need to accommodate callback functions here - open ports for TCP
581 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveControllerHostAdd,
582 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
583 routerConfig.configureHostMainPolicies(strIoTSlaveControllerHostAdd, strIoTSlaveControllerHostAdd,
584 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
585 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveControllerHostAdd,
586 strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
587 // Instrument the IoTSet declarations inside the class file
588 instrumentObjectIoTSet(strFieldObjectID);
590 // Send routing policy to router for controller object
591 // ROUTING POLICY: RMI communication - RMI registry and stub ports
592 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
593 STR_TCP_PROTOCOL, commHan.getRMIRegPort(strObjName));
594 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
595 STR_TCP_PROTOCOL, commHan.getRMIStubPort(strObjName));
596 // Send the same set of routing policies to compute nodes
597 routerConfig.configureHostMainPolicies(strIoTSlaveControllerHostAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
598 STR_TCP_PROTOCOL, commHan.getRMIRegPort(strObjName));
599 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
600 STR_TCP_PROTOCOL, commHan.getRMIRegPort(strObjName));
601 routerConfig.configureHostMainPolicies(strIoTSlaveControllerHostAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
602 STR_TCP_PROTOCOL, commHan.getRMIStubPort(strObjName));
603 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
604 STR_TCP_PROTOCOL, commHan.getRMIStubPort(strObjName));
605 // Send the same set of routing policies for callback ports
606 setCallbackPortsPolicy(strObjName, STR_ROUTER_ADD, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
610 * A private method to set router policies for callback ports
612 * @params strRouterAdd String router address
613 * @params strIoTSlaveControllerHostAdd String slave controller host address
614 * @params strIoTSlaveObjectHostAdd String slave object host address
615 * @params strProtocol String protocol
616 * @return iPort Integer port number
618 private void setCallbackPortsPolicy(String strObjName, String strRouterAdd, String strIoTSlaveControllerHostAdd,
619 String strIoTSlaveObjectHostAdd, String strProtocol) {
621 int iNumCallbackPorts = Integer.parseInt(STR_NUM_CALLBACK_PORTS);
622 Integer[] rmiCallbackPorts = commHan.getCallbackPorts(strObjName, iNumCallbackPorts);
624 // Iterate over port numbers and set up policies
625 for (int i=0; i<iNumCallbackPorts; i++) {
626 routerConfig.configureRouterMainPolicies(strRouterAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
627 strProtocol, rmiCallbackPorts[i]);
628 routerConfig.configureHostMainPolicies(strIoTSlaveControllerHostAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
629 strProtocol, rmiCallbackPorts[i]);
630 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
631 strProtocol, rmiCallbackPorts[i]);
636 * A private method to set router policies for IoTDeviceAddress objects
638 * @params strFieldIdentifier String field name + object ID
639 * @params Map.Entry<String,Object> Entry of map IoTSet instrumentation
640 * @params strIoTSlaveObjectHostAdd String slave host address
643 private void setRouterPolicyIoTSetDevice(String strFieldIdentifier, Map.Entry<String,Object> map,
644 String strIoTSlaveObjectHostAdd) {
646 // Get information from the set
647 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
648 int iRows = setInstrumenter.numberOfRows();
649 RuntimeOutput.print("IoTMaster: Number of rows for IoTDeviceAddress: " + iRows, BOOL_VERBOSE);
650 // Transfer the address
651 for(int iRow=0; iRow<iRows; iRow++) {
652 arrFieldValues = setInstrumenter.fieldValues(iRow);
653 objAddInitHand.addField(strFieldIdentifier, arrFieldValues); // Save this for object instantiation
654 // Get device address - if 00:00:00:00:00:00 that means it needs the driver object address (self)
655 String strDeviceAddress = null;
656 String strDeviceAddressKey = null;
657 if (arrFieldValues[0].equals(STR_SELF_MAC_ADD)) {
658 strDeviceAddress = strIoTSlaveObjectHostAdd;
659 strDeviceAddressKey = strObjName + "-" + strIoTSlaveObjectHostAdd;
660 } else { // Concatenate object name and IP address to give unique key - for a case where there is one device for multiple drivers
661 strDeviceAddress = routerConfig.getIPFromMACAddress((String) arrFieldValues[0]);
662 strDeviceAddressKey = strObjName + "-" + strDeviceAddress;
664 int iDestDeviceDriverPort = (int) arrFieldValues[1];
665 String strProtocol = (String) arrFieldValues[2];
666 // Add the port connection into communication handler - if it's not assigned yet
667 if (commHan.getComPort(strDeviceAddressKey) == null)
668 commHan.addPortConnection(strIoTSlaveObjectHostAdd, strDeviceAddressKey);
669 boolean bDstPortWildCard = false;
670 // Recognize this and allocate different ports for it
671 if (arrFieldValues.length > 3) {
672 bDstPortWildCard = (boolean) arrFieldValues[4];
673 if (bDstPortWildCard) { // This needs a unique source port
674 String strUniqueDev = strDeviceAddressKey + ":" + iRow;
675 commHan.addAdditionalPort(strUniqueDev);
680 System.out.println("\n\n DEBUG: InstrumentPolicySetDevice: Object Name: " + strObjName);
681 System.out.println("DEBUG: InstrumentPolicySetDevice: Port number: " + commHan.getComPort(strDeviceAddressKey));
682 System.out.println("DEBUG: InstrumentPolicySetDevice: Device address: " + strDeviceAddressKey + "\n\n");
685 // Send routing policy to router for device drivers and devices
686 // ROUTING POLICY: RMI communication - RMI registry and stub ports
687 if((iDestDeviceDriverPort == -1) && (!strProtocol.equals(STR_NO_PROTOCOL))) {
688 // Port number -1 means that we don't set the policy strictly to port number level
689 // "nopro" = no protocol specified for just TCP or just UDP (can be both used as well)
690 // ROUTING POLICY: Device driver and device
691 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveObjectHostAdd, strDeviceAddress, strProtocol);
692 // ROUTING POLICY: Send to the compute node where the device driver is
693 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress, strProtocol);
694 } else if((iDestDeviceDriverPort == -1) && (strProtocol.equals(STR_NO_PROTOCOL))) {
695 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveObjectHostAdd, strDeviceAddress);
696 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress);
697 } else if(strProtocol.equals(STR_TCPGW_PROTOCOL)) {
698 // This is a TCP protocol that connects, e.g. a phone to our runtime system
699 // that provides a gateway access (accessed through destination port number)
700 commHan.addDevicePort(iDestDeviceDriverPort);
701 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveObjectHostAdd, strDeviceAddress, STR_TCP_PROTOCOL, iDestDeviceDriverPort);
702 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress, STR_TCP_PROTOCOL, iDestDeviceDriverPort);
703 routerConfig.configureRouterHTTPPolicies(STR_ROUTER_ADD, strIoTSlaveObjectHostAdd, strDeviceAddress);
704 routerConfig.configureHostHTTPPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress);
706 // Other port numbers...
707 commHan.addDevicePort(iDestDeviceDriverPort);
708 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveObjectHostAdd, strDeviceAddress, strProtocol,
709 commHan.getComPort(strDeviceAddressKey), iDestDeviceDriverPort);
710 routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress, strProtocol,
711 commHan.getComPort(strDeviceAddressKey), iDestDeviceDriverPort);
717 * A private method to set router policies for IoTAddress objects
719 * @params strFieldIdentifier String field name + object ID
720 * @params Map.Entry<String,Object> Entry of map IoTSet instrumentation
721 * @params strHostAddress String host address
724 private void setRouterPolicyIoTSetAddress(String strFieldIdentifier, Map.Entry<String,Object> map,
725 String strHostAddress) {
727 // Get information from the set
728 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
729 int iRows = setInstrumenter.numberOfRows();
730 RuntimeOutput.print("IoTMaster: Number of rows for IoTAddress: " + iRows, BOOL_VERBOSE);
731 // Transfer the address
732 for(int iRow=0; iRow<iRows; iRow++) {
733 arrFieldValues = setInstrumenter.fieldValues(iRow);
734 objAddInitHand.addField(strFieldIdentifier, arrFieldValues); // Save this for object instantiation
735 // Get device address
736 String strAddress = (String) arrFieldValues[0];
737 // Setting up router policies for HTTP/HTTPs
738 routerConfig.configureRouterHTTPPolicies(STR_ROUTER_ADD, strHostAddress, strAddress);
739 routerConfig.configureHostHTTPPolicies(strHostAddress, strHostAddress, strAddress);
744 * A private method to instrument an object's IoTSet and IoTRelation field to up policies
746 * Mostly the IoTSet fields would contain IoTDeviceAddress objects
748 * @params strFieldObjectID String field object ID
751 private void instrumentObjectIoTSet(String strFieldObjectID) throws IOException {
753 // If this is a new object ... then create one
754 // Instrument the class source code and look for IoTSet for device addresses
755 // e.g. @config private IoTSet<IoTDeviceAddress> lb_addresses;
756 HashMap<String,Object> hmObjectFieldObjects = null;
757 if(STR_LANGUAGE.equals(STR_JAVA)) {
758 String strObjectClassNamePath = STR_IOT_CODE_PATH + strObjClassName + "/" + strObjClassName + STR_CLS_FILE_EXT;
759 FileInputStream fis = new FileInputStream(strObjectClassNamePath);
760 ClassReader cr = new ClassReader(fis);
761 ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
762 // We need Object ID to instrument IoTDeviceAddress
763 ClassRuntimeInstrumenterMaster crim = new ClassRuntimeInstrumenterMaster(cw, strFieldObjectID, BOOL_VERBOSE);
766 mapClassNameToCrim.put(strObjClassName + strFieldObjectID, crim);
767 hmObjectFieldObjects = crim.getFieldObjects();
769 String strObjectClassNamePath = STR_IOT_CODE_PATH + strObjClassName + "/" + strObjClassName + STR_CFG_FILE_EXT;
770 CRuntimeInstrumenterMaster crim = new CRuntimeInstrumenterMaster(strObjectClassNamePath, strFieldObjectID, BOOL_VERBOSE);
771 mapClassNameToCrim.put(strObjClassName + strFieldObjectID, crim);
772 hmObjectFieldObjects = crim.getFieldObjects();
774 // Get the object and the class names
775 // Build objects for IoTSet and IoTRelation fields in the device object classes
776 // mapClassNameToCrim.put(strObjClassName + strFieldObjectID, crim);
777 // HashMap<String,Object> hmObjectFieldObjects = crim.getFieldObjects();
778 RuntimeOutput.print("IoTMaster: Going to instrument for " + strObjClassName + " with objectID " +
779 strFieldObjectID, BOOL_VERBOSE);
780 for(Map.Entry<String,Object> map : hmObjectFieldObjects.entrySet()) {
781 RuntimeOutput.print("IoTMaster: Object name: " + map.getValue().getClass().getName(), BOOL_VERBOSE);
782 // Iterate over HashMap and choose between processing
783 String strFieldName = map.getKey();
784 String strClassName = map.getValue().getClass().getName();
785 String strFieldIdentifier = strFieldName + strFieldObjectID;
786 if(strClassName.equals(STR_SET_INSTRUMENTER_CLS)) {
787 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
788 if(setInstrumenter.getObjTableName().equals(STR_IOT_DEV_ADD_CLS)) {
789 // Instrument the normal IoTDeviceAddress
790 setRouterPolicyIoTSetDevice(strFieldIdentifier, map, strIoTSlaveObjectHostAdd);
791 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ADD_CLS)) {
792 // Instrument the IoTAddress
793 setRouterPolicyIoTSetAddress(strFieldIdentifier, map, strIoTSlaveObjectHostAdd);
794 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ZB_ADD_CLS)) {
795 // Instrument the IoTZigbeeAddress - special feature for Zigbee device support
796 RuntimeOutput.print("IoTMaster: IoTZigbeeAddress found! No router policy is set here..",
799 String strErrMsg = "IoTMaster: Device driver object" +
800 " can only have IoTSet<IoTAddress>, IoTSet<IoTDeviceAddress>," +
801 " or IoTSet<IoTZigbeeAddress>!";
802 throw new Error(strErrMsg);
805 String strErrMsg = "IoTMaster: Device driver object can only have IoTSet for addresses!";
806 throw new Error(strErrMsg);
813 * A private method to send files to a Java slave driver
817 private void sendFileToJavaSlaveDriver(ServerSocket serverSocket, ObjectInputStream inStream, ObjectOutputStream outStream,
818 String strObjName, String strObjClassName, String strObjClassInterfaceName, String strObjStubClsIntfaceName,
819 String strIoTSlaveObjectHostAdd, String strFieldObjectID, Object[] arrFieldValues, Class[] arrFieldClasses)
820 throws IOException, ClassNotFoundException {
822 // Create message to transfer file first
823 String sFileName = strObjClassName + STR_JAR_FILE_EXT;
824 String sPath = STR_IOT_CODE_PATH + strObjClassName + "/" + sFileName;
825 File file = new File(sPath);
826 commMasterToSlave(new MessageSendFile(IoTCommCode.TRANSFER_FILE, sFileName, file.length()),
827 "Sending file!", inStream, outStream);
828 // Send file - JAR file for object creation
829 sendFile(serverSocket.accept(), sPath, file.length());
830 Message msgReply = (Message) inStream.readObject();
831 RuntimeOutput.print("IoTMaster: Reply message: " + msgReply.getMessage(), BOOL_VERBOSE);
832 // Pack object information to create object on a IoTSlave
833 Message msgObjIoTSlave = new MessageCreateObject(IoTCommCode.CREATE_OBJECT, strIoTSlaveObjectHostAdd,
834 strObjClassName, strObjName, strObjClassInterfaceName, strObjStubClsIntfaceName, commHan.getRMIRegPort(strObjName),
835 commHan.getRMIStubPort(strObjName), arrFieldValues, arrFieldClasses);
837 commMasterToSlave(msgObjIoTSlave, "Sending object information", inStream, outStream);
842 * A private method to create an object on a specific machine
844 * @params strObjName String object name
845 * @params strObjClassName String object class name
846 * @params strObjClassInterfaceName String object class interface name
847 * @params strIoTSlaveObjectHostAdd String IoTSlave host address
848 * @params strFieldObjectID String field object ID
849 * @params arrFieldValues Array of field values
850 * @params arrFieldClasses Array of field classes
853 private void createObject(String strObjName, String strObjClassName, String strObjClassInterfaceName, String strObjStubClsIntfaceName,
854 String strIoTSlaveObjectHostAdd, String strFieldObjectID, Object[] arrFieldValues, Class[] arrFieldClasses)
855 throws IOException, FileNotFoundException, ClassNotFoundException, InterruptedException {
862 start = System.currentTimeMillis();
864 // Construct ssh command line
865 // e.g. ssh rtrimana@dw-2.eecs.uci.edu cd <path>;
866 // java -cp $CLASSPATH:./*.jar
867 // -Djava.rmi.server.codebase=file:./*.jar
868 // iotruntime.IoTSlave dw-1.eecs.uci.edu 46151 23829 42874 &
869 // The In-Port for IoTMaster is the Out-Port for IoTSlave and vice versa
870 String strSSHCommand = STR_SSH_USERNAME + strIoTSlaveObjectHostAdd + " cd " + STR_RUNTIME_DIR + " sudo java " +
871 STR_CLS_PATH + " " + STR_RMI_PATH + " " + STR_RMI_HOSTNAME +
872 strIoTSlaveObjectHostAdd + " " + STR_IOT_SLAVE_CLS + " " + strIoTMasterHostAdd + " " +
873 commHan.getComPort(strObjName) + " " + commHan.getRMIRegPort(strObjName) + " " +
874 commHan.getRMIStubPort(strObjName) + " >& " + STR_LOG_FILE_PATH + strObjName + ".log &";
875 RuntimeOutput.print(strSSHCommand, BOOL_VERBOSE);
876 // Start a new thread to start a new JVM
877 createThread(strSSHCommand);
878 ServerSocket serverSocket = new ServerSocket(commHan.getComPort(strObjName));
879 Socket socket = serverSocket.accept();
880 ObjectInputStream inStream = new ObjectInputStream(socket.getInputStream());
881 ObjectOutputStream outStream = new ObjectOutputStream(socket.getOutputStream());
884 result = System.currentTimeMillis()-start;
885 System.out.println("\n\n ==> Time needed to start JVM for " + strObjName + ": " + result + "\n\n");
888 start = System.currentTimeMillis();
890 if(STR_LANGUAGE.equals(STR_JAVA)) {
891 sendFileToJavaSlaveDriver(serverSocket, inStream, outStream, strObjName,
892 strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName,
893 strIoTSlaveObjectHostAdd, strFieldObjectID, arrFieldValues, arrFieldClasses);
898 result = System.currentTimeMillis()-start;
899 System.out.println("\n\n ==> Time needed to send JAR file for " + strObjName + ": " + result + "\n\n");
902 start = System.currentTimeMillis();
904 // Instrument the class source code and look for IoTSet for device addresses
905 // e.g. @config private IoTSet<IoTDeviceAddress> lb_addresses;
906 RuntimeOutput.print("IoTMaster: Instantiating for " + strObjClassName + " with objectID " +
907 strFieldObjectID, BOOL_VERBOSE);
908 // Get the object and the class names
909 // Build objects for IoTSet and IoTRelation fields in the device object classes
910 Object crimObj = mapClassNameToCrim.get(strObjClassName + strFieldObjectID);
911 HashMap<String,Object> hmObjectFieldObjects = null;
912 if (crimObj instanceof ClassRuntimeInstrumenterMaster) {
913 ClassRuntimeInstrumenterMaster crim = (ClassRuntimeInstrumenterMaster) crimObj;
914 hmObjectFieldObjects = crim.getFieldObjects();
915 } else if (crimObj instanceof CRuntimeInstrumenterMaster) {
916 CRuntimeInstrumenterMaster crim = (CRuntimeInstrumenterMaster) crimObj;
917 hmObjectFieldObjects = crim.getFieldObjects();
919 for(Map.Entry<String,Object> map : hmObjectFieldObjects.entrySet()) {
920 RuntimeOutput.print("IoTMaster: Object name: " + map.getValue().getClass().getName(), BOOL_VERBOSE);
921 // Iterate over HashMap and choose between processing
922 String strFieldName = map.getKey();
923 String strClassName = map.getValue().getClass().getName();
924 String strFieldIdentifier = strFieldName + strFieldObjectID;
925 if(strClassName.equals(STR_SET_INSTRUMENTER_CLS)) {
926 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
927 if(setInstrumenter.getObjTableName().equals(STR_IOT_DEV_ADD_CLS)) {
928 // Instrument the normal IoTDeviceAddress
930 instrumentIoTSetDevice(strFieldIdentifier, strObjName, strFieldName, strIoTSlaveObjectHostAdd, inStream, outStream);
932 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ZB_ADD_CLS)) {
933 // Instrument the IoTZigbeeAddress - special feature for Zigbee device support
935 instrumentIoTSetZBDevice(map, strObjName, strFieldName, strIoTSlaveObjectHostAdd, inStream, outStream);
937 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ADD_CLS)) {
938 // Instrument the IoTAddress
940 instrumentIoTSetAddress(strFieldIdentifier, strFieldName, inStream, outStream);
943 String strErrMsg = "IoTMaster: Device driver object" +
944 " can only have IoTSet<IoTAddress>, IoTSet<IoTDeviceAddress>," +
945 " or IoTSet<IoTZigbeeAddress>!";
946 throw new Error(strErrMsg);
949 String strErrMsg = "IoTMaster: Device driver object can only have IoTSet for addresses!";
950 throw new Error(strErrMsg);
954 // TODO: Change this later
956 if(STR_LANGUAGE.equals(STR_JAVA))
957 outStream.writeObject(new MessageSimple(IoTCommCode.END_SESSION));
962 result = System.currentTimeMillis()-start;
963 System.out.println("\n\n ==> Time needed to create object " + strObjName + " and instrument IoTDeviceAddress: " + result + "\n\n");
969 serverSocket.close();
974 * A private method to create controller objects
978 private void createControllerObjects() throws InterruptedException {
980 // Create a list of threads
981 List<Thread> threads = new ArrayList<Thread>();
982 // Get the list of active controller objects and loop it
983 List<String> listActiveControllerObject = commHan.getActiveControllerObjectList();
984 for(String strObjName : listActiveControllerObject) {
986 ObjectCreationInfo objCrtInfo = commHan.getObjectCreationInfo(strObjName);
987 Thread objectThread = new Thread(new Runnable() {
991 createObject(strObjName, objCrtInfo.getObjectClassName(), objCrtInfo.getObjectClassInterfaceName(),
992 objCrtInfo.getObjectStubClassInterfaceName(), objCrtInfo.getIoTSlaveObjectHostAdd(),
993 commHan.getFieldObjectID(strObjName), commHan.getArrayFieldValues(strObjName),
994 commHan.getArrayFieldClasses(strObjName));
995 } catch (IOException |
996 ClassNotFoundException |
997 InterruptedException ex) {
998 ex.printStackTrace();
1003 threads.add(objectThread);
1004 objectThread.start();
1007 for (Thread thread : threads) {
1010 } catch (InterruptedException ex) {
1011 ex.printStackTrace();
1018 * A private method to instrument IoTSet
1020 * @params Map.Entry<String,Object> Entry of map IoTSet instrumentation
1021 * @params strFieldName String field name
1024 private void instrumentIoTSet(Map.Entry<String,Object> map, String strFieldName)
1025 throws IOException, ClassNotFoundException, InterruptedException {
1027 // Get information from the set
1028 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
1029 objInitHand.addField(strFieldName, IoTCommCode.CREATE_NEW_IOTSET);
1031 int iRows = setInstrumenter.numberOfRows();
1032 for(int iRow=0; iRow<iRows; iRow++) {
1033 // Get field classes and values
1034 arrFieldClasses = setInstrumenter.fieldClasses(iRow);
1035 arrFieldValues = setInstrumenter.fieldValues(iRow);
1036 // Get object ID and class name
1037 String strObjID = setInstrumenter.fieldObjectID(iRow);
1038 strObjClassName = setInstrumenter.fieldEntryType(strObjID);
1039 // Call the method to create an object
1040 instrumentObject(strObjID);
1041 int iNumOfPorts = Integer.parseInt(STR_NUM_CALLBACK_PORTS);
1042 objInitHand.addObjectIntoField(strFieldName, strIoTSlaveObjectHostAdd, strObjName,
1043 strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName, commHan.getRMIRegPort(strObjName),
1044 commHan.getRMIStubPort(strObjName), commHan.getCallbackPorts(strObjName, iNumOfPorts));
1050 * A private method to instrument IoTRelation
1052 * @params Map.Entry<String,Object> Entry of map IoTRelation instrumentation
1053 * @params strFieldName String field name
1056 private void instrumentIoTRelation(Map.Entry<String,Object> map, String strFieldName)
1057 throws IOException, ClassNotFoundException, InterruptedException {
1059 // Get information from the set
1060 RelationInstrumenter relationInstrumenter = (RelationInstrumenter) map.getValue();
1061 int iRows = relationInstrumenter.numberOfRows();
1062 objInitHand.addField(strFieldName, IoTCommCode.CREATE_NEW_IOTRELATION);
1064 for(int iRow=0; iRow<iRows; iRow++) {
1065 // Operate on the first set first
1066 arrFieldClasses = relationInstrumenter.firstFieldClasses(iRow);
1067 arrFieldValues = relationInstrumenter.firstFieldValues(iRow);
1068 String strObjID = relationInstrumenter.firstFieldObjectID(iRow);
1069 strObjClassName = relationInstrumenter.firstEntryFieldType(strObjID);
1070 // Call the method to create an object
1071 instrumentObject(strObjID);
1072 // Get the first object controller host address
1073 String strFirstIoTSlaveObjectHostAdd = strIoTSlaveObjectHostAdd;
1074 int iNumOfPorts = Integer.parseInt(STR_NUM_CALLBACK_PORTS);
1075 objInitHand.addObjectIntoField(strFieldName, strIoTSlaveObjectHostAdd, strObjName,
1076 strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName,
1077 commHan.getRMIRegPort(strObjName), commHan.getRMIStubPort(strObjName),
1078 commHan.getCallbackPorts(strObjName, iNumOfPorts));
1079 // Operate on the second set
1080 arrFieldClasses = relationInstrumenter.secondFieldClasses(iRow);
1081 arrFieldValues = relationInstrumenter.secondFieldValues(iRow);
1082 strObjID = relationInstrumenter.secondFieldObjectID(iRow);
1083 strObjClassName = relationInstrumenter.secondEntryFieldType(strObjID);
1084 // Call the method to create an object
1085 instrumentObject(strObjID);
1086 // Get the second object controller host address
1087 String strSecondIoTSlaveObjectHostAdd = strIoTSlaveObjectHostAdd;
1088 objInitHand.addSecondObjectIntoField(strFieldName, strIoTSlaveObjectHostAdd, strObjName,
1089 strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName,
1090 commHan.getRMIRegPort(strObjName), commHan.getRMIStubPort(strObjName),
1091 commHan.getCallbackPorts(strObjName, iNumOfPorts));
1092 // ROUTING POLICY: first and second controller objects in IoTRelation
1093 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strFirstIoTSlaveObjectHostAdd,
1094 strSecondIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
1095 // ROUTING POLICY: Send the same routing policy to both the hosts
1096 routerConfig.configureHostMainPolicies(strFirstIoTSlaveObjectHostAdd, strFirstIoTSlaveObjectHostAdd,
1097 strSecondIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
1098 routerConfig.configureHostMainPolicies(strSecondIoTSlaveObjectHostAdd, strFirstIoTSlaveObjectHostAdd,
1099 strSecondIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
1104 * A method to reinitialize IoTSet and IoTRelation in the code based on ObjectInitHandler information
1106 * @params inStream ObjectInputStream communication
1107 * @params outStream ObjectOutputStream communication
1110 private void initializeSetsAndRelationsJava(ObjectInputStream inStream, ObjectOutputStream outStream)
1111 throws IOException, ClassNotFoundException {
1112 // Get list of fields
1113 List<String> strFields = objInitHand.getListOfFields();
1114 // Iterate on HostAddress
1115 for(String str : strFields) {
1116 IoTCommCode iotcommMsg = objInitHand.getFieldMessage(str);
1117 if (iotcommMsg == IoTCommCode.CREATE_NEW_IOTSET) {
1118 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO CREATE IOTSET
1119 Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, str);
1120 commMasterToSlave(msgCrtIoTSet, "Create new IoTSet!", inStream, outStream);
1121 List<ObjectInitInfo> listObject = objInitHand.getListObjectInitInfo(str);
1122 for (ObjectInitInfo objInitInfo : listObject) {
1123 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTSET
1124 commMasterToSlave(new MessageGetObject(IoTCommCode.GET_IOTSET_OBJECT, objInitInfo.getIoTSlaveObjectHostAdd(),
1125 objInitInfo.getObjectName(), objInitInfo.getObjectClassName(), objInitInfo.getObjectClassInterfaceName(),
1126 objInitInfo.getObjectStubClassInterfaceName(), objInitInfo.getRMIRegistryPort(), objInitInfo.getRMIStubPort(),
1127 objInitInfo.getRMICallbackPorts()), "Get IoTSet object!", inStream, outStream);
1130 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO REINITIALIZE IOTSET FIELD
1131 commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTSET_FIELD),
1132 "Renitialize IoTSet field!", inStream, outStream);
1133 } else if (iotcommMsg == IoTCommCode.CREATE_NEW_IOTRELATION) {
1134 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO CREATE IOTRELATION
1135 Message msgCrtIoTRel = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTRELATION, str);
1136 commMasterToSlave(msgCrtIoTRel, "Create new IoTRelation!", inStream, outStream);
1137 List<ObjectInitInfo> listObject = objInitHand.getListObjectInitInfo(str);
1138 List<ObjectInitInfo> listSecondObject = objInitHand.getSecondObjectInitInfo(str);
1139 Iterator it = listSecondObject.iterator();
1140 for (ObjectInitInfo objInitInfo : listObject) {
1141 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTRELATION (FIRST OBJECT)
1142 commMasterToSlave(new MessageGetObject(IoTCommCode.GET_IOTRELATION_FIRST_OBJECT,
1143 objInitInfo.getIoTSlaveObjectHostAdd(), objInitInfo.getObjectName(), objInitInfo.getObjectClassName(),
1144 objInitInfo.getObjectClassInterfaceName(), objInitInfo.getObjectStubClassInterfaceName(),
1145 objInitInfo.getRMIRegistryPort(), objInitInfo.getRMIStubPort(), objInitInfo.getRMICallbackPorts()),
1146 "Get IoTRelation first object!", inStream, outStream);
1147 ObjectInitInfo objSecObj = (ObjectInitInfo) it.next();
1148 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTRELATION (SECOND OBJECT)
1149 commMasterToSlave(new MessageGetObject(IoTCommCode.GET_IOTRELATION_SECOND_OBJECT,
1150 objSecObj.getIoTSlaveObjectHostAdd(), objSecObj.getObjectName(), objSecObj.getObjectClassName(),
1151 objSecObj.getObjectClassInterfaceName(), objSecObj.getObjectStubClassInterfaceName(),
1152 objSecObj.getRMIRegistryPort(), objSecObj.getRMIStubPort(), objSecObj.getRMICallbackPorts()),
1153 "Get IoTRelation second object!", inStream, outStream);
1155 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO REINITIALIZE IOTRELATION FIELD
1156 commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTRELATION_FIELD),
1157 "Renitialize IoTRelation field!", inStream, outStream);
1163 * A method to reinitialize IoTSet and IoTRelation in the code based on ObjectInitHandler information
1165 * @params inStream ObjectInputStream communication
1166 * @params outStream ObjectOutputStream communication
1169 private void initializeSetsAndRelationsCpp(ObjectInputStream inStream, ObjectOutputStream outStream)
1170 throws IOException, ClassNotFoundException {
1171 // Get list of fields
1172 List<String> strFields = objInitHand.getListOfFields();
1173 // Iterate on HostAddress
1174 for(String str : strFields) {
1175 IoTCommCode iotcommMsg = objInitHand.getFieldMessage(str);
1176 if (iotcommMsg == IoTCommCode.CREATE_NEW_IOTSET) {
1177 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO CREATE IOTSET
1178 Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, str);
1179 commMasterToSlave(msgCrtIoTSet, "Create new IoTSet!", inStream, outStream);
1180 List<ObjectInitInfo> listObject = objInitHand.getListObjectInitInfo(str);
1181 for (ObjectInitInfo objInitInfo : listObject) {
1182 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTSET
1183 commMasterToSlave(new MessageGetObject(IoTCommCode.GET_IOTSET_OBJECT, objInitInfo.getIoTSlaveObjectHostAdd(),
1184 objInitInfo.getObjectName(), objInitInfo.getObjectClassName(), objInitInfo.getObjectClassInterfaceName(),
1185 objInitInfo.getObjectStubClassInterfaceName(), objInitInfo.getRMIRegistryPort(), objInitInfo.getRMIStubPort(),
1186 objInitInfo.getRMICallbackPorts()), "Get IoTSet object!", inStream, outStream);
1189 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO REINITIALIZE IOTSET FIELD
1190 commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTSET_FIELD),
1191 "Renitialize IoTSet field!", inStream, outStream);
1192 } else if (iotcommMsg == IoTCommCode.CREATE_NEW_IOTRELATION) {
1193 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO CREATE IOTRELATION
1194 Message msgCrtIoTRel = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTRELATION, str);
1195 commMasterToSlave(msgCrtIoTRel, "Create new IoTRelation!", inStream, outStream);
1196 List<ObjectInitInfo> listObject = objInitHand.getListObjectInitInfo(str);
1197 List<ObjectInitInfo> listSecondObject = objInitHand.getSecondObjectInitInfo(str);
1198 Iterator it = listSecondObject.iterator();
1199 for (ObjectInitInfo objInitInfo : listObject) {
1200 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTRELATION (FIRST OBJECT)
1201 commMasterToSlave(new MessageGetObject(IoTCommCode.GET_IOTRELATION_FIRST_OBJECT,
1202 objInitInfo.getIoTSlaveObjectHostAdd(), objInitInfo.getObjectName(), objInitInfo.getObjectClassName(),
1203 objInitInfo.getObjectClassInterfaceName(), objInitInfo.getObjectStubClassInterfaceName(),
1204 objInitInfo.getRMIRegistryPort(), objInitInfo.getRMIStubPort(), objInitInfo.getRMICallbackPorts()),
1205 "Get IoTRelation first object!", inStream, outStream);
1206 ObjectInitInfo objSecObj = (ObjectInitInfo) it.next();
1207 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTRELATION (SECOND OBJECT)
1208 commMasterToSlave(new MessageGetObject(IoTCommCode.GET_IOTRELATION_SECOND_OBJECT,
1209 objSecObj.getIoTSlaveObjectHostAdd(), objSecObj.getObjectName(), objSecObj.getObjectClassName(),
1210 objSecObj.getObjectClassInterfaceName(), objSecObj.getObjectStubClassInterfaceName(),
1211 objSecObj.getRMIRegistryPort(), objSecObj.getRMIStubPort(), objSecObj.getRMICallbackPorts()),
1212 "Get IoTRelation second object!", inStream, outStream);
1214 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO REINITIALIZE IOTRELATION FIELD
1215 commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTRELATION_FIELD),
1216 "Renitialize IoTRelation field!", inStream, outStream);
1222 * A method to set router basic policies at once
1224 * @param strRouter String router name
1227 private void setRouterBasicPolicies(String strRouter) {
1229 String strMonitorHost = routerConfig.getIPFromMACAddress(STR_MONITORING_HOST);
1230 routerConfig.configureRouterICMPPolicies(strRouter, strMonitorHost);
1231 routerConfig.configureRouterDHCPPolicies(strRouter);
1232 routerConfig.configureRouterDNSPolicies(strRouter);
1233 routerConfig.configureRouterSSHPolicies(strRouter, strMonitorHost);
1234 routerConfig.configureRejectPolicies(strRouter);
1238 * A method to set host basic policies at once
1240 * @param strHost String host name
1243 private void setHostBasicPolicies(String strHost) {
1245 String strMonitorHost = routerConfig.getIPFromMACAddress(STR_MONITORING_HOST);
1246 routerConfig.configureHostDHCPPolicies(strHost);
1247 routerConfig.configureHostDNSPolicies(strHost);
1248 if (strHost.equals(strMonitorHost)) {
1249 // Check if this is the monitoring host
1250 routerConfig.configureHostICMPPolicies(strHost);
1251 routerConfig.configureHostSSHPolicies(strHost);
1253 routerConfig.configureHostICMPPolicies(strHost, strMonitorHost);
1254 routerConfig.configureHostSSHPolicies(strHost, strMonitorHost);
1256 // Apply SQL allowance policies to master host
1257 if (strHost.equals(strIoTMasterHostAdd)) {
1258 routerConfig.configureHostSQLPolicies(strHost);
1260 routerConfig.configureRejectPolicies(strHost);
1264 * A method to create a thread for policy deployment
1266 * @param strRouterAddress String router address to configure
1267 * @param setHostAddresses Set of strings for host addresses to configure
1270 private void createPolicyThreads(String strRouterAddress, Set<String> setHostAddresses) throws IOException {
1272 // Create a list of threads
1273 List<Thread> threads = new ArrayList<Thread>();
1274 // Start threads for hosts
1275 for(String strAddress : setHostAddresses) {
1276 Thread policyThread = new Thread(new Runnable() {
1278 synchronized(this) {
1279 routerConfig.sendHostPolicies(strAddress);
1283 threads.add(policyThread);
1284 policyThread.start();
1285 RuntimeOutput.print("Deploying policies for: " + strAddress, BOOL_VERBOSE);
1287 // A thread for router
1288 Thread policyThread = new Thread(new Runnable() {
1290 synchronized(this) {
1291 routerConfig.sendRouterPolicies(strRouterAddress);
1295 threads.add(policyThread);
1296 policyThread.start();
1297 RuntimeOutput.print("Deploying policies on router: " + strRouterAddress, BOOL_VERBOSE);
1299 for (Thread thread : threads) {
1302 } catch (InterruptedException ex) {
1303 ex.printStackTrace();
1309 * A method to send files to Java IoTSlave
1313 private void sendFileToJavaSlave(String strObjControllerName, ServerSocket serverSocket,
1314 ObjectInputStream inStream, ObjectOutputStream outStream) throws IOException, ClassNotFoundException {
1317 String strControllerJarName = strObjControllerName + STR_JAR_FILE_EXT;
1318 String strControllerJarNamePath = STR_CONT_PATH + strObjControllerName + "/" +
1319 strControllerJarName;
1320 File file = new File(strControllerJarNamePath);
1321 commMasterToSlave(new MessageSendFile(IoTCommCode.TRANSFER_FILE, strControllerJarName, file.length()),
1322 "Sending file!", inStream, outStream);
1323 // Send file - Class file for object creation
1324 sendFile(serverSocket.accept(), strControllerJarNamePath, file.length());
1325 Message msgReply = (Message) inStream.readObject();
1326 RuntimeOutput.print("IoTMaster: Reply message: " + msgReply.getMessage(), BOOL_VERBOSE);
1327 // Send .zip file if additional zip file is specified
1328 String strObjCfgFile = strObjControllerName + STR_CFG_FILE_EXT;
1329 String strObjCfgFilePath = STR_CONT_PATH + strObjControllerName + "/" + strObjCfgFile;
1330 String strAdditionalFile = parseConfigFile(strObjCfgFilePath, STR_FILE_TRF_CFG);
1331 if (strAdditionalFile.equals(STR_YES)) {
1332 String strControllerCmpName = strObjControllerName + STR_ZIP_FILE_EXT;
1333 String strControllerCmpNamePath = STR_CONT_PATH + strObjControllerName + "/" +
1334 strControllerCmpName;
1335 file = new File(strControllerCmpNamePath);
1336 commMasterToSlave(new MessageSendFile(IoTCommCode.TRANSFER_FILE, strControllerCmpName, file.length()),
1337 "Sending file!", inStream, outStream);
1338 // Send file - Class file for object creation
1339 sendFile(serverSocket.accept(), strControllerCmpNamePath, file.length());
1340 msgReply = (Message) inStream.readObject();
1341 RuntimeOutput.print("IoTMaster: Reply message: " + msgReply.getMessage(), BOOL_VERBOSE);
1347 * A method to assign objects to multiple JVMs, including
1348 * the controller/device object that uses other objects
1349 * in IoTSet and IoTRelation
1353 private void createObjects() {
1360 // Extract hostname for this IoTMaster from MySQL DB
1361 strIoTMasterHostAdd = routerConfig.getIPFromMACAddress(STR_MASTER_MAC_ADD);
1362 // Loop as we can still find controller/device classes
1363 for(int i=0; i<strObjectNames.length; i++) {
1365 start = System.currentTimeMillis();
1367 // Assign a new list of PrintWriter objects
1368 routerConfig.renewPrintWriter();
1369 // Get controller names one by one
1370 String strObjControllerName = strObjectNames[i];
1371 // Use LoadBalancer to assign a host address
1372 //strIoTSlaveControllerHostAdd = lbIoT.selectHost();
1373 strIoTSlaveControllerHostAdd = routerConfig.getIPFromMACAddress(lbIoT.selectHost());
1374 if (strIoTSlaveControllerHostAdd == null)
1375 throw new Error("IoTMaster: Could not translate MAC to IP address! Please check the router's /tmp/dhcp.leases!");
1376 // == START INITIALIZING CONTROLLER/DEVICE IOTSLAVE ==
1377 // Add port connection and get port numbers
1378 // Naming for objects ProximitySensor becomes ProximitySensor0, ProximitySensor1, etc.
1379 commHan.addPortConnection(strIoTSlaveControllerHostAdd, strObjControllerName);
1380 // ROUTING POLICY: IoTMaster and main controller object
1381 routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTMasterHostAdd,
1382 strIoTSlaveControllerHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjControllerName));
1383 // ROUTING POLICY: Send the same routing policy to both the hosts
1384 routerConfig.configureHostMainPolicies(strIoTMasterHostAdd, strIoTMasterHostAdd,
1385 strIoTSlaveControllerHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjControllerName));
1386 routerConfig.configureHostMainPolicies(strIoTSlaveControllerHostAdd, strIoTMasterHostAdd,
1387 strIoTSlaveControllerHostAdd, STR_TCP_PROTOCOL, commHan.getComPort(strObjControllerName));
1389 // Construct ssh command line and create a controller thread for e.g. AcmeProximity
1390 String strSSHCommand = STR_SSH_USERNAME + strIoTSlaveControllerHostAdd + " cd " +
1391 STR_RUNTIME_DIR + " sudo java " + STR_JVM_INIT_HEAP_SIZE + " " +
1392 STR_JVM_MAX_HEAP_SIZE + " " + STR_CLS_PATH + " " +
1393 STR_RMI_PATH + " " + STR_IOT_SLAVE_CLS + " " + strIoTMasterHostAdd + " " +
1394 commHan.getComPort(strObjControllerName) + " " +
1395 commHan.getRMIRegPort(strObjControllerName) + " " +
1396 commHan.getRMIStubPort(strObjControllerName) + " >& " +
1397 STR_LOG_FILE_PATH + strObjControllerName + ".log &";
1398 RuntimeOutput.print(strSSHCommand, BOOL_VERBOSE);
1399 createThread(strSSHCommand);
1400 // Wait for connection
1401 // Create a new socket for communication
1402 ServerSocket serverSocket = new ServerSocket(commHan.getComPort(strObjControllerName));
1403 Socket socket = serverSocket.accept();
1404 ObjectInputStream inStream = new ObjectInputStream(socket.getInputStream());
1405 ObjectOutputStream outStream = new ObjectOutputStream(socket.getOutputStream());
1406 RuntimeOutput.print("IoTMaster: Communication established!", BOOL_VERBOSE);
1409 result = System.currentTimeMillis()-start;
1410 System.out.println("\n\n ==> From start until after SSH for main controller: " + result);
1412 start = System.currentTimeMillis();
1414 // Send files for every controller class
1415 // e.g. AcmeProximity.jar and AcmeProximity.zip
1416 String strControllerClassName = strObjControllerName + STR_CLS_FILE_EXT;
1417 String strControllerClassNamePath = STR_CONT_PATH + strObjControllerName + "/" +
1418 strControllerClassName;
1420 if(STR_LANGUAGE.equals(STR_JAVA)) {
1421 sendFileToJavaSlave(strObjControllerName, serverSocket, inStream, outStream);
1422 // Create main controller/device object
1423 commMasterToSlave(new MessageCreateMainObject(IoTCommCode.CREATE_MAIN_OBJECT, strObjControllerName),
1424 "Create main object!", inStream, outStream);
1425 } else if(STR_LANGUAGE.equals(STR_CPP))
1428 throw new Error("IoTMaster: Language specification not recognized: " + STR_LANGUAGE);
1431 result = System.currentTimeMillis()-start;
1432 System.out.println("\n\n ==> From IoTSlave start until main controller object is created: " + result);
1433 System.out.println(" ==> Including file transfer times!\n\n");
1435 start = System.currentTimeMillis();
1437 // == END INITIALIZING CONTROLLER/DEVICE IOTSLAVE ==
1438 // Instrumenting one file
1439 RuntimeOutput.print("IoTMaster: Opening class file: " + strControllerClassName, BOOL_VERBOSE);
1440 RuntimeOutput.print("IoTMaster: Class file path: " + strControllerClassNamePath, BOOL_VERBOSE);
1441 HashMap<String,Object> hmControllerFieldObjects = null;
1442 if(STR_LANGUAGE.equals(STR_JAVA)) {
1443 FileInputStream fis = new FileInputStream(strControllerClassNamePath);
1444 ClassReader cr = new ClassReader(fis);
1445 ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
1446 ClassRuntimeInstrumenterMaster crim = new ClassRuntimeInstrumenterMaster(cw, null, BOOL_VERBOSE);
1449 hmControllerFieldObjects = crim.getFieldObjects();
1451 String strControllerConfigFile = STR_CONT_PATH + strObjControllerName + "/" + strObjControllerName + STR_CFG_FILE_EXT;
1452 CRuntimeInstrumenterMaster crim = new CRuntimeInstrumenterMaster(strControllerConfigFile, null, BOOL_VERBOSE);
1453 hmControllerFieldObjects = crim.getFieldObjects();
1455 // Get the object and the class names
1456 // Build objects for IoTSet and IoTRelation fields in the controller/device classes
1457 //HashMap<String,Object> hmControllerFieldObjects = crim.getFieldObjects();
1458 for(Map.Entry<String,Object> map : hmControllerFieldObjects.entrySet()) {
1459 RuntimeOutput.print("IoTMaster: Object name: " + map.getValue().getClass().getName(), BOOL_VERBOSE);
1460 // Iterate over HashMap and choose between processing
1461 // SetInstrumenter vs. RelationInstrumenter
1462 String strFieldName = map.getKey();
1463 String strClassName = map.getValue().getClass().getName();
1464 if(strClassName.equals(STR_SET_INSTRUMENTER_CLS)) {
1465 SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
1466 if(setInstrumenter.getObjTableName().equals(STR_IOT_DEV_ADD_CLS)) {
1467 String strErrMsg = "IoTMaster: Controller object" +
1468 " cannot have IoTSet<IoTDeviceAddress>!";
1469 throw new Error(strErrMsg);
1470 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ZB_ADD_CLS)) {
1471 String strErrMsg = "IoTMaster: Controller object" +
1472 " cannot have IoTSet<ZigbeeAddress>!";
1473 throw new Error(strErrMsg);
1474 } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ADD_CLS)) {
1475 // Instrument the IoTAddress
1476 setRouterPolicyIoTSetAddress(strFieldName, map, strIoTSlaveControllerHostAdd);
1477 instrumentIoTSetAddress(strFieldName, strFieldName, inStream, outStream);
1480 instrumentIoTSet(map, strFieldName);
1482 } else if (strClassName.equals(STR_REL_INSTRUMENTER_CLS)) {
1483 instrumentIoTRelation(map, strFieldName);
1487 result = System.currentTimeMillis()-start;
1488 System.out.println("\n\n ==> Time needed to instrument device driver objects: " + result + "\n\n");
1489 System.out.println(" ==> #Objects: " + commHan.getActiveControllerObjectList().size() + "\n\n");
1492 start = System.currentTimeMillis();
1494 // ROUTING POLICY: Deploy basic policies if this is the last controller
1495 if (i == strObjectNames.length-1) {
1496 // ROUTING POLICY: implement basic policies to reject all other irrelevant traffics
1497 for(String s: commHan.getHosts()) {
1498 setHostBasicPolicies(s);
1500 // We retain all the basic policies for router,
1501 // but we delete the initial allowance policies for internal all TCP and UDP communications
1502 setRouterBasicPolicies(STR_ROUTER_ADD);
1504 // Close access to policy files and deploy policies
1505 routerConfig.close();
1506 // Deploy the policy
1507 HashSet<String> setAddresses = new HashSet<String>(commHan.getHosts());
1508 setAddresses.add(strIoTMasterHostAdd);
1509 createPolicyThreads(STR_ROUTER_ADD, setAddresses);
1512 result = System.currentTimeMillis()-start;
1513 System.out.println("\n\n ==> Time needed to send policy files and deploy them : " + result + "\n\n");
1516 start = System.currentTimeMillis();
1518 // Separating object creations and Set/Relation initializations
1519 createControllerObjects();
1522 result = System.currentTimeMillis()-start;
1523 System.out.println("\n\n ==> Time needed to instantiate objects: " + result + "\n\n");
1525 start = System.currentTimeMillis();
1527 // Sets and relations initializations
1528 if(STR_LANGUAGE.equals(STR_JAVA))
1529 initializeSetsAndRelationsJava(inStream, outStream);
1534 result = System.currentTimeMillis()-start;
1535 System.out.println("\n\n ==> Time needed to initialize sets and relations: " + result + "\n\n");
1537 if(STR_LANGUAGE.equals(STR_JAVA))
1538 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO EXECUTE INIT METHOD
1539 commMasterToSlave(new MessageSimple(IoTCommCode.INVOKE_INIT_METHOD),
1540 "Invoke init() method!", inStream, outStream);
1543 // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO END PROCESS
1544 if(STR_LANGUAGE.equals(STR_JAVA))
1545 outStream.writeObject(new MessageSimple(IoTCommCode.END_SESSION));
1551 serverSocket.close();
1552 commHan.printLists();
1553 lbIoT.printHostInfo();
1556 } catch (IOException |
1557 InterruptedException |
1558 ClassNotFoundException ex) {
1559 System.out.println("IoTMaster: Exception: "
1561 ex.printStackTrace();
1565 public static void main(String args[]) {
1567 // Detect the available controller/device classes
1568 // Input args[] should be used to list the controllers/devices
1569 // e.g. java IoTMaster AcmeProximity AcmeThermostat AcmeVentController
1570 IoTMaster iotMaster = new IoTMaster(args);
1572 iotMaster.parseIoTMasterConfigFile();
1573 // Initialize CommunicationHandler, LoadBalancer, and RouterConfig
1574 iotMaster.initLiveDataStructure();
1576 iotMaster.createObjects();