Adding C++ field instrumentation using config file
authorrtrimana <rtrimana@uci.edu>
Thu, 19 Jan 2017 19:25:34 +0000 (11:25 -0800)
committerrtrimana <rtrimana@uci.edu>
Thu, 19 Jan 2017 19:25:34 +0000 (11:25 -0800)
benchmarks/Cpp/Lifxtest/Lifxtest.config
benchmarks/Java/Lifxtest/Lifxtest.config
benchmarks/drivers/Cpp/LifxLightBulb/LifxLightBulb.config
benchmarks/drivers/Java/LifxLightBulb/LifxLightBulb.config
iotjava/iotruntime/master/CRuntimeInstrumenterMaster.java [new file with mode: 0644]
iotjava/iotruntime/master/IoTMaster.java
localconfig/iotruntime/IoTMaster.config

index 5a44766..39b3a38 100644 (file)
@@ -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
index 5a44766..39b3a38 100644 (file)
@@ -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
index fa88933..aed4665 100644 (file)
@@ -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
index fa88933..aed4665 100644 (file)
@@ -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 (file)
index 0000000..ed0c156
--- /dev/null
@@ -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 <rahmadi.trimananda @ uci.edu>
+ * @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<String,Object> hmObj;
+       private String strObjectID;
+       private boolean bVerbose;
+       private String strObjectConfigFile;
+
+       /**
+        *  Constructor
+        */
+       public CRuntimeInstrumenterMaster(String strConfigFile, String strObjID, boolean _bVerbose) {
+
+               hmObj = new HashMap<String,Object>();
+               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<iNumOfField; iFieldCounter++) {
+                       String strFieldKey = STR_FIELD + iFieldCounter; // Start from 0
+                       String strFieldClassKey = STR_FIELD_CLASS + iFieldCounter;
+                       String strFieldTypeKey = STR_FIELD_TYPE + iFieldCounter;
+                       String strField = parseConfigFile(strObjectConfigFile, strFieldKey);
+                       String strFieldClass = parseConfigFile(strObjectConfigFile, strFieldClassKey);
+                       String strFieldType = parseConfigFile(strObjectConfigFile, strFieldTypeKey);
+                       // Check if this is a Set class, then process it
+                       if (strFieldType.equals(STR_IOT_SET_TYPE)) {
+                               RuntimeOutput.print("CRuntimeInstrumenterMaster: IoTSet is detected!", bVerbose);
+                               SetInstrumenter setInstrument = new
+                                       SetInstrumenter(strFieldClass, STR_CONFIG_FILE_PATH + strField + STR_CONFIG_EXTENSION, strObjectID, bVerbose);
+                               hmObj.put(strField, setInstrument);
+                       // Check if this is a Relation class, then process it
+                       } else if (strFieldType.equals(STR_IOT_RELATION_TYPE)) {
+                               RuntimeOutput.print("CRuntimeInstrumenterMaster: IoTRelation is detected!", bVerbose);
+                               String strFieldClassRelKey = STR_FIELD_CLASS_REL + iFieldCounter;
+                               String strFieldClassRel = parseConfigFile(strObjectConfigFile, strFieldClassRelKey);
+                               RelationInstrumenter relInstrument = new
+                                       RelationInstrumenter(strFieldClass, strFieldClassRel, STR_CONFIG_FILE_PATH + strField + STR_CONFIG_EXTENSION, bVerbose);
+                               hmObj.put(strField, relInstrument);
+                       } else
+                               throw new Error("CRuntimeInstrumenterMaster: " + strFieldType + " not recognized!");
+               }
+       }
+
+
+       /**
+        * A method that returns HashMap hmObj
+        *
+        * @return         HashMap<String,Object>
+        */
+       public HashMap<String,Object> getFieldObjects() {
+
+               getFieldInfo();
+               return hmObj;
+       }
+
+}
+
+
index 1f7e697..5406e47 100644 (file)
@@ -52,7 +52,9 @@ public class IoTMaster {
        private ObjectInitHandler objInitHand;
        private ObjectAddressInitHandler objAddInitHand;
        private String[] strObjectNames;
-       private Map<String,ClassRuntimeInstrumenterMaster> mapClassNameToCrim;
+       // Now this can be either ClassRuntimeInstrumenterMaster or CRuntimeInstrumenterMaster
+       private Map<String,Object> 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<String,ClassRuntimeInstrumenterMaster>();
+               mapClassNameToCrim = new HashMap<String,Object>();
        }
 
        /**
@@ -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<Object[]> 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<Object[]> 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<IoTDeviceAddress> 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<String,Object> 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<String,Object> hmObjectFieldObjects = crim.getFieldObjects();
+//             mapClassNameToCrim.put(strObjClassName + strFieldObjectID, crim);
+//             HashMap<String,Object> hmObjectFieldObjects = crim.getFieldObjects();
+               RuntimeOutput.print("IoTMaster: Going to instrument for " + strObjClassName + " with objectID " + 
+                       strFieldObjectID, BOOL_VERBOSE);
                for(Map.Entry<String,Object> 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<IoTDeviceAddress> 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<String,Object> hmObjectFieldObjects = crim.getFieldObjects();
+               Object crimObj = mapClassNameToCrim.get(strObjClassName + strFieldObjectID);
+               HashMap<String,Object> 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<String,Object> 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<String> 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<ObjectInitInfo> 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<ObjectInitInfo> listObject = objInitHand.getListObjectInitInfo(str);
+                               List<ObjectInitInfo> 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<String> 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<String,Object> 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<String,Object> hmControllerFieldObjects = crim.getFieldObjects();
+                               //HashMap<String,Object> hmControllerFieldObjects = crim.getFieldObjects();
                                for(Map.Entry<String,Object> 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();
index 79e16e8..0a934bd 100644 (file)
@@ -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