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