Cleaning up code for runtime, installer, RMI, compiler for the Java side
[iot2.git] / iotjava / iotruntime / master / CommunicationHandler.java
1 package iotruntime.master;
2
3 import java.util.ArrayList;
4 import java.util.HashMap;
5 import java.util.HashSet;
6 import java.util.List;
7 import java.util.Map;
8 import java.util.Random;
9 import java.util.Set;
10
11 /** Class CommunicationHandler is a class that maintains
12  *  a data structure that preserves a collection of host name,
13  *  port numbers, and objects that are running
14  *  +-----------------+----+--------+------------------+--------------+----+----------------+
15  *  | HOST-ADDRESS    | ...|IN-PORT | RMIREGISTRY-PORT | RMISTUB-PORT | ...| ACTIVE OBJECTS |
16  *  +-----------------+----+--------+------------------+--------------+----+----------------+
17  *  | XXX.XXX.XXX.XXX |    | XXXXX  | XXXXX            | XXXXX        |    | XXXXXXXXXXXXXX |
18  *  |                 |    | XXXXX  | XXXXX            | XXXXX        |    | XXXXXXXXXXXXXX |
19  *  |                 |    | XXXXX  | XXXXX            | XXXXX        |    | XXXXXXXXXXXXXX |
20  *  |                 | ...| ...    | ...              | ...          | ...| ...            |
21  *  +-----------------+----+--------+------------------+--------------+----+----------------+
22  *  In this case we use ACTIVE OBJECTS names as the key
23  *  So ACTIVE OBJECTS maps to numbers and these numbers map to each other
24  *  entry in hashmaps (HostAddress can be repetitive)
25  *  e.g. ACTIVE OBJECTS ProximitySensorPS0 - 0
26  *                      ProximitySensorPS1 - 1
27  *                      TempSensorTS1      - 2
28  *                      ...
29  *
30  * @author      Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>
31  * @version     1.0
32  * @since       2016-01-07
33  */
34 public final class CommunicationHandler {
35
36         /**
37          * CommunicationHandler class properties
38          * <p>
39          * Random, host name, port number, active objects
40          * HostAdd is the key to the table so we use it
41          * as a key to elements
42          * HostList gives a mapping from hostname to list of objects
43          */
44         private Random random;
45         private List<String> listActiveControllerObj;
46         private List<String> listFieldObjectID;
47         private List<ObjectCreationInfo> listObjCrtInfo;
48         private List<Object[]> listArrFieldValues;
49         private List<Class[]> listArrFieldClasses;
50         private Map<String, Integer> hmActiveObj;
51         private Map<Integer, String> hmHostAdd;
52         private Map<String, ArrayList<String> > hmHostList;
53         private Map<Integer, Integer> hmComPort;
54         private Map<Integer, Integer> hmRMIRegPort;
55         private Map<Integer, Integer> hmRMIStubPort;
56         private Set<Integer> hsDevicePort;
57         private Map<Integer, Integer> hmAdditionalPort;
58         private int iNumOfObjects;
59         private int iNumOfHosts;
60         private boolean bVerbose;
61
62         /**
63          * CommunicationHandler class constants
64          */
65         private final int INT_MAX_PORT = 65535;
66         private final int INT_MIN_PORT = 10000;
67
68         /**
69          * Constructor
70          */
71         public CommunicationHandler(boolean _bVerbose) {
72
73                 random = new Random();
74                 listActiveControllerObj = new ArrayList<String>();
75                 listFieldObjectID = new ArrayList<String>();
76                 listObjCrtInfo = new ArrayList<ObjectCreationInfo>();
77                 listArrFieldValues = new ArrayList<Object[]>();
78                 listArrFieldClasses = new ArrayList<Class[]>();
79                 hmActiveObj = new HashMap<String, Integer>();
80                 hmHostAdd = new HashMap<Integer, String>();
81                 hmHostList = new HashMap<String, ArrayList<String>>();
82                 hmComPort = new HashMap<Integer, Integer>();
83                 hmRMIRegPort = new HashMap<Integer, Integer>();
84                 hmRMIStubPort = new HashMap<Integer, Integer>();
85                 hsDevicePort = new HashSet<Integer>();
86                 hmAdditionalPort = new HashMap<Integer, Integer>();
87                 iNumOfObjects = 0;
88                 iNumOfHosts = 0;
89                 bVerbose = _bVerbose;
90                 RuntimeOutput.print("CommunicationHandler: Creating a new CommunicationHandler object!", bVerbose);
91         }
92         
93         /**
94          * Method clearCommunicationHandler()
95          * <p>
96          * Clear the data structure
97          *
98          * @return  void
99          */
100         public void clearCommunicationHandler() {
101
102                 listActiveControllerObj.clear();
103                 listFieldObjectID.clear();
104                 listObjCrtInfo.clear();
105                 listArrFieldValues.clear();
106                 listArrFieldClasses.clear();
107                 hmActiveObj.clear();
108                 hmHostAdd.clear();
109                 hmHostList.clear();
110                 hmComPort.clear();
111                 hmRMIRegPort.clear();
112                 hmRMIStubPort.clear();
113                 hsDevicePort.clear();
114                 hmAdditionalPort.clear();
115                 iNumOfObjects = 0;
116                 iNumOfHosts = 0;
117                 RuntimeOutput.print("CommunicationHandler: Clearing CommunicationHandler object's data structure!", bVerbose);
118     }
119
120         /**
121          * Method addPortConnection()
122          * <p>
123          * Add a new connection then generate new in-port and out-port numbers
124          *
125          * @param   sHAddress                   String host address
126          * @param   sAObject                    String active object name
127          * @return  void
128          */
129         public void addPortConnection(String sHAddress, String sAObject) {
130
131                 // Increment counter first before we add objects as we start from 0
132                 // Objects are named uniquely so we record this and match with the host
133                 // Hostname occurrence can be repetitive as there can be more than
134                 // one host on one compute node
135
136                 // Add a new object in the list of objects
137                 hmActiveObj.put(sAObject, iNumOfObjects);
138
139                 // Check host existence in our data structure
140                 // Add a new host and a new object
141                 if(hmHostList.containsKey(sHAddress) == false) {
142                         iNumOfHosts++;
143                         hmHostList.put(sHAddress, new ArrayList<String>());
144                 }
145                 hmHostList.get(sHAddress).add(sAObject);
146
147                 // Map object to host
148                 hmHostAdd.put(iNumOfObjects, sHAddress);
149
150                 int iComPort = 0;
151                 do {
152                         iComPort = random.nextInt(INT_MAX_PORT - INT_MIN_PORT + 1) + INT_MIN_PORT;
153                 // Check port existence in HashMap
154                 } while (portIsAvailable(iComPort) == false);
155                 hmComPort.put(iNumOfObjects, iComPort);
156
157                 int iRMIRegPort = 0;
158                 do {
159                         iRMIRegPort = random.nextInt(INT_MAX_PORT - INT_MIN_PORT + 1) + INT_MIN_PORT;
160                 // Check port existence in HashMap
161                 } while (portIsAvailable(iRMIRegPort) == false);
162                 hmRMIRegPort.put(iNumOfObjects, iRMIRegPort);
163
164                 int iRMIStubPort = 0;
165                 do {
166                         iRMIStubPort = random.nextInt(INT_MAX_PORT - INT_MIN_PORT + 1) + INT_MIN_PORT;
167                 // Check port existence in HashMap
168                 } while (portIsAvailable(iRMIStubPort) == false);
169                 hmRMIStubPort.put(iNumOfObjects, iRMIStubPort);
170
171                 iNumOfObjects++;
172         }
173
174         /**
175          * A private method to add a new active controller object
176          *
177          * @params  strFieldObjectID                    String field object ID
178          * @params  strObjName                                  String object name
179          * @params  strObjClassName                     String object class name
180          * @params  strObjClassInterfaceName    String object class interface name
181          * @params  strIoTSlaveObjectHostAdd    String IoTSlave host address
182          * @params  arrFieldValues                              Array of field values
183          * @params  arrFieldClasses                             Array of field classes
184          * @return  void
185          */
186         public void addActiveControllerObject(String strFieldObjectID, String strObjName, String strObjClassName,
187                 String strObjClassInterfaceName, String strObjStubClsIntfaceName, String strIoTSlaveObjectHostAdd, Object[] arrFieldValues, 
188                 Class[] arrFieldClasses) {
189
190                 listActiveControllerObj.add(strObjName);
191                 listFieldObjectID.add(strFieldObjectID);
192                 listArrFieldValues.add(arrFieldValues);
193                 listArrFieldClasses.add(arrFieldClasses);
194                 ObjectCreationInfo objCrtInfo = new ObjectCreationInfo(strIoTSlaveObjectHostAdd, strObjName,
195                         strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName);
196                 listObjCrtInfo.add(objCrtInfo);
197         }
198
199         /**
200          * Method addDevicePort()
201          * <p>
202          * Add a port that is used by a device when communicating with its driver
203          * This port will be taken into account when checking for port availability
204          *
205          * @param   iDevPort  Device port number
206          * @return  void
207          */
208         public void addDevicePort(int iDevPort) {
209
210                 hsDevicePort.add(iDevPort);
211         }
212
213         /**
214          * Method addAdditionalPort()
215          * <p>
216          * Add a new port for new connections for any objects in the program.
217          * This newly generated port number will be recorded.
218          *
219          * @return  int         One new port
220          */
221         public int addAdditionalPort(String sAObject) {
222
223                 hmActiveObj.put(sAObject, iNumOfObjects);
224
225                 int iAdditionalPort = 0;
226                 do {
227                         iAdditionalPort = random.nextInt(INT_MAX_PORT - INT_MIN_PORT + 1) + INT_MIN_PORT;
228                 // Check port existence in HashMap
229                 } while (portIsAvailable(iAdditionalPort) == false);
230                 hmAdditionalPort.put(iNumOfObjects, iAdditionalPort);
231
232                 iNumOfObjects++;
233
234                 return iAdditionalPort;
235         }
236
237         /**
238          * Method portIsAvailable()
239          * <p>
240          * Checks the availability of the newly generated port.
241          * If port number has been used in any of the lists then
242          * it is not available
243          *
244          * @param   iPortNumber  Device port number
245          * @return  boolean
246          */
247         public boolean portIsAvailable(int iPortNumber) {
248
249                 if (hmComPort.containsValue(iPortNumber) == true) {
250                         return false;
251                 } else if (hmRMIRegPort.containsValue(iPortNumber) == true) {
252                         return false;
253                 } else if (hmRMIStubPort.containsValue(iPortNumber) == true) {
254                         return false;
255                 } else if (hmAdditionalPort.containsValue(iPortNumber) == true) {
256                         return false;
257                 } else if (hsDevicePort.contains(iPortNumber) == true) {
258                         return false;
259                 } else {
260                         return true;
261                 }
262         }
263
264         /**
265          * Method getNumOfObjects()
266          *
267          * @return  int
268          */
269         public int getNumOfObjects() {
270
271                 return iNumOfObjects;
272
273         }
274
275         /**
276          * Method getNumOfHosts()
277          *
278          * @return  int
279          */
280         public int getNumOfHosts() {
281
282                 return iNumOfHosts;
283
284         }
285
286         /**
287          * Method objectExists()
288          *
289          * @param   sObjName  String object name
290          * @return  boolean
291          */
292         public boolean objectExists(String sObjName) {
293
294                 return hmActiveObj.containsKey(sObjName);
295
296         }
297
298         /**
299          * Method hostExists()
300          *
301          * @param   sHostName  String host name
302          * @return  boolean
303          */
304         public boolean hostExists(String sHostName) {
305
306                 return hmHostList.containsKey(sHostName);
307
308         }
309
310         /**
311          * Method getHostAddress()
312          * <p>
313          * User finds HostAddress using Object name
314          *
315          * @param   sAObject  String active object name
316          * @return  String
317          */
318         public String getHostAddress(String sAObject) {
319
320                 return hmHostAdd.get(hmActiveObj.get(sAObject));
321
322         }
323
324         /**
325          * Method getHosts()
326          * <p>
327          * User gets the set of hostnames
328          *
329          * @return  String
330          */
331         public Set<String> getHosts() {
332
333                 return hmHostList.keySet();
334
335         }
336
337         /**
338          * Method getComPort()
339          * <p>
340          * User finds In-Port number using Object name
341          *
342          * @param   sAObject  String active object name
343          * @return  Integer
344          */
345         public Integer getComPort(String sAObject) {
346
347                 return hmComPort.get(hmActiveObj.get(sAObject));
348         }
349
350         /**
351          * Method getAdditionalPort()
352          * <p>
353          * User finds a port number using Object name
354          *
355          * @param   sAObject  String active object name
356          * @return  Integer
357          */
358         public Integer getAdditionalPort(String sAObject) {
359
360                 return hmAdditionalPort.get(hmActiveObj.get(sAObject));
361         }
362
363         /**
364          * Method getRMIRegPort()
365          * <p>
366          * User finds Out-Port number using Object name
367          *
368          * @param   sAObject  String active object name
369          * @return  Integer
370          */
371         public Integer getRMIRegPort(String sAObject) {
372
373                 return hmRMIRegPort.get(hmActiveObj.get(sAObject));
374
375         }
376
377         /**
378          * Method getRMIStubPort()
379          * <p>
380          * User finds Out-Port number using Object name
381          *
382          * @param   sAObject  String active object name
383          * @return  Integer
384          */
385         public Integer getRMIStubPort(String sAObject) {
386
387                 return hmRMIStubPort.get(hmActiveObj.get(sAObject));
388
389         }
390
391         /**
392          * Method getFieldObjectID()
393          * <p>
394          * User finds field object ID using Object name
395          *
396          * @param   sAObject  String active object name
397          * @return  String
398          */
399         public String getFieldObjectID(String sAObject) {
400
401                 return listFieldObjectID.get(listActiveControllerObj.indexOf(sAObject));
402
403         }
404
405         /**
406          * Method getObjectCreationInfo()
407          * <p>
408          * User finds ObjectCreationInfo using Object name
409          *
410          * @param   sAObject  String active object name
411          * @return  ObjectCreationInfo
412          */
413         public ObjectCreationInfo getObjectCreationInfo(String sAObject) {
414
415                 return listObjCrtInfo.get(listActiveControllerObj.indexOf(sAObject));
416
417         }
418
419         /**
420          * Method getArrayFieldClasses()
421          * <p>
422          * User finds array of field classes using Object name
423          *
424          * @param   sAObject  String active object name
425          * @return  Class[]
426          */
427         public Class[] getArrayFieldClasses(String sAObject) {
428
429                 return listArrFieldClasses.get(listActiveControllerObj.indexOf(sAObject));
430
431         }
432
433         /**
434          * Method getArrayFieldValues()
435          * <p>
436          * User finds array of field values using Object name
437          *
438          * @param   sAObject  String active object name
439          * @return  Object[]
440          */
441         public Object[] getArrayFieldValues(String sAObject) {
442
443                 return listArrFieldValues.get(listActiveControllerObj.indexOf(sAObject));
444
445         }
446
447         /**
448          * Method getActiveControllerObjectList()
449          *
450          * @return  List<String>
451          */
452         public List<String> getActiveControllerObjectList() {
453
454                 return listActiveControllerObj;
455
456         }
457
458         /**
459          * Method printLists()
460          *
461          * @return  void
462          */
463         public void printLists() {
464
465                 // Iterate on HostAddress
466                 for(String s : hmHostList.keySet()) {
467
468                         for(String str : hmHostList.get(s)) {
469
470                                 int iIndex = hmActiveObj.get(str);
471                                 RuntimeOutput.print("Active Object: " + str, bVerbose);
472                                 RuntimeOutput.print("Communication Port: " + hmComPort.get(iIndex), bVerbose);
473                                 RuntimeOutput.print("RMI Registry Port: " + hmRMIRegPort.get(iIndex), bVerbose);
474                                 RuntimeOutput.print("RMI Stub Port: " + hmRMIStubPort.get(iIndex), bVerbose);
475                                 RuntimeOutput.print("\n", bVerbose);
476                         }
477                 }
478
479                 for(int iPort : hsDevicePort) {
480                         RuntimeOutput.print("Device Port: " + iPort, bVerbose);
481                 }
482                 RuntimeOutput.print("\n", bVerbose);
483         }
484 }