Integrating capability-based RMI on Sentinel for 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  *       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> hsCallbackPort;
71         private int iNumOfObjects;
72         private int iNumOfHosts;
73         private boolean bVerbose;
74
75         /**
76          * CommunicationHandler class constants
77          */
78         private final int INT_MAX_PORT = 65535;
79         private final int INT_MIN_PORT = 10000;
80
81         /**
82          * Empty constructor
83          */
84         public CommunicationHandler(boolean _bVerbose) {
85
86                 random = new Random();
87                 listActiveControllerObj = new ArrayList<String>();
88                 listFieldObjectID = new ArrayList<String>();
89                 listObjCrtInfo = new ArrayList<ObjectCreationInfo>();
90                 listArrFieldValues = new ArrayList<Object[]>();
91                 listArrFieldClasses = new ArrayList<Class[]>();
92                 hmActiveObj = new HashMap<String, Integer>();
93                 hmHostAdd = new HashMap<Integer, String>();
94                 hmHostList = new HashMap<String, ArrayList<String>>();
95                 hmComPort = new HashMap<Integer, Integer>();
96                 hmRMIRegPort = new HashMap<Integer, Integer>();
97                 hmRMIStubPort = new HashMap<Integer, Integer>();
98                 hsDevicePort = new HashSet<Integer>();
99                 hsCallbackPort = new HashSet<Integer>();
100                 iNumOfObjects = 0;
101                 iNumOfHosts = 0;
102                 bVerbose = _bVerbose;
103                 RuntimeOutput.print("CommunicationHandler: Creating a new CommunicationHandler object!", bVerbose);
104         }
105
106         /**
107          * Method addPortConnection()
108          * <p>
109          * Add a new connection then generate new in-port and out-port numbers
110          *
111          * @param   sHAddress                   String host address
112          * @param   sAObject                    String active object name
113          * @return  void
114          */
115         public void addPortConnection(String sHAddress, String sAObject) {
116
117                 // Increment counter first before we add objects as we start from 0
118                 // Objects are named uniquely so we record this and match with the host
119                 // Hostname occurrence can be repetitive as there can be more than
120                 // one host on one compute node
121
122                 // Add a new object in the list of objects
123                 hmActiveObj.put(sAObject, iNumOfObjects);
124
125                 // Check host existence in our data structure
126                 // Add a new host and a new object
127                 if(hmHostList.containsKey(sHAddress) == false) {
128                         iNumOfHosts++;
129                         hmHostList.put(sHAddress, new ArrayList<String>());
130                 }
131                 hmHostList.get(sHAddress).add(sAObject);
132
133                 // Map object to host
134                 hmHostAdd.put(iNumOfObjects, sHAddress);
135
136                 int iComPort = 0;
137                 do {
138                         iComPort = random.nextInt(INT_MAX_PORT - INT_MIN_PORT + 1) + INT_MIN_PORT;
139                         // Check port existence in HashMap
140                 } while (portIsAvailable(iComPort) == false);
141                 hmComPort.put(iNumOfObjects, iComPort);
142
143                 int iRMIRegPort = 0;
144                 do {
145                         iRMIRegPort = random.nextInt(INT_MAX_PORT - INT_MIN_PORT + 1) + INT_MIN_PORT;
146                         // Check port existence in HashMap
147                 } while (portIsAvailable(iRMIRegPort) == false);
148                 hmRMIRegPort.put(iNumOfObjects, iRMIRegPort);
149
150                 int iRMIStubPort = 0;
151                 do {
152                         iRMIStubPort = random.nextInt(INT_MAX_PORT - INT_MIN_PORT + 1) + INT_MIN_PORT;
153                         // Check port existence in HashMap
154                 } while (portIsAvailable(iRMIStubPort) == false);
155                 hmRMIStubPort.put(iNumOfObjects, iRMIStubPort);
156
157                 iNumOfObjects++;
158         }
159
160         /**
161          * A private method to add a new active controller object
162          *
163          * @params  strFieldObjectID                    String field object ID
164          * @params  strObjName                                  String object name
165          * @params  strObjClassName                     String object class name
166          * @params  strObjClassInterfaceName    String object class interface name
167          * @params  strIoTSlaveObjectHostAdd    String IoTSlave host address
168          * @params  arrFieldValues                              Array of field values
169          * @params  arrFieldClasses                             Array of field classes
170          * @return  void
171          */
172         public void addActiveControllerObject(String strFieldObjectID, String strObjName, String strObjClassName,
173                 String strObjClassInterfaceName, String strObjStubClsIntfaceName, String strIoTSlaveObjectHostAdd, Object[] arrFieldValues, 
174                 Class[] arrFieldClasses) {
175
176                 listActiveControllerObj.add(strObjName);
177                 listFieldObjectID.add(strFieldObjectID);
178                 listArrFieldValues.add(arrFieldValues);
179                 listArrFieldClasses.add(arrFieldClasses);
180                 ObjectCreationInfo objCrtInfo = new ObjectCreationInfo(strIoTSlaveObjectHostAdd, strObjName,
181                         strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName);
182                 listObjCrtInfo.add(objCrtInfo);
183         }
184
185
186         /**
187          * Method getCallbackPort()
188          * <p>
189          * Get a new port for new connections for callback objects in the program.
190          * This newly generated port number will be recorded.
191          *
192          * @return  int[]       A set of callback ports
193          */
194         public int[] getCallbackPorts(int numOfPorts) {
195
196                 int[] ports = new int[numOfPorts];
197
198                 for(int i = 0; i < numOfPorts; i++) {
199                         do {
200                                 ports[i] = random.nextInt(INT_MAX_PORT - INT_MIN_PORT + 1) + INT_MIN_PORT;
201                                 // Check port existence in HashMap
202                         } while (portIsAvailable(ports[i]) == false);
203                         hsCallbackPort.add(ports[i]);
204                 }
205
206                 return ports;
207         }
208
209
210         /**
211          * Method addDevicePort()
212          * <p>
213          * Add a port that is used by a device when communicating with its driver
214          * This port will be taken into account when checking for port availability
215          *
216          * @param   iDevPort  Device port number
217          * @return  void
218          */
219         public void addDevicePort(int iDevPort) {
220
221                 hsDevicePort.add(iDevPort);
222
223         }
224
225         /**
226          * Method portIsAvailable()
227          * <p>
228          * Checks the availability of the newly generated port.
229          * If port number has been used in any of the lists then
230          * it is not available
231          *
232          * @param   iPortNumber  Device port number
233          * @return  boolean
234          */
235         public boolean portIsAvailable(int iPortNumber) {
236
237                 if (hmComPort.containsValue(iPortNumber) == true) {
238                         return false;
239                 } else if (hmRMIRegPort.containsValue(iPortNumber) == true) {
240                         return false;
241                 } else if (hmRMIStubPort.containsValue(iPortNumber) == true) {
242                         return false;
243                 } else if (hsDevicePort.contains(iPortNumber) == true) {
244                         return false;
245                 } else if (hsCallbackPort.contains(iPortNumber) == true) {
246                         return false;
247                 } else {
248                         return true;
249                 }
250         }
251
252         /**
253          * Method getNumOfObjects()
254          *
255          * @return  int
256          */
257         public int getNumOfObjects() {
258
259                 return iNumOfObjects;
260
261         }
262
263         /**
264          * Method getNumOfHosts()
265          *
266          * @return  int
267          */
268         public int getNumOfHosts() {
269
270                 return iNumOfHosts;
271
272         }
273
274         /**
275          * Method objectExists()
276          *
277          * @param   sObjName  String object name
278          * @return  boolean
279          */
280         public boolean objectExists(String sObjName) {
281
282                 return hmActiveObj.containsKey(sObjName);
283
284         }
285
286         /**
287          * Method hostExists()
288          *
289          * @param   sHostName  String host name
290          * @return  boolean
291          */
292         public boolean hostExists(String sHostName) {
293
294                 return hmHostList.containsKey(sHostName);
295
296         }
297
298         /**
299          * Method getHostAddress()
300          * <p>
301          * User finds HostAddress using Object name
302          *
303          * @param   sAObject  String active object name
304          * @return  String
305          */
306         public String getHostAddress(String sAObject) {
307
308                 return hmHostAdd.get(hmActiveObj.get(sAObject));
309
310         }
311
312         /**
313          * Method getHosts()
314          * <p>
315          * User gets the set of hostnames
316          *
317          * @return  String
318          */
319         public Set<String> getHosts() {
320
321                 return hmHostList.keySet();
322
323         }
324
325         /**
326          * Method getComPort()
327          * <p>
328          * User finds In-Port number using Object name
329          *
330          * @param   sAObject  String active object name
331          * @return  Integer
332          */
333         public Integer getComPort(String sAObject) {
334
335                 return hmComPort.get(hmActiveObj.get(sAObject));
336         }
337
338         /**
339          * Method getRMIRegPort()
340          * <p>
341          * User finds Out-Port number using Object name
342          *
343          * @param   sAObject  String active object name
344          * @return  Integer
345          */
346         public Integer getRMIRegPort(String sAObject) {
347
348                 return hmRMIRegPort.get(hmActiveObj.get(sAObject));
349
350         }
351
352         /**
353          * Method getRMIStubPort()
354          * <p>
355          * User finds Out-Port number using Object name
356          *
357          * @param   sAObject  String active object name
358          * @return  Integer
359          */
360         public Integer getRMIStubPort(String sAObject) {
361
362                 return hmRMIStubPort.get(hmActiveObj.get(sAObject));
363
364         }
365
366         /**
367          * Method getFieldObjectID()
368          * <p>
369          * User finds field object ID using Object name
370          *
371          * @param   sAObject  String active object name
372          * @return  String
373          */
374         public String getFieldObjectID(String sAObject) {
375
376                 return listFieldObjectID.get(listActiveControllerObj.indexOf(sAObject));
377
378         }
379
380         /**
381          * Method getObjectCreationInfo()
382          * <p>
383          * User finds ObjectCreationInfo using Object name
384          *
385          * @param   sAObject  String active object name
386          * @return  ObjectCreationInfo
387          */
388         public ObjectCreationInfo getObjectCreationInfo(String sAObject) {
389
390                 return listObjCrtInfo.get(listActiveControllerObj.indexOf(sAObject));
391
392         }
393
394         /**
395          * Method getArrayFieldClasses()
396          * <p>
397          * User finds array of field classes using Object name
398          *
399          * @param   sAObject  String active object name
400          * @return  Class[]
401          */
402         public Class[] getArrayFieldClasses(String sAObject) {
403
404                 return listArrFieldClasses.get(listActiveControllerObj.indexOf(sAObject));
405
406         }
407
408         /**
409          * Method getArrayFieldValues()
410          * <p>
411          * User finds array of field values using Object name
412          *
413          * @param   sAObject  String active object name
414          * @return  Object[]
415          */
416         public Object[] getArrayFieldValues(String sAObject) {
417
418                 return listArrFieldValues.get(listActiveControllerObj.indexOf(sAObject));
419
420         }
421
422         /**
423          * Method getActiveControllerObjectList()
424          *
425          * @return  List<String>
426          */
427         public List<String> getActiveControllerObjectList() {
428
429                 return listActiveControllerObj;
430
431         }
432
433         /**
434          * Method printLists()
435          *
436          * @return  void
437          */
438         public void printLists() {
439
440                 // Iterate on HostAddress
441                 for(String s : hmHostList.keySet()) {
442
443                         for(String str : hmHostList.get(s)) {
444
445                                 int iIndex = hmActiveObj.get(str);
446                                 RuntimeOutput.print("Active Object: " + str, bVerbose);
447                                 RuntimeOutput.print("Communication Port: " + hmComPort.get(iIndex), bVerbose);
448                                 RuntimeOutput.print("RMI Registry Port: " + hmRMIRegPort.get(iIndex), bVerbose);
449                                 RuntimeOutput.print("RMI Stub Port: " + hmRMIStubPort.get(iIndex), bVerbose);
450                         }
451                 }
452
453                 for(int iPort : hsDevicePort) {
454
455                         RuntimeOutput.print("Device Port: " + iPort, bVerbose);
456
457                 }
458         }
459 }