/* * "Copyright (c) 2010-11 The Regents of the University of California. * All rights reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose, without fee, and without written agreement is * hereby granted, provided that the above copyright notice, the following * two paragraphs and the author appear in all copies of this software. * * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." * * Author: Jorge Ortiz (jortiz@cs.berkeley.edu) * IS4 release version 1.0 */ package is4; import local.db.*; import is4.*; import is4.exceptions.*; import net.sf.json.*; import java.util.*; import java.lang.String; import java.lang.NullPointerException; import java.io.*; import java.util.logging.Logger; import java.util.logging.Level; public class Registrar implements Serializable{ protected static Registrar registrar = null; protected static Hashtable<String,JoinInfoTuple> regTable = new Hashtable<String,JoinInfoTuple>(); protected static Hashtable<UUID,String> keyTable = new Hashtable<UUID,String>(); protected static String IS4HOME=null; protected static String regObjPath = "/.state/Registrar.obj"; protected static String regTableObjPath = "/.state/rt.obj"; protected static String keyTableObjPath = "/.state/kt.obj"; protected static transient final Logger logger = Logger.getLogger(Registrar.class.getPackage().getName()); private static boolean initialized = false; private Registrar(){ } /* * Returns the single instance of the registrar object. */ public static Registrar registrarInstance() { //loadIs4State(); /*File f1 = new File(regObjPath); File f2 = new File(regTableObjPath); File f3 = new File(keyTableObjPath); if(registrar == null && !f1.exists()) { registrar = new Registrar(); //System.out.println("New Registrar"); logger.info("New Registrar"); } else if (f1.exists() && registrar == null) { try{ FileInputStream fileIn = new FileInputStream(f1); ObjectInputStream in = new ObjectInputStream(fileIn); registrar = (Registrar)in.readObject(); logger.info("Previous Registrar instance saved, loading..."); fileIn = new FileInputStream(f2); in = new ObjectInputStream(fileIn); regTable = (Hashtable<String, JoinInfoTuple>)in.readObject(); fileIn = new FileInputStream(f3); in = new ObjectInputStream(fileIn); keyTable = (Hashtable<UUID,String>)in.readObject(); //System.out.println("Loaded registrar"); logger.info("Loaded registrar"); }catch(Exception e){ e.printStackTrace(); logger.log(Level.SEVERE, "Exception while loading previous Registrar state", e); System.exit(1); } //System.out.println("regTable size: " + registrar.regTable.size()); //System.out.println("keyTable size: " + registrar.keyTable.size()); */ if(!initialized){ loadIs4State(); registrar = new Registrar(); databaseSync(); } return registrar; } protected static void loadIs4State() throws NullPointerException{ String home = System.getenv().get("IS4HOME"); if(IS4HOME == null && home !=null && !home.equals("")){ IS4HOME = home; regObjPath = IS4HOME + regObjPath; regTableObjPath = IS4HOME + regTableObjPath; keyTableObjPath = IS4HOME + keyTableObjPath; } else if(IS4HOME == null && home ==null || home.equals("")){ NullPointerException e = new NullPointerException("Registar: IS4HOME environment variable must be set!"); logger.log(Level.SEVERE, "Environment variable not set", e); throw e; } } protected static void databaseSync(){ try{ JSONObject publishersJson = ((MySqlDriver)DBAbstractionLayer.database).getPublishersTable(); Set<String> allPubIdsSet = publishersJson.keySet(); Iterator<String> allPubIdIterator = allPubIdsSet.iterator(); while(allPubIdIterator.hasNext()){ String thisPubId = allPubIdIterator.next(); UUID pubuuid = UUID.fromString(thisPubId); //put in keyTable keyTable.put(pubuuid, publishersJson.getString(thisPubId)); //put in regTable Date date = new Date(); JoinInfoTuple jit = new JoinInfoTuple(pubuuid, date.getTime()/1000); regTable.put(publishersJson.getString(thisPubId), jit); } //save object state saveState(); initialized = true; return; } catch(Exception e){ logger.log(Level.WARNING, "", e); } initialized = false; } /* * Checks if the given object is registered in the system.a * * @param name the assocaite unique id received by the object or device after * registration. * * @returns true if registered, false if not. */ public boolean isRegisteredName(String name){ logger.info("Checking if " + name + " is registered"); checkDatabaseName(name); return regTable.containsKey(name); } /* * Checks if the publisher with the given registration/publisher id * is currently registered with the system. */ /*public boolean isRegistered(UUID pubId){ //System.out.println("Checking registration"); logger.info("Checking if publisher with pudId: " + pubId.toString() + " is registered"); return keyTable.containsKey(pubId); }*/ public boolean isRegisteredId(String pubId){ try{ logger.info("Checking if publisher with pudId: " + pubId.toString() + " is registered"); checkDatabaseId(pubId); UUID pubIdUUID = UUID.fromString(pubId); return keyTable.containsKey(pubIdUUID); } catch(IllegalArgumentException e){ logger.log(Level.WARNING, pubId + " is an invalid UUID", e); return false; } } /* * Unregisters the publisher with the given publisher/registration id. */ public synchronized void unregisterDevice(String regId){ logger.info("Removing publisher: " + regId); try { UUID regIdUUID = UUID.fromString(regId); String name = keyTable.get(regIdUUID); String removedKTV = keyTable.remove(regIdUUID); JoinInfoTuple removedRTV = null; if(name!=null){ removedRTV=regTable.remove(name); if(removedRTV==null) logger.warning("Associated value for publisher " + regId + " is null"); else logger.fine("Removing publisher " + regId + ": [" + name + ": " + removedRTV.toString() + "]"); } else { logger.warning("The \"name\" associated with " + regId + " is null"); } //save object state saveState(); } catch (IllegalArgumentException e) { logger.log(Level.WARNING, "Invalid UUID format: " + regId + "\nCould not remove device", e); saveState(); } } /** * Unregisters the give publisher with the given id. */ /*public synchronized void unregisterDevice(UUID regIdUUID){ this.unregisterDevice(regIdUUID.toString()); }*/ public void checkDatabaseId(String pid){ try { String name = null; if((name = ((MySqlDriver)DBAbstractionLayer.database).getName(pid)) != null){ //register the device Date date = new Date(); UUID Pid = UUID.fromString(pid); JoinInfoTuple jit = new JoinInfoTuple(Pid, date.getTime()/1000); regTable.put(name, jit); keyTable.put(Pid, name); logger.fine("adding " + name + ":" + jit.toString()); //save object state saveState(); } } catch(Exception e) { logger.log(Level.WARNING, "",e); } } public void checkDatabaseName(String name){ try { String pid= null; if((pid= ((MySqlDriver)DBAbstractionLayer.database).getPid(name)) != null){ UUID Pid = UUID.fromString(pid); //register the device Date date = new Date(); JoinInfoTuple jit = new JoinInfoTuple(Pid, date.getTime()/1000); regTable.put(name, jit); keyTable.put(Pid, name); logger.fine("adding " + name + ":" + jit.toString()); //save object state saveState(); } } catch(Exception e){ logger.log(Level.WARNING, "", e); } } /* * Register the device by name given by String parameter. Returns the associated * unique registration id to be used for future communication. */ public synchronized String registerDevice(String name) throws NameRegisteredException, NoMoreRegistrantsException{ /*if(regTable.containsKey(name)) throw new NameRegisteredException();*/ UUID newId = UUID.randomUUID(); //make sure there's no collisions -- chances are there will be 0 collisions int loopMax = 10000; int loopCount=0; while(keyTable.containsKey(newId) && loopCount < 10000) newId = UUID.randomUUID(); if(loopCount >= loopMax) throw new NoMoreRegistrantsException(); //keyTable.put(newId, name); ///////////////////////////////////////////////////////////////////////////// //register the device Date date = new Date(); JoinInfoTuple jit = new JoinInfoTuple(newId, date.getTime()/1000); regTable.put(name, jit); keyTable.put(newId, name); // logger.fine("adding " + name + ":" + jit.toString()); //save object state //saveState(); return newId.toString(); } /*public synchronized void unregisterDevice(String name){ JoinInfoTuple jit = regTable.remove(name); logger.fine("removing " + name + ": " + jit.toString() + " in Registrar"); //save object state saveState(); }*/ /*public List<UUID> getPubIds(){ Set<UUID> keySet = keyTable.keySet(); if(keySet != null){ ArrayList<UUID> keyList = new ArrayList<UUID>(keySet); logger.fine("Getting PubId list; size="+ keyList.size()); return (List<UUID>) keyList; } return (List<UUID>)keySet; }*/ public List<String> getPubIds() {//Str() { ArrayList<UUID> uuidList = null; Set<UUID> keySet = keyTable.keySet(); ArrayList<UUID> keyList = new ArrayList<UUID>(keySet); if(keySet != null) uuidList=(ArrayList<UUID>) keyList; else return new ArrayList<String>(); ArrayList<String> uuidListStr = new ArrayList<String>(); for(int i=0; i<uuidList.size(); i++) uuidListStr.add(uuidList.get(i).toString()); logger.fine("Getting PubId list; size="+ uuidListStr.size()); return (List<String>)uuidListStr; } public synchronized static void saveState(){ /*try { FileOutputStream fileOut = new FileOutputStream(regObjPath); ObjectOutputStream out = new ObjectOutputStream(fileOut); out.writeObject(registrar); fileOut = new FileOutputStream(regTableObjPath); out = new ObjectOutputStream(fileOut); out.writeObject(regTable); fileOut = new FileOutputStream(keyTableObjPath); out = new ObjectOutputStream(fileOut); out.writeObject(keyTable); //System.out.println("Wrote objects"); logger.info("Wrote objectes"); } catch(Exception e) { //e.printStackTrace(); logger.log(Level.SEVERE, "Likely and IOException while writing objects", e); }*/ } }