From 92a72956d7da4e864057ff4a8e5a91f1bddaf552 Mon Sep 17 00:00:00 2001 From: rtrimana Date: Thu, 19 Jan 2017 11:25:34 -0800 Subject: [PATCH] Adding C++ field instrumentation using config file --- benchmarks/Cpp/Lifxtest/Lifxtest.config | 6 + benchmarks/Java/Lifxtest/Lifxtest.config | 6 + .../Cpp/LifxLightBulb/LifxLightBulb.config | 5 + .../Java/LifxLightBulb/LifxLightBulb.config | 5 + .../master/CRuntimeInstrumenterMaster.java | 134 +++++++ iotjava/iotruntime/master/IoTMaster.java | 376 +++++++++++++----- localconfig/iotruntime/IoTMaster.config | 3 + 7 files changed, 433 insertions(+), 102 deletions(-) create mode 100644 iotjava/iotruntime/master/CRuntimeInstrumenterMaster.java diff --git a/benchmarks/Cpp/Lifxtest/Lifxtest.config b/benchmarks/Cpp/Lifxtest/Lifxtest.config index 5a44766..39b3a38 100644 --- a/benchmarks/Cpp/Lifxtest/Lifxtest.config +++ b/benchmarks/Cpp/Lifxtest/Lifxtest.config @@ -1 +1,7 @@ ADDITIONAL_ZIP_FILE=No + +# For C++ instrumentation +FIELD_NUMBER=1 +FIELD_0=lifx_light_bulb +FIELD_CLASS_0=LightBulbTest +FIELD_TYPE_0=IoTSet diff --git a/benchmarks/Java/Lifxtest/Lifxtest.config b/benchmarks/Java/Lifxtest/Lifxtest.config index 5a44766..39b3a38 100644 --- a/benchmarks/Java/Lifxtest/Lifxtest.config +++ b/benchmarks/Java/Lifxtest/Lifxtest.config @@ -1 +1,7 @@ ADDITIONAL_ZIP_FILE=No + +# For C++ instrumentation +FIELD_NUMBER=1 +FIELD_0=lifx_light_bulb +FIELD_CLASS_0=LightBulbTest +FIELD_TYPE_0=IoTSet diff --git a/benchmarks/drivers/Cpp/LifxLightBulb/LifxLightBulb.config b/benchmarks/drivers/Cpp/LifxLightBulb/LifxLightBulb.config index fa88933..aed4665 100644 --- a/benchmarks/drivers/Cpp/LifxLightBulb/LifxLightBulb.config +++ b/benchmarks/drivers/Cpp/LifxLightBulb/LifxLightBulb.config @@ -4,3 +4,8 @@ INTERFACE_CLASS=LightBulb #INTERFACE_STUB_CLASS=LightBulbTest INTERFACE_STUB_CLASS=LightBulbSmart +# For C++ instrumentation +FIELD_NUMBER=1 +FIELD_0=lb_addresses +FIELD_CLASS_0=IoTDeviceAddress +FIELD_TYPE_0=IoTSet diff --git a/benchmarks/drivers/Java/LifxLightBulb/LifxLightBulb.config b/benchmarks/drivers/Java/LifxLightBulb/LifxLightBulb.config index fa88933..aed4665 100644 --- a/benchmarks/drivers/Java/LifxLightBulb/LifxLightBulb.config +++ b/benchmarks/drivers/Java/LifxLightBulb/LifxLightBulb.config @@ -4,3 +4,8 @@ INTERFACE_CLASS=LightBulb #INTERFACE_STUB_CLASS=LightBulbTest INTERFACE_STUB_CLASS=LightBulbSmart +# For C++ instrumentation +FIELD_NUMBER=1 +FIELD_0=lb_addresses +FIELD_CLASS_0=IoTDeviceAddress +FIELD_TYPE_0=IoTSet diff --git a/iotjava/iotruntime/master/CRuntimeInstrumenterMaster.java b/iotjava/iotruntime/master/CRuntimeInstrumenterMaster.java new file mode 100644 index 0000000..ed0c156 --- /dev/null +++ b/iotjava/iotruntime/master/CRuntimeInstrumenterMaster.java @@ -0,0 +1,134 @@ +package iotruntime.master; + +// Java basic packages +import java.util.*; +import java.io.*; + +/** Class CRuntimeInstrumenterMaster helps instrument C++ code. + * This class basically reads a C++ config file that has information + * about fields of IoTSet and IoTRelation. + * + * @author Rahmadi Trimananda + * @version 1.0 + * @since 2017-19-01 + */ +public class CRuntimeInstrumenterMaster { + + /** + * CRuntimeInstrumenterMaster class constants + */ + private static final String STR_IOT_SET_TYPE = "IoTSet"; + private static final String STR_IOT_RELATION_TYPE = "IoTRelation"; + private static final String STR_FIELD_NUMBER = "FIELD_NUMBER"; + private static final String STR_FIELD = "FIELD_"; + private static final String STR_FIELD_CLASS = "FIELD_CLASS_"; + // For IoTRelation second object class + private static final String STR_FIELD_CLASS_REL = "FIELD_CLASS_REL_"; + private static final String STR_FIELD_TYPE = "FIELD_TYPE_"; + private static final String STR_CONFIG_EXTENSION = ".config"; + private static final String STR_CONFIG_FILE_PATH = "mysql/"; + + /** + * CRuntimeInstrumenterMaster class properties + */ + private HashMap hmObj; + private String strObjectID; + private boolean bVerbose; + private String strObjectConfigFile; + + /** + * Constructor + */ + public CRuntimeInstrumenterMaster(String strConfigFile, String strObjID, boolean _bVerbose) { + + hmObj = new HashMap(); + strObjectID = strObjID; + bVerbose = _bVerbose; + strObjectConfigFile = strConfigFile; + } + + + /** + * A method to parse information from a config file + * + * @param strCfgFileName Config file name + * @param strCfgField Config file field name + * @return String + */ + private String parseConfigFile(String strCfgFileName, String strCfgField) { + // Parse configuration file + Properties prop = new Properties(); + File file = new File(strCfgFileName); + FileInputStream fis = null; + try { + fis = new FileInputStream(file); + prop.load(fis); + fis.close(); + } catch (IOException ex) { + System.out.println("CRuntimeInstrumenterMaster: Error reading config file: " + strCfgFileName + + ". Please make sure it contains field information!"); + ex.printStackTrace(); + } + System.out.println("CRuntimeInstrumenterMaster: Reading " + strCfgField + + " from config file: " + strCfgFileName + " with value: " + + prop.getProperty(strCfgField, null)); + // NULL is returned if the property isn't found + return prop.getProperty(strCfgField, null); + } + + + /** + * A method to parse field information + * + * @return void + */ + private void getFieldInfo() { + + // Parse the config file and look for field information + String strFieldNum = parseConfigFile(strObjectConfigFile, STR_FIELD_NUMBER); + int iNumOfField = 0; + if (strFieldNum != null) + iNumOfField = Integer.parseInt(strFieldNum); + else + throw new Error("CRuntimeInstrumenterMaster: Number of fields information not found!"); + for (int iFieldCounter=0; iFieldCounter + */ + public HashMap getFieldObjects() { + + getFieldInfo(); + return hmObj; + } + +} + + diff --git a/iotjava/iotruntime/master/IoTMaster.java b/iotjava/iotruntime/master/IoTMaster.java index 1f7e697..5406e47 100644 --- a/iotjava/iotruntime/master/IoTMaster.java +++ b/iotjava/iotruntime/master/IoTMaster.java @@ -52,7 +52,9 @@ public class IoTMaster { private ObjectInitHandler objInitHand; private ObjectAddressInitHandler objAddInitHand; private String[] strObjectNames; - private Map mapClassNameToCrim; + // Now this can be either ClassRuntimeInstrumenterMaster or CRuntimeInstrumenterMaster + private Map mapClassNameToCrim; + /** * These properties hold information of a certain object * at a certain time @@ -68,6 +70,14 @@ public class IoTMaster { private Object[] arrFieldValues; private Socket filesocket; + /** + * For connection with C++ IoTSlave + */ + private ServerSocket serverSocketCpp; + private Socket socketCpp; + private BufferedInputStream inputCpp; + private BufferedOutputStream outputCpp; + // Constants that are to be extracted from config file private static String STR_MASTER_MAC_ADD; private static String STR_IOT_CODE_PATH; @@ -86,6 +96,7 @@ public class IoTMaster { private static String STR_NUM_CALLBACK_PORTS; private static String STR_JVM_INIT_HEAP_SIZE; private static String STR_JVM_MAX_HEAP_SIZE; + private static String STR_LANGUAGE; private static boolean BOOL_VERBOSE; /** @@ -108,6 +119,8 @@ public class IoTMaster { private static final String STR_FILE_TRF_CFG = "ADDITIONAL_ZIP_FILE"; private static final String STR_YES = "Yes"; private static final String STR_NO = "No"; + private static final String STR_JAVA = "Java"; + private static final String STR_CPP = "C++"; /** * Runtime class name constants - not to be configured by users @@ -142,6 +155,11 @@ public class IoTMaster { arrFieldValues = null; filesocket = null; mapClassNameToCrim = null; + // Connection with C++ IoTSlave + serverSocketCpp = null; + socketCpp = null; + inputCpp = null; + outputCpp = null; STR_MASTER_MAC_ADD = null; STR_IOT_CODE_PATH = null; @@ -160,6 +178,7 @@ public class IoTMaster { STR_NUM_CALLBACK_PORTS = null; STR_JVM_INIT_HEAP_SIZE = null; STR_JVM_MAX_HEAP_SIZE = null; + STR_LANGUAGE = null; BOOL_VERBOSE = false; } @@ -177,7 +196,7 @@ public class IoTMaster { routerConfig.getAddressList(STR_ROUTER_ADD); objInitHand = new ObjectInitHandler(BOOL_VERBOSE); objAddInitHand = new ObjectAddressInitHandler(BOOL_VERBOSE); - mapClassNameToCrim = new HashMap(); + mapClassNameToCrim = new HashMap(); } /** @@ -217,6 +236,7 @@ public class IoTMaster { STR_NUM_CALLBACK_PORTS = prop.getProperty("NUMBER_CALLBACK_PORTS"); STR_JVM_INIT_HEAP_SIZE = prop.getProperty("JVM_INIT_HEAP_SIZE"); STR_JVM_MAX_HEAP_SIZE = prop.getProperty("JVM_MAX_HEAP_SIZE"); + STR_LANGUAGE = prop.getProperty("LANGUAGE"); if(prop.getProperty("VERBOSE").equals(STR_YES)) { BOOL_VERBOSE = true; } @@ -239,6 +259,7 @@ public class IoTMaster { RuntimeOutput.print("STR_NUM_CALLBACK_PORTS=" + STR_NUM_CALLBACK_PORTS, BOOL_VERBOSE); RuntimeOutput.print("STR_JVM_INIT_HEAP_SIZE=" + STR_JVM_INIT_HEAP_SIZE, BOOL_VERBOSE); RuntimeOutput.print("STR_JVM_MAX_HEAP_SIZE=" + STR_JVM_MAX_HEAP_SIZE, BOOL_VERBOSE); + RuntimeOutput.print("STR_LANGUAGE=" + STR_LANGUAGE, BOOL_VERBOSE); RuntimeOutput.print("BOOL_VERBOSE=" + BOOL_VERBOSE, BOOL_VERBOSE); RuntimeOutput.print("IoTMaster: Information extracted successfully!", BOOL_VERBOSE); } @@ -348,8 +369,11 @@ public class IoTMaster { // Get information from the set List listObject = objAddInitHand.getFields(strFieldIdentifier); // Create a new IoTSet - Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, strFieldName); - commMasterToSlave(msgCrtIoTSet, "Create new IoTSet for IoTDeviceAddress!", inStream, outStream); + if(STR_LANGUAGE.equals(STR_JAVA)) { + Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, strFieldName); + commMasterToSlave(msgCrtIoTSet, "Create new IoTSet for IoTDeviceAddress!", inStream, outStream); + } else + ; int iRows = listObject.size(); RuntimeOutput.print("IoTMaster: Number of rows for IoTDeviceAddress: " + iRows, BOOL_VERBOSE); // Transfer the address @@ -385,19 +409,24 @@ public class IoTMaster { System.out.println("DEBUG: InstrumentSetDevice: Device address: " + strDeviceAddressKey + "\n\n"); // Send address one by one - Message msgGetIoTSetObj = null; - if (bDstPortWildCard) { - String strUniqueDev = strDeviceAddressKey + ":" + iRow; - msgGetIoTSetObj = new MessageGetDeviceObject(IoTCommCode.GET_DEVICE_IOTSET_OBJECT, - strDeviceAddress, commHan.getAdditionalPort(strUniqueDev), iDestDeviceDriverPort, bSrcPortWildCard, bDstPortWildCard); + if(STR_LANGUAGE.equals(STR_JAVA)) { + Message msgGetIoTSetObj = null; + if (bDstPortWildCard) { + String strUniqueDev = strDeviceAddressKey + ":" + iRow; + msgGetIoTSetObj = new MessageGetDeviceObject(IoTCommCode.GET_DEVICE_IOTSET_OBJECT, + strDeviceAddress, commHan.getAdditionalPort(strUniqueDev), iDestDeviceDriverPort, bSrcPortWildCard, bDstPortWildCard); + } else + msgGetIoTSetObj = new MessageGetDeviceObject(IoTCommCode.GET_DEVICE_IOTSET_OBJECT, + strDeviceAddress, commHan.getComPort(strDeviceAddressKey), iDestDeviceDriverPort, bSrcPortWildCard, bDstPortWildCard); + commMasterToSlave(msgGetIoTSetObj, "Get IoTSet objects!", inStream, outStream); } else - msgGetIoTSetObj = new MessageGetDeviceObject(IoTCommCode.GET_DEVICE_IOTSET_OBJECT, - strDeviceAddress, commHan.getComPort(strDeviceAddressKey), iDestDeviceDriverPort, bSrcPortWildCard, bDstPortWildCard); - commMasterToSlave(msgGetIoTSetObj, "Get IoTSet objects!", inStream, outStream); + ; } // Reinitialize IoTSet on device object - commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTSET_FIELD), - "Reinitialize IoTSet fields!", inStream, outStream); + if(STR_LANGUAGE.equals(STR_JAVA)) + commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTSET_FIELD), "Reinitialize IoTSet fields!", inStream, outStream); + else + ; } @@ -418,8 +447,11 @@ public class IoTMaster { // Get information from the set SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue(); // Create a new IoTSet - Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, strFieldName); - commMasterToSlave(msgCrtIoTSet, "Create new IoTSet for IoTZigbeeAddress!", inStream, outStream); + if(STR_LANGUAGE.equals(STR_JAVA)) { + Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, strFieldName); + commMasterToSlave(msgCrtIoTSet, "Create new IoTSet for IoTZigbeeAddress!", inStream, outStream); + } else // TODO: will need to implement IoTSet Zigbee for C++ later + ; // Prepare ZigbeeConfig String strZigbeeGWAddress = routerConfig.getIPFromMACAddress(STR_ZB_GATEWAY_ADDRESS); String strZigbeeGWAddressKey = strObjName + "-" + strZigbeeGWAddress; @@ -448,9 +480,11 @@ public class IoTMaster { // Send policy to Zigbee gateway - TODO: Need to clear policy first? zbConfig.setPolicy(strIoTSlaveObjectHostAdd, commHan.getComPort(strZigbeeGWAddressKey), strZBDevAddress); // Send address one by one - Message msgGetIoTSetZBObj = new MessageGetSimpleDeviceObject(IoTCommCode.GET_ZB_DEV_IOTSET_OBJECT, - strZBDevAddress); - commMasterToSlave(msgGetIoTSetZBObj, "Get IoTSet objects!", inStream, outStream); + if(STR_LANGUAGE.equals(STR_JAVA)) { + Message msgGetIoTSetZBObj = new MessageGetSimpleDeviceObject(IoTCommCode.GET_ZB_DEV_IOTSET_OBJECT, strZBDevAddress); + commMasterToSlave(msgGetIoTSetZBObj, "Get IoTSet objects!", inStream, outStream); + } else + ; } zbConfig.closeConnection(); // Reinitialize IoTSet on device object @@ -474,8 +508,11 @@ public class IoTMaster { // Get information from the set List listObject = objAddInitHand.getFields(strFieldIdentifier); // Create a new IoTSet - Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, strFieldName); - commMasterToSlave(msgCrtIoTSet, "Create new IoTSet for IoTAddress!", inStream, outStream); + if(STR_LANGUAGE.equals(STR_JAVA)) { + Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, strFieldName); + commMasterToSlave(msgCrtIoTSet, "Create new IoTSet for IoTAddress!", inStream, outStream); + } else + ; int iRows = listObject.size(); RuntimeOutput.print("IoTMaster: Number of rows for IoTAddress: " + iRows, BOOL_VERBOSE); // Transfer the address @@ -484,9 +521,11 @@ public class IoTMaster { // Get device address String strAddress = (String) arrFieldValues[0]; // Send address one by one - Message msgGetIoTSetAddObj = new MessageGetSimpleDeviceObject(IoTCommCode.GET_ADD_IOTSET_OBJECT, - strAddress); - commMasterToSlave(msgGetIoTSetAddObj, "Get IoTSet objects!", inStream, outStream); + if(STR_LANGUAGE.equals(STR_JAVA)) { + Message msgGetIoTSetAddObj = new MessageGetSimpleDeviceObject(IoTCommCode.GET_ADD_IOTSET_OBJECT, strAddress); + commMasterToSlave(msgGetIoTSetAddObj, "Get IoTSet objects!", inStream, outStream); + } else + ; } // Reinitialize IoTSet on device object commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTSET_FIELD), @@ -666,10 +705,10 @@ public class IoTMaster { } else { // Other port numbers... commHan.addDevicePort(iDestDeviceDriverPort); - routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveObjectHostAdd, strDeviceAddress, strProtocol, commHan.getComPort(strDeviceAddressKey), - iDestDeviceDriverPort); - routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress, strProtocol, commHan.getComPort(strDeviceAddressKey), - iDestDeviceDriverPort); + routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strIoTSlaveObjectHostAdd, strDeviceAddress, strProtocol, + commHan.getComPort(strDeviceAddressKey), iDestDeviceDriverPort); + routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress, strProtocol, + commHan.getComPort(strDeviceAddressKey), iDestDeviceDriverPort); } } } @@ -714,20 +753,30 @@ public class IoTMaster { // If this is a new object ... then create one // Instrument the class source code and look for IoTSet for device addresses // e.g. @config private IoTSet lb_addresses; - String strObjectClassNamePath = STR_IOT_CODE_PATH + strObjClassName + "/" + strObjClassName + STR_CLS_FILE_EXT; - FileInputStream fis = new FileInputStream(strObjectClassNamePath); - ClassReader cr = new ClassReader(fis); - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); - // We need Object ID to instrument IoTDeviceAddress - ClassRuntimeInstrumenterMaster crim = new ClassRuntimeInstrumenterMaster(cw, strFieldObjectID, BOOL_VERBOSE); - cr.accept(crim, 0); - fis.close(); - RuntimeOutput.print("IoTMaster: Going to instrument for " + strObjClassName + " with objectID " + - strFieldObjectID, BOOL_VERBOSE); + HashMap hmObjectFieldObjects = null; + if(STR_LANGUAGE.equals(STR_JAVA)) { + String strObjectClassNamePath = STR_IOT_CODE_PATH + strObjClassName + "/" + strObjClassName + STR_CLS_FILE_EXT; + FileInputStream fis = new FileInputStream(strObjectClassNamePath); + ClassReader cr = new ClassReader(fis); + ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); + // We need Object ID to instrument IoTDeviceAddress + ClassRuntimeInstrumenterMaster crim = new ClassRuntimeInstrumenterMaster(cw, strFieldObjectID, BOOL_VERBOSE); + cr.accept(crim, 0); + fis.close(); + mapClassNameToCrim.put(strObjClassName + strFieldObjectID, crim); + hmObjectFieldObjects = crim.getFieldObjects(); + } else { // For C++ + String strObjectClassNamePath = STR_IOT_CODE_PATH + strObjClassName + "/" + strObjClassName + STR_CFG_FILE_EXT; + CRuntimeInstrumenterMaster crim = new CRuntimeInstrumenterMaster(strObjectClassNamePath, strFieldObjectID, BOOL_VERBOSE); + mapClassNameToCrim.put(strObjClassName + strFieldObjectID, crim); + hmObjectFieldObjects = crim.getFieldObjects(); + } // Get the object and the class names // Build objects for IoTSet and IoTRelation fields in the device object classes - mapClassNameToCrim.put(strObjClassName + strFieldObjectID, crim); - HashMap hmObjectFieldObjects = crim.getFieldObjects(); +// mapClassNameToCrim.put(strObjClassName + strFieldObjectID, crim); +// HashMap hmObjectFieldObjects = crim.getFieldObjects(); + RuntimeOutput.print("IoTMaster: Going to instrument for " + strObjClassName + " with objectID " + + strFieldObjectID, BOOL_VERBOSE); for(Map.Entry map : hmObjectFieldObjects.entrySet()) { RuntimeOutput.print("IoTMaster: Object name: " + map.getValue().getClass().getName(), BOOL_VERBOSE); // Iterate over HashMap and choose between processing @@ -760,6 +809,35 @@ public class IoTMaster { } + /** + * A private method to send files to a Java slave driver + * + * @return void + */ + private void sendFileToJavaSlaveDriver(ServerSocket serverSocket, ObjectInputStream inStream, ObjectOutputStream outStream, + String strObjName, String strObjClassName, String strObjClassInterfaceName, String strObjStubClsIntfaceName, + String strIoTSlaveObjectHostAdd, String strFieldObjectID, Object[] arrFieldValues, Class[] arrFieldClasses) + throws IOException, ClassNotFoundException { + + // Create message to transfer file first + String sFileName = strObjClassName + STR_JAR_FILE_EXT; + String sPath = STR_IOT_CODE_PATH + strObjClassName + "/" + sFileName; + File file = new File(sPath); + commMasterToSlave(new MessageSendFile(IoTCommCode.TRANSFER_FILE, sFileName, file.length()), + "Sending file!", inStream, outStream); + // Send file - JAR file for object creation + sendFile(serverSocket.accept(), sPath, file.length()); + Message msgReply = (Message) inStream.readObject(); + RuntimeOutput.print("IoTMaster: Reply message: " + msgReply.getMessage(), BOOL_VERBOSE); + // Pack object information to create object on a IoTSlave + Message msgObjIoTSlave = new MessageCreateObject(IoTCommCode.CREATE_OBJECT, strIoTSlaveObjectHostAdd, + strObjClassName, strObjName, strObjClassInterfaceName, strObjStubClsIntfaceName, commHan.getRMIRegPort(strObjName), + commHan.getRMIStubPort(strObjName), arrFieldValues, arrFieldClasses); + // Send message + commMasterToSlave(msgObjIoTSlave, "Sending object information", inStream, outStream); + } + + /** * A private method to create an object on a specific machine * @@ -809,16 +887,12 @@ public class IoTMaster { // PROFILING start = System.currentTimeMillis(); - // Create message to transfer file first - String sFileName = strObjClassName + STR_JAR_FILE_EXT; - String sPath = STR_IOT_CODE_PATH + strObjClassName + "/" + sFileName; - File file = new File(sPath); - commMasterToSlave(new MessageSendFile(IoTCommCode.TRANSFER_FILE, sFileName, file.length()), - "Sending file!", inStream, outStream); - // Send file - JAR file for object creation - sendFile(serverSocket.accept(), sPath, file.length()); - Message msgReply = (Message) inStream.readObject(); - RuntimeOutput.print("IoTMaster: Reply message: " + msgReply.getMessage(), BOOL_VERBOSE); + if(STR_LANGUAGE.equals(STR_JAVA)) { + sendFileToJavaSlaveDriver(serverSocket, inStream, outStream, strObjName, + strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName, + strIoTSlaveObjectHostAdd, strFieldObjectID, arrFieldValues, arrFieldClasses); + } else + ; // PROFILING result = System.currentTimeMillis()-start; @@ -827,20 +901,21 @@ public class IoTMaster { // PROFILING start = System.currentTimeMillis(); - // Pack object information to create object on a IoTSlave - Message msgObjIoTSlave = new MessageCreateObject(IoTCommCode.CREATE_OBJECT, strIoTSlaveObjectHostAdd, - strObjClassName, strObjName, strObjClassInterfaceName, strObjStubClsIntfaceName, commHan.getRMIRegPort(strObjName), - commHan.getRMIStubPort(strObjName), arrFieldValues, arrFieldClasses); - // Send message - commMasterToSlave(msgObjIoTSlave, "Sending object information", inStream, outStream); // Instrument the class source code and look for IoTSet for device addresses // e.g. @config private IoTSet lb_addresses; RuntimeOutput.print("IoTMaster: Instantiating for " + strObjClassName + " with objectID " + strFieldObjectID, BOOL_VERBOSE); // Get the object and the class names // Build objects for IoTSet and IoTRelation fields in the device object classes - ClassRuntimeInstrumenterMaster crim = mapClassNameToCrim.get(strObjClassName + strFieldObjectID); - HashMap hmObjectFieldObjects = crim.getFieldObjects(); + Object crimObj = mapClassNameToCrim.get(strObjClassName + strFieldObjectID); + HashMap hmObjectFieldObjects = null; + if (crimObj instanceof ClassRuntimeInstrumenterMaster) { + ClassRuntimeInstrumenterMaster crim = (ClassRuntimeInstrumenterMaster) crimObj; + hmObjectFieldObjects = crim.getFieldObjects(); + } else if (crimObj instanceof CRuntimeInstrumenterMaster) { + CRuntimeInstrumenterMaster crim = (CRuntimeInstrumenterMaster) crimObj; + hmObjectFieldObjects = crim.getFieldObjects(); + } for(Map.Entry map : hmObjectFieldObjects.entrySet()) { RuntimeOutput.print("IoTMaster: Object name: " + map.getValue().getClass().getName(), BOOL_VERBOSE); // Iterate over HashMap and choose between processing @@ -877,7 +952,11 @@ public class IoTMaster { } // End the session // TODO: Change this later - outStream.writeObject(new MessageSimple(IoTCommCode.END_SESSION)); + + if(STR_LANGUAGE.equals(STR_JAVA)) + outStream.writeObject(new MessageSimple(IoTCommCode.END_SESSION)); + else + ; // PROFILING result = System.currentTimeMillis()-start; @@ -1028,7 +1107,66 @@ public class IoTMaster { * @params outStream ObjectOutputStream communication * @return void */ - private void initializeSetsAndRelations(ObjectInputStream inStream, ObjectOutputStream outStream) + private void initializeSetsAndRelationsJava(ObjectInputStream inStream, ObjectOutputStream outStream) + throws IOException, ClassNotFoundException { + // Get list of fields + List strFields = objInitHand.getListOfFields(); + // Iterate on HostAddress + for(String str : strFields) { + IoTCommCode iotcommMsg = objInitHand.getFieldMessage(str); + if (iotcommMsg == IoTCommCode.CREATE_NEW_IOTSET) { + // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO CREATE IOTSET + Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, str); + commMasterToSlave(msgCrtIoTSet, "Create new IoTSet!", inStream, outStream); + List listObject = objInitHand.getListObjectInitInfo(str); + for (ObjectInitInfo objInitInfo : listObject) { + // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTSET + commMasterToSlave(new MessageGetObject(IoTCommCode.GET_IOTSET_OBJECT, objInitInfo.getIoTSlaveObjectHostAdd(), + objInitInfo.getObjectName(), objInitInfo.getObjectClassName(), objInitInfo.getObjectClassInterfaceName(), + objInitInfo.getObjectStubClassInterfaceName(), objInitInfo.getRMIRegistryPort(), objInitInfo.getRMIStubPort(), + objInitInfo.getRMICallbackPorts()), "Get IoTSet object!", inStream, outStream); + + } + // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO REINITIALIZE IOTSET FIELD + commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTSET_FIELD), + "Renitialize IoTSet field!", inStream, outStream); + } else if (iotcommMsg == IoTCommCode.CREATE_NEW_IOTRELATION) { + // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO CREATE IOTRELATION + Message msgCrtIoTRel = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTRELATION, str); + commMasterToSlave(msgCrtIoTRel, "Create new IoTRelation!", inStream, outStream); + List listObject = objInitHand.getListObjectInitInfo(str); + List listSecondObject = objInitHand.getSecondObjectInitInfo(str); + Iterator it = listSecondObject.iterator(); + for (ObjectInitInfo objInitInfo : listObject) { + // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTRELATION (FIRST OBJECT) + commMasterToSlave(new MessageGetObject(IoTCommCode.GET_IOTRELATION_FIRST_OBJECT, + objInitInfo.getIoTSlaveObjectHostAdd(), objInitInfo.getObjectName(), objInitInfo.getObjectClassName(), + objInitInfo.getObjectClassInterfaceName(), objInitInfo.getObjectStubClassInterfaceName(), + objInitInfo.getRMIRegistryPort(), objInitInfo.getRMIStubPort(), objInitInfo.getRMICallbackPorts()), + "Get IoTRelation first object!", inStream, outStream); + ObjectInitInfo objSecObj = (ObjectInitInfo) it.next(); + // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTRELATION (SECOND OBJECT) + commMasterToSlave(new MessageGetObject(IoTCommCode.GET_IOTRELATION_SECOND_OBJECT, + objSecObj.getIoTSlaveObjectHostAdd(), objSecObj.getObjectName(), objSecObj.getObjectClassName(), + objSecObj.getObjectClassInterfaceName(), objSecObj.getObjectStubClassInterfaceName(), + objSecObj.getRMIRegistryPort(), objSecObj.getRMIStubPort(), objSecObj.getRMICallbackPorts()), + "Get IoTRelation second object!", inStream, outStream); + } + // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO REINITIALIZE IOTRELATION FIELD + commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTRELATION_FIELD), + "Renitialize IoTRelation field!", inStream, outStream); + } + } + } + + /** + * A method to reinitialize IoTSet and IoTRelation in the code based on ObjectInitHandler information + * + * @params inStream ObjectInputStream communication + * @params outStream ObjectOutputStream communication + * @return void + */ + private void initializeSetsAndRelationsCpp(ObjectInputStream inStream, ObjectOutputStream outStream) throws IOException, ClassNotFoundException { // Get list of fields List strFields = objInitHand.getListOfFields(); @@ -1167,6 +1305,43 @@ public class IoTMaster { } } + /** + * A method to send files to Java IoTSlave + * + * @return void + */ + private void sendFileToJavaSlave(String strObjControllerName, ServerSocket serverSocket, + ObjectInputStream inStream, ObjectOutputStream outStream) throws IOException, ClassNotFoundException { + + // Send .jar file + String strControllerJarName = strObjControllerName + STR_JAR_FILE_EXT; + String strControllerJarNamePath = STR_CONT_PATH + strObjControllerName + "/" + + strControllerJarName; + File file = new File(strControllerJarNamePath); + commMasterToSlave(new MessageSendFile(IoTCommCode.TRANSFER_FILE, strControllerJarName, file.length()), + "Sending file!", inStream, outStream); + // Send file - Class file for object creation + sendFile(serverSocket.accept(), strControllerJarNamePath, file.length()); + Message msgReply = (Message) inStream.readObject(); + RuntimeOutput.print("IoTMaster: Reply message: " + msgReply.getMessage(), BOOL_VERBOSE); + // Send .zip file if additional zip file is specified + String strObjCfgFile = strObjControllerName + STR_CFG_FILE_EXT; + String strObjCfgFilePath = STR_CONT_PATH + strObjControllerName + "/" + strObjCfgFile; + String strAdditionalFile = parseConfigFile(strObjCfgFilePath, STR_FILE_TRF_CFG); + if (strAdditionalFile.equals(STR_YES)) { + String strControllerCmpName = strObjControllerName + STR_ZIP_FILE_EXT; + String strControllerCmpNamePath = STR_CONT_PATH + strObjControllerName + "/" + + strControllerCmpName; + file = new File(strControllerCmpNamePath); + commMasterToSlave(new MessageSendFile(IoTCommCode.TRANSFER_FILE, strControllerCmpName, file.length()), + "Sending file!", inStream, outStream); + // Send file - Class file for object creation + sendFile(serverSocket.accept(), strControllerCmpNamePath, file.length()); + msgReply = (Message) inStream.readObject(); + RuntimeOutput.print("IoTMaster: Reply message: " + msgReply.getMessage(), BOOL_VERBOSE); + } + } + /** * A method to assign objects to multiple JVMs, including @@ -1241,36 +1416,16 @@ public class IoTMaster { String strControllerClassName = strObjControllerName + STR_CLS_FILE_EXT; String strControllerClassNamePath = STR_CONT_PATH + strObjControllerName + "/" + strControllerClassName; - // Send .jar file - String strControllerJarName = strObjControllerName + STR_JAR_FILE_EXT; - String strControllerJarNamePath = STR_CONT_PATH + strObjControllerName + "/" + - strControllerJarName; - File file = new File(strControllerJarNamePath); - commMasterToSlave(new MessageSendFile(IoTCommCode.TRANSFER_FILE, strControllerJarName, file.length()), - "Sending file!", inStream, outStream); - // Send file - Class file for object creation - sendFile(serverSocket.accept(), strControllerJarNamePath, file.length()); - Message msgReply = (Message) inStream.readObject(); - RuntimeOutput.print("IoTMaster: Reply message: " + msgReply.getMessage(), BOOL_VERBOSE); - // Send .zip file if additional zip file is specified - String strObjCfgFile = strObjControllerName + STR_CFG_FILE_EXT; - String strObjCfgFilePath = STR_CONT_PATH + strObjControllerName + "/" + strObjCfgFile; - String strAdditionalFile = parseConfigFile(strObjCfgFilePath, STR_FILE_TRF_CFG); - if (strAdditionalFile.equals(STR_YES)) { - String strControllerCmpName = strObjControllerName + STR_ZIP_FILE_EXT; - String strControllerCmpNamePath = STR_CONT_PATH + strObjControllerName + "/" + - strControllerCmpName; - file = new File(strControllerCmpNamePath); - commMasterToSlave(new MessageSendFile(IoTCommCode.TRANSFER_FILE, strControllerCmpName, file.length()), - "Sending file!", inStream, outStream); - // Send file - Class file for object creation - sendFile(serverSocket.accept(), strControllerCmpNamePath, file.length()); - msgReply = (Message) inStream.readObject(); - RuntimeOutput.print("IoTMaster: Reply message: " + msgReply.getMessage(), BOOL_VERBOSE); - } - // Create main controller/device object - commMasterToSlave(new MessageCreateMainObject(IoTCommCode.CREATE_MAIN_OBJECT, strObjControllerName), - "Create main object!", inStream, outStream); + + if(STR_LANGUAGE.equals(STR_JAVA)) { + sendFileToJavaSlave(strObjControllerName, serverSocket, inStream, outStream); + // Create main controller/device object + commMasterToSlave(new MessageCreateMainObject(IoTCommCode.CREATE_MAIN_OBJECT, strObjControllerName), + "Create main object!", inStream, outStream); + } else if(STR_LANGUAGE.equals(STR_CPP)) + ; + else + throw new Error("IoTMaster: Language specification not recognized: " + STR_LANGUAGE); // PROFILING result = System.currentTimeMillis()-start; @@ -1283,15 +1438,23 @@ public class IoTMaster { // Instrumenting one file RuntimeOutput.print("IoTMaster: Opening class file: " + strControllerClassName, BOOL_VERBOSE); RuntimeOutput.print("IoTMaster: Class file path: " + strControllerClassNamePath, BOOL_VERBOSE); - FileInputStream fis = new FileInputStream(strControllerClassNamePath); - ClassReader cr = new ClassReader(fis); - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); - ClassRuntimeInstrumenterMaster crim = new ClassRuntimeInstrumenterMaster(cw, null, BOOL_VERBOSE); - cr.accept(crim, 0); - fis.close(); + HashMap hmControllerFieldObjects = null; + if(STR_LANGUAGE.equals(STR_JAVA)) { + FileInputStream fis = new FileInputStream(strControllerClassNamePath); + ClassReader cr = new ClassReader(fis); + ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); + ClassRuntimeInstrumenterMaster crim = new ClassRuntimeInstrumenterMaster(cw, null, BOOL_VERBOSE); + cr.accept(crim, 0); + fis.close(); + hmControllerFieldObjects = crim.getFieldObjects(); + } else { + String strControllerConfigFile = STR_CONT_PATH + strObjControllerName + "/" + strObjControllerName + STR_CFG_FILE_EXT; + CRuntimeInstrumenterMaster crim = new CRuntimeInstrumenterMaster(strControllerConfigFile, null, BOOL_VERBOSE); + hmControllerFieldObjects = crim.getFieldObjects(); + } // Get the object and the class names // Build objects for IoTSet and IoTRelation fields in the controller/device classes - HashMap hmControllerFieldObjects = crim.getFieldObjects(); + //HashMap hmControllerFieldObjects = crim.getFieldObjects(); for(Map.Entry map : hmControllerFieldObjects.entrySet()) { RuntimeOutput.print("IoTMaster: Object name: " + map.getValue().getClass().getName(), BOOL_VERBOSE); // Iterate over HashMap and choose between processing @@ -1362,17 +1525,26 @@ public class IoTMaster { start = System.currentTimeMillis(); // Sets and relations initializations - initializeSetsAndRelations(inStream, outStream); + if(STR_LANGUAGE.equals(STR_JAVA)) + initializeSetsAndRelationsJava(inStream, outStream); + else + ; // PROFILING result = System.currentTimeMillis()-start; System.out.println("\n\n ==> Time needed to initialize sets and relations: " + result + "\n\n"); - // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO EXECUTE INIT METHOD - commMasterToSlave(new MessageSimple(IoTCommCode.INVOKE_INIT_METHOD), - "Invoke init() method!", inStream, outStream); + if(STR_LANGUAGE.equals(STR_JAVA)) + // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO EXECUTE INIT METHOD + commMasterToSlave(new MessageSimple(IoTCommCode.INVOKE_INIT_METHOD), + "Invoke init() method!", inStream, outStream); + else + ; // == COMMUNICATION WITH IOTSLAVE CONTROLLER TO END PROCESS - outStream.writeObject(new MessageSimple(IoTCommCode.END_SESSION)); + if(STR_LANGUAGE.equals(STR_JAVA)) + outStream.writeObject(new MessageSimple(IoTCommCode.END_SESSION)); + else + ; outStream.close(); inStream.close(); socket.close(); diff --git a/localconfig/iotruntime/IoTMaster.config b/localconfig/iotruntime/IoTMaster.config index 79e16e8..0a934bd 100644 --- a/localconfig/iotruntime/IoTMaster.config +++ b/localconfig/iotruntime/IoTMaster.config @@ -30,6 +30,9 @@ VERBOSE=Yes #Number of callback ports NUMBER_CALLBACK_PORTS=1 +#Language: C++ or Java +LANGUAGE=Java + #JVM heap size - can go out of memory if a IoTSlave needs to handle a lot of objects #E.g. JVM_INIT_HEAP_SIZE=-Xms64m, JVM_MAX_HEAP_SIZE=-Xmx64m (64 MB of heap) #Made empty for now as it needs fine-tuning -- 2.34.1