/* * ALMA - Atacama Large Millimiter Array * (c) European Southern Observatory, 2002 * Copyright by ESO (in the framework of the ALMA collaboration), * All rights reserved * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * Created on Apr 3, 2007 * */ package com.cosylab.cdb.jdal; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.StringReader; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Random; import java.util.Set; import java.util.StringTokenizer; import java.util.TreeSet; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; import java.util.logging.Level; import java.util.logging.Logger; import javax.persistence.EnumType; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.exolab.castor.net.URILocation; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.Transaction; import org.hibernate.criterion.Restrictions; import org.hibernate.criterion.Criterion; import org.omg.CORBA.NO_IMPLEMENT; import org.omg.CORBA.NO_RESOURCES; import org.omg.CORBA.ORB; import org.omg.PortableServer.IdAssignmentPolicyValue; import org.omg.PortableServer.POA; import org.omg.PortableServer.Servant; import org.w3c.dom.DOMError; import org.w3c.dom.DOMErrorHandler; import org.w3c.dom.DOMException; import org.w3c.dom.bootstrap.DOMImplementationRegistry; import org.w3c.dom.ls.DOMImplementationLS; import org.w3c.dom.ls.LSException; import org.w3c.dom.ls.LSInput; import org.w3c.dom.ls.LSOutput; import org.w3c.dom.ls.LSParser; import org.w3c.dom.ls.LSResourceResolver; import org.xml.sax.InputSource; import alma.ACSErrTypeCommon.wrappers.AcsJIllegalArgumentEx; import alma.Logging.IllegalLogLevelsEx; import alma.Logging.LoggerDoesNotExistEx; import alma.Logging.LoggingConfigurablePackage.LogLevels; import alma.TMCDB.baci.BACIPropertyType; import alma.TMCDB.baci.ComponentData; import alma.TMCDB.baci.EmptyStringHandlerBACIPropertyType; import alma.TMCDB.maci.Channels; import alma.TMCDB.maci.EventChannelNode; import alma.acs.logging.AcsLogLevel; import alma.acs.logging.ClientLogManager; import alma.acs.logging.config.LogConfig; import alma.acs.logging.config.LogConfigException; import alma.acs.logging.level.AcsLogLevelDefinition; import alma.acs.tmcdb.AcsService; import alma.acs.tmcdb.AcsServiceServiceType; import alma.acs.tmcdb.BACIPropArchMech; import alma.acs.tmcdb.BACIProperty; import alma.acs.tmcdb.ChannelMapping; import alma.acs.tmcdb.Component; import alma.acs.tmcdb.ComponentType; import alma.acs.tmcdb.Computer; import alma.acs.tmcdb.ComputerProcessorType; import alma.acs.tmcdb.Configuration; import alma.acs.tmcdb.Container; import alma.acs.tmcdb.ContainerStartupOption; import alma.acs.tmcdb.DomainsMapping; import alma.acs.tmcdb.Event; import alma.acs.tmcdb.EventChannel; import alma.acs.tmcdb.EventChannelConReliability; import alma.acs.tmcdb.EventChannelDiscardPolicy; import alma.acs.tmcdb.EventChannelEventReliability; import alma.acs.tmcdb.EventChannelOrderPolicy; import alma.acs.tmcdb.ImplLangEnum; import alma.acs.tmcdb.LoggingConfig; import alma.acs.tmcdb.Manager; import alma.acs.tmcdb.NamedLoggerConfig; import alma.acs.tmcdb.NotificationServiceMapping; import alma.acs.tmcdb.Schemas; import alma.acs.tmcdb.logic.ContainerStartupOptionHelper; import alma.cdbErrType.CDBExceptionEx; import alma.cdbErrType.CDBFieldDoesNotExistEx; import alma.cdbErrType.CDBFieldIsReadOnlyEx; import alma.cdbErrType.CDBRecordAlreadyExistsEx; import alma.cdbErrType.CDBRecordDoesNotExistEx; import alma.cdbErrType.CDBRecordIsReadOnlyEx; import alma.cdbErrType.CDBXMLErrorEx; import alma.cdbErrType.WrongCDBDataTypeEx; import alma.cdbErrType.wrappers.AcsJCDBExceptionEx; import alma.cdbErrType.wrappers.AcsJCDBFieldDoesNotExistEx; import alma.cdbErrType.wrappers.AcsJCDBRecordDoesNotExistEx; import alma.cdbErrType.wrappers.AcsJCDBXMLErrorEx; import alma.cdbErrType.wrappers.AcsJWrongCDBDataTypeEx; import alma.maci.loggingconfig.UnnamedLogger; import com.cosylab.CDB.DAL; import com.cosylab.CDB.DALChangeListener; import com.cosylab.CDB.DALChangeListenerHelper; import com.cosylab.CDB.DAO; import com.cosylab.CDB.DAOHelper; import com.cosylab.CDB.DAOOperations; import com.cosylab.CDB.DAOPOA; import com.cosylab.CDB.DAOPOATie; import com.cosylab.CDB.JDAL; import com.cosylab.CDB.JDALHelper; import com.cosylab.CDB.WDAO; import com.cosylab.CDB.WDAOHelper; import com.cosylab.CDB.WDAOPOA; import com.cosylab.CDB.WDAOPOATie; import com.cosylab.CDB.WJDALPOA; import com.cosylab.CDB.WJDALPOATie; import com.cosylab.cdb.client.CDBAccess; import com.cosylab.cdb.client.DAOProxy; import com.cosylab.cdb.jdal.hibernate.DOMJavaClassIntrospector; import com.cosylab.cdb.jdal.hibernate.ExtraDataFeatureUtil; import com.cosylab.cdb.jdal.hibernate.HibernateDBUtil; import com.cosylab.cdb.jdal.hibernate.HibernateUtil; import com.cosylab.cdb.jdal.hibernate.RootMap; import com.cosylab.cdb.jdal.hibernate.DOMJavaClassIntrospector.XMLSaver; import com.cosylab.cdb.jdal.hibernate.plugin.HibernateWDALPlugin; import com.cosylab.cdb.jdal.hibernate.plugin.PluginFactory; import com.cosylab.util.FileHelper; /** * WDAL implementation for hibernate w/ DOMJavaClassInspector. * @author msekoranja */ @SuppressWarnings("unchecked") public class HibernateWDALImpl extends WJDALPOA implements Recoverer { static final String TMCDB_CONFIGURATION_NAME_KEY = "TMCDB_CONFIGURATION_NAME"; static final String TMCDB_COMPONENT_TREE_NAME_KEY = "TMCDB_COMPONENT_TREE_NAME"; static final String COMPONENT_TREE_NAME = System.getProperty(TMCDB_COMPONENT_TREE_NAME_KEY, "alma"); static final boolean TMCDB_ACS_ONLY = Boolean.getBoolean("cdb_rdb.acsOnly"); // a DAL is always valid for *one* configuration: protected String configName = null; protected int configId = -1; protected Configuration config = null; protected final HibernateUtil hibernateUtil; protected final HibernateDBUtil hibernateDBUtil; protected volatile Session mainSession = null; final static String DUMMY_CONTAINER_FLAG = "dummy"; protected boolean loadXMLCDB = false; protected boolean createTables = false; protected boolean forceInMemory = false; protected String[] args; protected ORB orb; protected POA poa; private final HashMap<String, DAO> daoMap = new HashMap<String, DAO>(); private final HashMap wdaoMap = new HashMap(); private HashMap daoObjMap = new HashMap(); private HashMap wdaoObjMap = new HashMap(); // clean cache implementation private HashMap<String, ArrayList<Integer>> listenedCurls = new HashMap<String, ArrayList<Integer>>(); private File listenersStorageFile = null; private Random idPool = new Random(); private HashMap<Integer, DALChangeListener> regListeners = new HashMap<Integer, DALChangeListener>(); private boolean recoveryRead = true; protected final Logger m_logger; protected volatile Object rootNode; protected SAXParser saxParser; protected LSParser parser; protected LSInput input; protected LSOutput output; protected DOMImplementationLS domImplementationLS; protected SchemaResourceResolverLoader schemaResourceResolverLoader; protected HibernateWDALPlugin plugin; private final AtomicBoolean loadInProgress = new AtomicBoolean(false); private String m_root = "CDB"; private final Object xmlNodeMonitor = new Object(); private AtomicBoolean shutdown = new AtomicBoolean(false); private AtomicLong lastSaveTime = new AtomicLong(0); private AtomicBoolean saveRequest = new AtomicBoolean(false); /** * ctor that takes all command line args given to OracleServer * @param args * @param orb_val * @param poa_val */ public HibernateWDALImpl(String args[], ORB orb, POA poa, Logger logger) { this.args = args; this.orb = orb; this.poa = poa; m_logger = logger; hibernateUtil = HibernateUtil.getInstance(logger); // read args for (int i = 0; i < args.length; i++) if (args[i].equals("-n")) { recoveryRead = false; } else if (args[i].equals("-configName")) { if (i < args.length - 1) configName = args[++i]; } else if (args[i].equals("-root")) { if (i < args.length - 1) { m_root = args[++i] + "/CDB"; } } else if (args[i].equals("-loadXMLCDB")) { loadXMLCDB = true; } else if (args[i].equals("-createTables")) { createTables = true; } else if (args[i].equals("-memory")) { forceInMemory = true; createTables = true; loadXMLCDB = true; } else if (args[i].equals("-jvmPropCfg")) { System.getProperties().remove(PluginFactory.CONFIGURATION_WDAL_PLUGIN_KEY); } else if (args[i].equals("-help") || args[i].equals("-h")) { System.out.println("usage: java " + this.getClass().getName() + " [options]"); System.out.println("\t-root\t\tXML CDB root (used on XML import)"); System.out.println("\t-configName\tconfiguration name to be used to insert/query"); System.out.println("\t-loadXMLCDB\timport XML CDB into RDB"); System.out.println("\t-createTables\tcreate tables into RDB"); System.out.println("\t-memory\t\tforce usage of in-memory RDB (implies -loadXMLCDB and -createTables)"); System.out.println("\t-jvmPropCfg\tforce default configuration plugin (JVM properties)"); System.exit(1); } if (TMCDB_ACS_ONLY) m_logger.info("Started in ACS only mode."); File rootF = new File(m_root); m_root = rootF.getAbsolutePath() + '/'; // TODO: Does the "root" make any sense if we do not import XML data? // Perhaps then we should not log this message, just for a dummy root "CDB" m_logger.log(AcsLogLevel.INFO, "HibernateDAL root is: " + m_root); if (configName == null) { m_logger.fine("No configuration name specified, trying '" + TMCDB_CONFIGURATION_NAME_KEY + "' environment variable."); configName = System.getProperty(TMCDB_CONFIGURATION_NAME_KEY, System.getenv(TMCDB_CONFIGURATION_NAME_KEY)); //if (configName == null) // throw new RuntimeException("Configuration name not specified. Must be set with command line arg -configName followed by a string or by environment varibale '" + TMCDB_CONFIGURATION_NAME_KEY + "'."); if (configName == null) { m_logger.log(AcsLogLevel.NOTICE, "ERROR: Configuration name not specified. Must be set with command line arg -configName followed by a string or by environment variable '" + TMCDB_CONFIGURATION_NAME_KEY + "'."); System.exit(1); } m_logger.config("Configuration name obtained from environment variable."); } m_logger.info("Using TMCDB Configuration '" + configName + "'."); initializeParser(); plugin = PluginFactory.getPlugin(m_logger); hibernateDBUtil = new HibernateDBUtil(logger, plugin); // set-up connection // in-memory can be configured from outside, therefore "feedback" for forceInMemory forceInMemory = hibernateDBUtil.setUp(forceInMemory, createTables); if (loadXMLCDB) { if (!loadXMLCDB(args, orb, poa, configName)) System.exit(1); } startRecoverySaver(); load(); } /** * Specialization of resource handler that loads all needed resources (schemas) into RDB. */ class SchemaResourceResolverLoader implements LSResourceResolver { private DOMImplementationLS domImplementationLS; private XSDElementTypeResolver xsdElementTypeResolver; private Session session = null; public SchemaResourceResolverLoader(Session session, DOMImplementationLS domImplementationLS, Logger logger) { this.domImplementationLS = domImplementationLS; this.session = session; try { xsdElementTypeResolver = new XSDElementTypeResolver(m_root, logger); } catch (Throwable tx) { throw new RuntimeException("Failed to instantiate " + this.getClass().getName(), tx); } } /** * @param session the session to set */ public void setSession(Session session) { this.session = session; } public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI) { //System.err.println("==== Resolving '" + type + "' '" + namespaceURI + "' '" + publicId + "' '" + systemId + "' '" + baseURI + "'"); if (namespaceURI == null) { System.err.println("SchemaResourceResolverLoader#resolveResource: namespaceURI=null found for baseURI=" + baseURI + ", type=" + type); return null; } try { String schema = null; Schemas schemaRecord = (Schemas)session.createCriteria(Schemas.class) .add(Restrictions.eq("URN", namespaceURI)).add(Restrictions.eq("configuration", config)).uniqueResult(); if (schemaRecord != null) schema = schemaRecord.getSchema(); // .. read store it into RDB, if not already there if (schema == null) { URILocation loc = xsdElementTypeResolver.getUriResolver().resolveURN(namespaceURI); if (loc != null) { final BufferedReader reader = new BufferedReader(loc.getReader()); final StringBuffer file = new StringBuffer(); String line; while ((line = reader.readLine()) != null) file.append(line).append('\n'); schema = file.toString(); schemaRecord = new Schemas(); schemaRecord.setURN(namespaceURI); schemaRecord.setConfiguration(config); schemaRecord.setSchema(schema); session.persist(schemaRecord); } else return null; } // return schema LSInput ret = domImplementationLS.createLSInput(); ret.setStringData(schema); return ret; } catch (Throwable th) { th.printStackTrace(); return null; } } } private void initializeParser() throws RuntimeException { try { System.setProperty(DOMImplementationRegistry.PROPERTY, "org.apache.xerces.dom.DOMImplementationSourceImpl"); DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance(); domImplementationLS = (DOMImplementationLS) registry.getDOMImplementation("LS"); parser = domImplementationLS.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, "http://www.w3.org/2001/XMLSchema"); //parser.getDomConfig().setParameter("http://apache.org/xml/features/xinclude", Boolean.TRUE); schemaResourceResolverLoader = new SchemaResourceResolverLoader(null, domImplementationLS, m_logger); parser.getDomConfig().setParameter("resource-resolver", schemaResourceResolverLoader); parser.getDomConfig().setParameter("http://apache.org/xml/features/validation/schema", Boolean.TRUE); parser.getDomConfig().setParameter("error-handler", new DOMErrorHandler() { public boolean handleError(DOMError error) { //((Exception) error.getRelatedException()).printStackTrace(); throw new LSException(LSException.PARSE_ERR, error.getMessage()); } }); input = domImplementationLS.createLSInput(); output = domImplementationLS.createLSOutput(); // SAX parser (non-validating) SAXParserFactory factory = SAXParserFactory.newInstance(); saxParser = factory.newSAXParser(); } catch (Throwable th) { throw new RuntimeException("Failed to initialize parser.", th); } } private synchronized void reloadData() { // full XML reload works only with in-memory DB // for external DBs, existing data should have been removed from the DB... if (forceInMemory) { // in-memory HSQLDB only, shutdown DB m_logger.info("Will shutdown the in-memory HSQLDB..."); try { try { hibernateUtil.beginTransaction(); Session session = hibernateUtil.getSession(); session.createSQLQuery("SHUTDOWN IMMEDIATELY").executeUpdate(); } finally { hibernateUtil.closeSession(); } } catch (Throwable th) { m_logger.log(Level.WARNING, "Failed to shutdown in-memory HSQLDB.", th); } if (hibernateUtil.getSessionFactory() != null) hibernateUtil.getSessionFactory().close(); m_logger.info("Will re-create the in-memory HSQLDB..."); hibernateDBUtil.setUp(forceInMemory, createTables); if (loadXMLCDB) { m_logger.info("Will reload XML CDB data..."); loadXMLCDB(args, orb, poa, configName); } } else { try { // clear Hibernate session (cache) hibernateUtil.getSession().clear(); } catch (Throwable th) { m_logger.log(Level.WARNING, "Failed to clear the hibernate session cache.", th); } } load(); m_logger.info("Successfully reloaded all data."); } private void load() { // HSO TODO: If this is a re-don't, we need to wait until any other IDL methods have finished, // which entered because loadInProgress was false ? loadInProgress.set(true); try { mainSession = hibernateUtil.getSession(); // reload config = resolveConfig(mainSession, configName); configId = config.getConfigurationId(); initializeRootNode(); // we do not close session (needed by WDAL) } catch (Throwable th) { m_logger.log(Level.SEVERE, "Failed to load TMCDB data from the relational database.", th); // @TODO use checked ex throw new RuntimeException("Failed to load data.", th); } finally { loadInProgress.set(false); } } private Configuration resolveConfig(Session session, String configName) { try { Configuration config = (Configuration)session.createCriteria(Configuration.class). add(Restrictions.eq("configurationName", configName)).uniqueResult(); if (config != null) return config; else throw new RuntimeException("Configuration with name '" + configName + "' does not exist."); } catch (Throwable th) { throw new RuntimeException("Failed to resolve configuration from name '" + configName + "'.", th); } } private static final String readString(DAOOperations dao, String name, String defaultValue) { try { return dao.get_string(name); } catch (Throwable th) { return defaultValue; } } private static final String[] readStringSeq(DAOOperations dao, String name, String[] defaultValue) { try { return dao.get_string_seq(name); } catch (Throwable th) { return defaultValue; } } private static final int readLong(DAOOperations dao, String name, int defaultValue) { try { return dao.get_long(name); } catch (Throwable th) { return defaultValue; } } private static final double readDouble(DAOOperations dao, String name, double defaultValue) { try { return dao.get_double(name); } catch (Throwable th) { return defaultValue; } } private static final Double readDouble(DAOOperations dao, String name, Double defaultValue) { try { return dao.get_double(name); } catch (Throwable th) { return defaultValue; } } private static final Float readFloat(DAOOperations dao, String name, Float defaultValue) { try { return new Float(dao.get_double(name)); } catch (Throwable th) { return defaultValue; } } public String[] getSubNodes(DAL dal, String subnode) throws Throwable { ArrayList subnodes = new ArrayList(); LinkedList stack = new LinkedList(); stack.addLast(subnode); while (!stack.isEmpty()) { String parentNode = stack.removeLast().toString(); String nodes = dal.list_nodes(parentNode); if (nodes.length() > 0) { StringTokenizer tokenizer = new StringTokenizer(nodes); while (tokenizer.hasMoreTokens()) { String nodeName = tokenizer.nextToken(); if (nodeName.endsWith(".xml")) continue; String fullName = parentNode + "/" + nodeName; stack.addLast(fullName); // strip off relative path subnodes.add(fullName.substring(subnode.length()+1)); } } } String[] retVal = new String[subnodes.size()]; subnodes.toArray(retVal); return retVal; } // NOTE: throw NO_RESOURCES is thrown, since there is no common exception for all CORBA calls private final void checkAccess() throws NO_RESOURCES { if (loadInProgress.get()) { m_logger.warning("Incoming Corba call denied (NO_RESOURCES) because data is being loaded."); throw new NO_RESOURCES("load in progress"); } } private void loadSchemas(Session session) throws Throwable { String schemas = DALImpl.getSchemas(m_root, m_logger); if (schemas == null) return; StringTokenizer tokenizer = new StringTokenizer(schemas); while (tokenizer.hasMoreTokens()) { String urn = tokenizer.nextToken(); String fileName = tokenizer.nextToken(); // ignore all DTDs and files ending with XMLSchema.xsd if (fileName.toLowerCase().endsWith(".dtd") || fileName.endsWith("XMLSchema.xsd")) continue; Schemas schemaRecord = null; try { schemaRecord = (Schemas) session.createCriteria(Schemas.class). add(Restrictions.eq("URN", urn)). add(Restrictions.eq("configuration", config)). uniqueResult(); } catch (HibernateException ex) { // adding this to better understand a java.sql.BatchUpdateException: ORA-31001: Invalid resource handle or path name "/XMLSchema.dtd" m_logger.log(Level.INFO, "Failed to select (check existence of) schema with URN='" + urn + "' in the database. The schema file to load would be " + fileName); throw ex; } if (schemaRecord == null) { final BufferedReader reader = new BufferedReader(new FileReader(fileName)); final StringBuffer file = new StringBuffer(); String line; while ((line = reader.readLine()) != null) file.append(line).append('\n'); schemaRecord = new Schemas(); schemaRecord.setURN(urn); schemaRecord.setConfiguration(config); schemaRecord.setSchema(file.toString()); session.persist(schemaRecord); } } } final int NULL_ID = 0; //final Integer NULL_ID = null; protected boolean loadXMLCDB(String args[], ORB orb, POA poa, String configName) { m_logger.info("Reading configuration from XML CDB..."); try { loadInProgress.set(true); /* create new poa for xmlCDB */ org.omg.CORBA.Policy[] policies = new org.omg.CORBA.Policy[] { poa.create_id_assignment_policy(IdAssignmentPolicyValue.USER_ID) }; POA xmlCDBPOA = poa.create_POA("xmlCDBPOA", poa.the_POAManager(), policies); for (int i = 0; i < policies.length; i++) policies[i].destroy(); // disable cache for XML CDB DAL (important) String[] newArgs = new String[args.length+2]; System.arraycopy(args, 0, newArgs, 0, args.length); newArgs[args.length] = "-disableRecoveryFile"; newArgs[args.length+1] = "-disableCache"; final WDALImpl servantDelegate = new WDALImpl(newArgs, orb, xmlCDBPOA, m_logger); final Servant wdalImplServant = new WJDALPOATie(servantDelegate); // WDALImpl wdalImplServant = new WDALImpl(args, orb, xmlCDBPOA, m_logger); xmlCDBPOA.activate_object_with_id(new byte[] { 'x', 'm', 'l', 'C', 'D', 'B' }, wdalImplServant); org.omg.CORBA.Object ref = xmlCDBPOA.servant_to_reference(wdalImplServant); final JDAL xmlCDB_ = JDALHelper.narrow(ref); // ----- // get set of BACI property attributes (non-extras) String[] baciPropertyAttributes = DOMJavaClassIntrospector.getAccessibleFields(new BACIPropertyType(), true); Set<String> baciPropertyAttributesSet = new HashSet<String>(); for (String attribute : baciPropertyAttributes) { baciPropertyAttributesSet.add(attribute); } XSDElementTypeResolver xsdElementTypeResolver = new XSDElementTypeResolver(m_root, m_logger); Set<String> nonControlDeviceSet = new TreeSet<String>(); Set<String> characteristicsDeviceSet = new TreeSet<String>(); Set<String> processedComponentTypes = new HashSet<String>(); // ----- CDBAccess cdbAccess = new CDBAccess(orb, m_logger); cdbAccess.setDAL(xmlCDB_); try { hibernateUtil.beginTransaction(); Session session = hibernateUtil.getSession(); schemaResourceResolverLoader.setSession(session); // check if configuration already exists config = (Configuration)session.createCriteria(Configuration.class). add(Restrictions.eq("configurationName", configName)).uniqueResult(); if (config != null) { m_logger.warning("Configuration with name '" + configName + "' already exists. Skipping loading XML stage."); return false; } // create configuration config = new Configuration(); config.setConfigurationName(configName); config.setFullName(configName); config.setActive(true); config.setCreationTime(Calendar.getInstance().getTime()); config.setDescription("Imported from CDB by HibernateWDAL"); session.persist(config); configId = config.getConfigurationId(); // plugin importPrologue() if (plugin != null) { try { plugin.importPrologue(session, config, cdbAccess); } catch (Throwable th) { // @TODO decent exception log. Is OK to swallow th? th.printStackTrace(); } } // load all schemas loadSchemas(session); try { //DAO managerDAO = xmlCDB.get_DAO_Servant("MACI/Managers/Manager"); DAOProxy managerDAO = cdbAccess.createDAO("MACI/Managers/Manager"); LoggingConfig managerLoggingConfig = persistLoggingConfig(session, managerDAO, false); Manager manager = new Manager(); manager.setConfiguration(config); manager.setLoggingConfig(managerLoggingConfig); manager.setStartup(managerDAO.get_string("Startup")); manager.setServiceComponents(managerDAO.get_string("ServiceComponents")); try { manager.setServiceDaemons(managerDAO.get_string("ServiceDaemons")); } catch (CDBFieldDoesNotExistEx e) { manager.setServiceDaemons(""); // Optional, but has no default! } manager.setTimeout((int)managerDAO.get_double("Timeout")); manager.setClientPingInterval((int)managerDAO.get_double("ClientPingInterval")); manager.setAdministratorPingInterval((int)managerDAO.get_double("AdministratorPingInterval")); manager.setContainerPingInterval((int)managerDAO.get_double("ContainerPingInterval")); manager.setServerThreads((byte)managerDAO.get_long("ServerThreads")); session.persist(manager); m_logger.info("Imported Manager from XML."); } catch (Throwable e) { m_logger.log(Level.WARNING,"MACI/Managers/Manager record does not exist or misconfigured, using defaults.",e); } /* String containers = xmlCDB.list_nodes("MACI/Containers"); StringTokenizer tokenizer = new StringTokenizer(containers); while (tokenizer.hasMoreTokens()) { String containerName = tokenizer.nextToken(); */ StringTokenizer tokenizer; String[] containerSubnodes = getSubNodes(xmlCDB_, "MACI/Containers"); for (String containerName : containerSubnodes) { //DAO containerDAO = xmlCDB.get_DAO_Servant("MACI/Containers/"+containerName); DAOProxy containerDAO = cdbAccess.createDAO("MACI/Containers/"+containerName); // check if real config, otherwice skip if (readLong(containerDAO, "LoggingConfig/minLogLevel", -1) < 0) continue; LoggingConfig loggingConfig = persistLoggingConfig(session, containerDAO, true); Computer hostComputer = null; String computerHostName = readString(containerDAO, "DeployInfo/Host", null); if (computerHostName != null) { hostComputer = (Computer)session.createCriteria(Computer.class). add(Restrictions.eq("networkName", computerHostName)).uniqueResult(); if (hostComputer == null) { // NOTE: we add some dummy data as computer name, realtime flag, CPU type here String computerName = computerHostName; int dotPos = computerName.indexOf('.'); if (dotPos > 0) computerName = computerName.substring(0, dotPos); hostComputer = new Computer(); hostComputer.setName(computerName); hostComputer.setConfiguration(config); hostComputer.setNetworkName(computerHostName); hostComputer.setRealTime(false); hostComputer.setDiskless(false); hostComputer.setProcessorType(ComputerProcessorType.UNI); hostComputer.setPhysicalLocation(null); session.persist(hostComputer); } } final String containerPath; int hierarchySeparatorPos = containerName.lastIndexOf('/'); if (hierarchySeparatorPos != -1) { containerPath = containerName.substring(0, hierarchySeparatorPos); containerName = containerName.substring(hierarchySeparatorPos + 1); } else containerPath = "/"; // for Oracle Container container = new Container(); container.setContainerName(containerName); container.setPath(containerPath); container.setConfiguration(config); container.setLoggingConfig(loggingConfig); container.setComputer(hostComputer); container.setImplLang(ImplLangEnum.valueOfForEnum(readString(containerDAO, "ImplLang", "cpp"))); // cpp is default, since field is required container.setTypeModifiers(readString(containerDAO, "DeployInfo/TypeModifiers", null)); container.setStartOnDemand(Boolean.valueOf(readString(containerDAO, "DeployInfo/StartOnDemand", "false"))); container.setRealTime(false); container.setRealTimeType(null); container.setKernelModuleLocation(null); container.setKernelModule(null); container.setKeepAliveTime(readLong(containerDAO, "DeployInfo/KeepAliveTime", -1)); container.setServerThreads(containerDAO.get_long("ServerThreads")); container.setManagerRetry(containerDAO.get_long("ManagerRetry")); container.setCallTimeout((int)containerDAO.get_double("Timeout")); container.setRecovery(Boolean.valueOf(containerDAO.get_string("Recovery"))); int pingInterval = readLong(containerDAO, "PingInterval", Integer.MIN_VALUE); if (pingInterval != Integer.MIN_VALUE) container.setPingInterval(pingInterval); container.setAutoloadSharedLibs(containerDAO.get_string("Autoload")); session.persist(container); // convert the "Flags" string of concatenated options to ContainerStartupOption String containerStartFlags = readString(containerDAO, "DeployInfo/Flags", null); ContainerStartupOptionHelper containerStartupOptionHelper = new ContainerStartupOptionHelper(m_logger); Collection<ContainerStartupOption> contOptions = containerStartupOptionHelper.convertFlagsString(container, containerStartFlags); for (ContainerStartupOption containerStartupOption : contOptions) { session.persist(containerStartupOption); } } if (containerSubnodes.length > 0) { m_logger.info("Imported Containers from XML."); } else { m_logger.info("No XML container data found."); } // set of all existing component names // used to generate *, *1, *2 names, as CDB does // NOTE: initial set is not filled with component names that are already in the DB Set<String> existingComponentNames = new HashSet<String>(); LinkedHashSet nodes = new LinkedHashSet(); //DAO componentDAO = xmlCDB.get_DAO_Servant("MACI/Components"); DAOProxy componentDAO = null; try { componentDAO = cdbAccess.createDAO("MACI/Components"); // current nodes.add("/"); String[] subnodes = getSubnodes(xmlCDB_, "MACI/Components"); if (subnodes != null) for (int i = 0; i < subnodes.length; i++) nodes.add(subnodes[i]); } catch (RuntimeException rte) { m_logger.warning("Failed to read MACI/Components DAO, skipping..."); } Iterator iter = nodes.iterator(); while (iter.hasNext()) { String path = iter.next().toString(); String prefix; if (path.length() == 0 || path.equals("/")) prefix = ""; else prefix = path + "/"; String components = (String) componentDAO.get_field_data(prefix + "_elements"); // store "original" path/prefix (it can be changed) final String originalPath = path; final String originalPrefix = prefix; tokenizer = new StringTokenizer(components, ","); while (tokenizer.hasMoreTokens()) { // set original values path = originalPath; prefix = originalPrefix; String componentName = prefix + tokenizer.nextToken(); String realComponentName = readString(componentDAO, componentName+"/Name", null); if (realComponentName == null) continue; // hierarchical name fix int hierarchySeparatorPos = realComponentName.lastIndexOf('/'); if (hierarchySeparatorPos != -1) realComponentName = realComponentName.substring(hierarchySeparatorPos + 1); // handle duplicate names, i.e. "*" // a "trick" of adding "/" to path is being used to achieve uniques // "/////" is the same as "/" for TMCDB, but not for DB while (existingComponentNames.contains(prefix + realComponentName)) { path = path + "/"; prefix = prefix + "/"; } existingComponentNames.add(prefix + realComponentName); int componentContainerId = -1; Container tmpComponentContainer = null; String containerName = readString(componentDAO, componentName+"/Container", null); if (containerName != null && !containerName.equals("*")) { String containerPath; hierarchySeparatorPos = containerName.lastIndexOf('/'); if (hierarchySeparatorPos != -1) { containerPath = containerName.substring(0, hierarchySeparatorPos); containerName = containerName.substring(hierarchySeparatorPos + 1); } else { containerPath = "/"; // for Oracle } Container container = (Container)session.createCriteria(Container.class) .add(Restrictions.eq("configuration", config)) .add(Restrictions.eq("containerName", containerName)) .add(Restrictions.eq("path", containerPath)).uniqueResult(); if (container != null) { componentContainerId = container.getContainerId(); tmpComponentContainer = container; } else { LoggingConfig loggingConfig = new LoggingConfig(); loggingConfig.setMinLogLevelDefault((byte)2); loggingConfig.setMinLogLevelLocalDefault((byte)2); loggingConfig.setCentralizedLogger("Log"); loggingConfig.setDispatchPacketSize((byte)10); loggingConfig.setImmediateDispatchLevel((byte)10); loggingConfig.setFlushPeriodSeconds((byte)10); loggingConfig.setMaxLogQueueSize(1000); loggingConfig.setMaxLogsPerSecond(-1); session.persist(loggingConfig); container = new Container(); container.setContainerName(containerName); container.setPath(containerPath); container.setConfiguration(config); container.setLoggingConfig(loggingConfig); container.setComputer(null); container.setImplLang(ImplLangEnum.valueOfForEnum(readString(componentDAO, "ImplLang", "cpp"))); // cpp is default, since field is required container.setTypeModifiers(DUMMY_CONTAINER_FLAG); container.setRealTime(false); container.setRealTimeType(null); container.setKernelModuleLocation(null); container.setKernelModule(null); container.setKeepAliveTime(-1); container.setServerThreads(5); container.setManagerRetry(10); container.setCallTimeout(2); container.setRecovery(false); container.setAutoloadSharedLibs(null); session.persist(container); componentContainerId = container.getContainerId(); tmpComponentContainer = container; } } String xml = null; boolean almaBranchDoesNotExist = componentName.startsWith("*"); boolean forceSubcomponentCheck = false; int typeId; String type = componentDAO.get_string(componentName+"/Type"); DAOProxy componentConfigurationDAO = null; // pulled out for performance optimization, to avoid reading it twice in many cases Schemas schema = null; { String schemaURN = null; // check if it is a non-control device, simply check for existence of "ControlDevice" element if (!almaBranchDoesNotExist) { try { // @TODO: Suppress the NOTICE log (or lower its level) which we get from the CDB code if there is no component configuration under the CDB/alma/ branch. // NOTICE [CDB-RDB] Curl 'alma/SCHEDULING_MASTERSCHEDULER' does not exist. componentConfigurationDAO = cdbAccess.createDAO(COMPONENT_TREE_NAME + "/" + componentName); schemaURN = componentConfigurationDAO.get_string("xmlns"); if (!processedComponentTypes.contains(type)) { boolean isControlDevice = !TMCDB_ACS_ONLY && xsdElementTypeResolver.doesExtend(schemaURN, "ControlDevice"); m_logger.fine(schemaURN + " does extend Control? " + isControlDevice); if (!isControlDevice) nonControlDeviceSet.add(type); boolean isCharateristicsComponent = xsdElementTypeResolver.doesExtend(schemaURN, "CharacteristicComponent") || (TMCDB_ACS_ONLY && xsdElementTypeResolver.doesExtend(schemaURN, "ControlDevice")); // sadly ControlDevice does not extend CharacteristicComponent XSD m_logger.fine(schemaURN + " does extend CharacteristicsComponent? " + isCharateristicsComponent); if (isCharateristicsComponent) characteristicsDeviceSet.add(type); processedComponentTypes.add(type); } } catch (Throwable th) { almaBranchDoesNotExist = true; // obviously not a control device (no component, i.e. alma, branch) // NOTE: if this device is missing alma branch data (and as control device it should have it), // this type will not be identified as control device at all, also for all devices of this type // (ComponentType is filled at first occurrence of the type) if (th.getCause() instanceof CDBRecordDoesNotExistEx) { // does not exists, this is OK... do not complain } else if (th instanceof CDBFieldDoesNotExistEx) { // field does not exist, but it might have sub-components forceSubcomponentCheck = true; } else { m_logger.log(AcsLogLevel.WARNING, "Failed to read component configuration: " + COMPONENT_TREE_NAME + "/" + componentName, th); } } } // get the Schema identifier for the schemaURN schema = (Schemas)session.createCriteria(Schemas.class) .add(Restrictions.eq("URN", schemaURN)) .add(Restrictions.eq("configuration", config)).uniqueResult(); if (schema == null && !almaBranchDoesNotExist) m_logger.severe("Component " + componentName + " of XSD type " + schemaURN + " has no XSD file."); ComponentType componentType = (ComponentType)session.createCriteria(ComponentType.class) .add(Restrictions.eq("IDL", type)).uniqueResult(); if (componentType == null) { componentType = new ComponentType(); componentType.setIDL(type); session.saveOrUpdate(componentType); } typeId = componentType.getComponentTypeId(); } boolean isControlDevice = !nonControlDeviceSet.contains(type) && !almaBranchDoesNotExist; boolean isCharateristicsDevice = characteristicsDeviceSet.contains(type); if (!isControlDevice && !isCharateristicsDevice && xml == null && !almaBranchDoesNotExist) { xml = getComponentXML(xmlCDB_, componentName, xml); } Component component = new Component(); // TODO this can be optimized!!! component.setComponentType((ComponentType)session.get(ComponentType.class, typeId)); component.setComponentName(realComponentName); component.setConfiguration(config); // component.setContainerId(componentContainerId); component.setContainer(tmpComponentContainer); // TODO verify this and clean up component.setImplLang(ImplLangEnum.valueOfForEnum(readString(componentDAO, componentName+"/ImplLang", "cpp"))); // cpp is default, since field is required component.setRealTime(false); component.setCode(componentDAO.get_string(componentName+"/Code")); component.setPath(path); component.setIsAutostart(Boolean.parseBoolean(componentDAO.get_string(componentName+"/Autostart"))); component.setIsDefault(Boolean.parseBoolean(componentDAO.get_string(componentName+"/Default"))); component.setIsStandaloneDefined(true); component.setIsControl(isControlDevice); component.setKeepAliveTime(componentDAO.get_long(componentName+"/KeepAliveTime")); component.setMinLogLevel((byte)readLong(componentDAO, componentName+"/ComponentLogger/minLogLevel", -1)); component.setMinLogLevelLocal((byte)readLong(componentDAO, componentName+"/ComponentLogger/minLogLevelLocal", -1)); component.setXMLDoc(xml); component.setURN(schema == null ? null : schema.getURN()); session.persist(component); session.flush(); // try to create alma branch (if available) if ((isControlDevice || isCharateristicsDevice) && !almaBranchDoesNotExist) { try { if (componentConfigurationDAO == null) { componentConfigurationDAO = cdbAccess.createDAO(COMPONENT_TREE_NAME + "/" + componentName); } if (plugin != null && isControlDevice) { plugin.controlDeviceImportEpilogue(session, config, cdbAccess, componentName, component); } Set<String> propertySet = new TreeSet<String>(); String[] propertyCandidates = componentConfigurationDAO.get_string_seq("_elements"); for (String propertyName : propertyCandidates) { // check if really property if (readString(componentConfigurationDAO, propertyName + "/format", null) != null) { m_logger.finer("Adding property " + propertyName); propertySet.add(propertyName); } } if (propertySet.size() > 0) { String[] properties = propertySet.toArray(new String[propertySet.size()]); String defaultPropertyNs = componentConfigurationDAO.get_string("xmlns"); String[] propertyNs = new String[properties.length]; for (int i = 0; i < properties.length; i++) propertyNs[i] = readString(componentConfigurationDAO, properties[i] + "/xmlns", defaultPropertyNs); ExtraDataFeatureUtil extraDataFeatureUtil = new ExtraDataFeatureUtil(m_logger); String[] propertyTypes = xsdElementTypeResolver.getElementTypes(componentConfigurationDAO.getElementName(), propertyNs, properties); for (int i = 0; i < properties.length; i++) { String propertyName = properties[i]; if (propertyTypes[i] != null && propertyTypes[i].endsWith("Seq")) { propertyTypes[i] = propertyTypes[i].substring(0, propertyTypes[i].length() - 3); } BACIProperty baciPropertyType = new BACIProperty(); baciPropertyType.setComponent(component); baciPropertyType.setPropertyName(propertyName); baciPropertyType.setDescription(nonEmptyString(componentConfigurationDAO.get_string(propertyName + "/description"), "-")); baciPropertyType.setFormat(nonEmptyString(componentConfigurationDAO.get_string(propertyName + "/format"), "%s")); baciPropertyType.setUnits(nonEmptyString(componentConfigurationDAO.get_string(propertyName + "/units"), "-")); baciPropertyType.setResolution(nonEmptyString(componentConfigurationDAO.get_string(propertyName + "/resolution"), EmptyStringHandlerBACIPropertyType.EMPTY_STRING_SUBSTITUTE)); baciPropertyType.setArchive_priority(componentConfigurationDAO.get_long(propertyName + "/archive_priority")); baciPropertyType.setArchive_min_int(componentConfigurationDAO.get_double(propertyName + "/archive_min_int")); baciPropertyType.setArchive_max_int(componentConfigurationDAO.get_double(propertyName + "/archive_max_int")); baciPropertyType.setArchive_suppress(Boolean.parseBoolean(componentConfigurationDAO.get_string(propertyName + "/archive_suppress"))); baciPropertyType.setArchive_mechanism(BACIPropArchMech.valueOfForEnum(nonEmptyString(componentConfigurationDAO.get_string(propertyName + "/archive_mechanism"), "monitor_collector"))); baciPropertyType.setDefault_timer_trig(componentConfigurationDAO.get_double(propertyName + "/default_timer_trig")); baciPropertyType.setMin_timer_trig(componentConfigurationDAO.get_double(propertyName + "/min_timer_trig")); baciPropertyType.setInitialize_devio(Boolean.parseBoolean(componentConfigurationDAO.get_string(propertyName + "/initialize_devio"))); /* P<type> */ baciPropertyType.setMin_delta_trig(readDouble(componentConfigurationDAO, propertyName + "/min_delta_trig", 0.0)); baciPropertyType.setDefault_value(nonEmptyString(componentConfigurationDAO.get_string(propertyName + "/default_value"), "-")); baciPropertyType.setGraph_min(limitDouble(readDouble(componentConfigurationDAO, propertyName + "/graph_min", null))); baciPropertyType.setGraph_max(limitDouble(readDouble(componentConfigurationDAO, propertyName + "/graph_max", null))); baciPropertyType.setMin_step(readDouble(componentConfigurationDAO, propertyName + "/min_step", null)); baciPropertyType.setArchive_delta(readDouble(componentConfigurationDAO, propertyName + "/archive_delta", 0.0)); baciPropertyType.setArchive_delta_percent(readDouble(componentConfigurationDAO, propertyName + "/archive_delta_percent", null)); /* RO<type> */ baciPropertyType.setAlarm_high_on(readDouble(componentConfigurationDAO, propertyName + "/alarm_high_on", null)); baciPropertyType.setAlarm_low_on(readDouble(componentConfigurationDAO, propertyName + "/alarm_low_on", null)); baciPropertyType.setAlarm_high_off(readDouble(componentConfigurationDAO, propertyName + "/alarm_high_off", null)); baciPropertyType.setAlarm_low_off(readDouble(componentConfigurationDAO, propertyName + "/alarm_low_off", null)); baciPropertyType.setAlarm_timer_trig(readDouble(componentConfigurationDAO, propertyName + "/alarm_timer_trig", null)); /* RW<type> */ baciPropertyType.setMin_value(limitDouble(readDouble(componentConfigurationDAO, propertyName + "/min_value", null))); baciPropertyType.setMax_value(limitDouble(readDouble(componentConfigurationDAO, propertyName + "/max_value", null))); /* ROpattern */ baciPropertyType.setBitDescription(nonEmptyString(readString(componentConfigurationDAO, propertyName + "/bitDescription", null), EmptyStringHandlerBACIPropertyType.EMPTY_STRING_SUBSTITUTE)); baciPropertyType.setWhenSet(nonEmptyString(readString(componentConfigurationDAO, propertyName + "/whenSet", null), EmptyStringHandlerBACIPropertyType.EMPTY_STRING_SUBSTITUTE)); baciPropertyType.setWhenCleared(nonEmptyString(readString(componentConfigurationDAO, propertyName + "/whenCleared", null), EmptyStringHandlerBACIPropertyType.EMPTY_STRING_SUBSTITUTE)); /* PEnum */ baciPropertyType.setStatesDescription(nonEmptyString(readString(componentConfigurationDAO, propertyName + "/statesDescription", null), EmptyStringHandlerBACIPropertyType.EMPTY_STRING_SUBSTITUTE)); baciPropertyType.setCondition(nonEmptyString(readString(componentConfigurationDAO, propertyName + "/condition", null), EmptyStringHandlerBACIPropertyType.EMPTY_STRING_SUBSTITUTE)); baciPropertyType.setAlarm_on(nonEmptyString(readString(componentConfigurationDAO, propertyName + "/alarm_on", null), EmptyStringHandlerBACIPropertyType.EMPTY_STRING_SUBSTITUTE)); baciPropertyType.setAlarm_off(nonEmptyString(readString(componentConfigurationDAO, propertyName + "/alarm_off", null), EmptyStringHandlerBACIPropertyType.EMPTY_STRING_SUBSTITUTE)); /* alarms */ baciPropertyType.setAlarm_fault_family(nonEmptyString(readString(componentConfigurationDAO, propertyName + "/alarm_fault_family", null), EmptyStringHandlerBACIPropertyType.EMPTY_STRING_SUBSTITUTE)); baciPropertyType.setAlarm_fault_member(nonEmptyString(readString(componentConfigurationDAO, propertyName + "/alarm_fault_member", null), EmptyStringHandlerBACIPropertyType.EMPTY_STRING_SUBSTITUTE)); int level = readLong(componentConfigurationDAO, propertyName + "/alarm_level", Integer.MIN_VALUE); if (level != Integer.MIN_VALUE) baciPropertyType.setAlarm_level(level); baciPropertyType.setData(extraDataFeatureUtil.getExtraDataMap(componentConfigurationDAO, propertyName, baciPropertyAttributesSet, ExtraDataFeatureUtil.EMPTY_SET)); session.persist(baciPropertyType); } // add non-property elements propertySet.add("Address"); // this is handled by HW plugin component.setXMLDoc(extraDataFeatureUtil.getExtraDataMap(componentConfigurationDAO, null, ExtraDataFeatureUtil.EMPTY_SET, propertySet)); session.update(component); } else { // no properties, add entire XML although it is a control device component.setXMLDoc(xml == null ? getComponentXML(xmlCDB_, componentName, xml) : xml); session.update(component); } // from remote, since DAO will compact it if (!almaBranchDoesNotExist || forceSubcomponentCheck) { String componentNodes = xmlCDB_.list_nodes(COMPONENT_TREE_NAME + "/" + componentName); if (componentNodes != null) { StringTokenizer tokenizer2 = new StringTokenizer(componentNodes); while (tokenizer2.hasMoreTokens()) propertySet.add(tokenizer2.nextToken()); } } } catch (RuntimeException rte) { // ignore components with no configuration; this is very ugly wat of doing it... if (rte.getMessage() != null && rte.getMessage().startsWith("Failed to obtain")) { // noop (there is no configuration for component) } else rte.printStackTrace(); } } } } if (nodes.size() > 0) { // if the preceding while loop actually did something... m_logger.info("Imported Components from XML."); } // // Channels configurations // String[] channelSubnodes = getSubNodes(xmlCDB_, "MACI/Channels"); for (String channelName : channelSubnodes) { //DAO channelDAO = xmlCDB.get_DAO_Servant("MACI/Channels/"+channelName); DAOProxy channelDAO = cdbAccess.createDAO("MACI/Channels/"+channelName); final String channelPath; final String channelShortName; int hierarchySeparatorPos = channelName.lastIndexOf('/'); if (hierarchySeparatorPos != -1) { channelPath = channelName.substring(0, hierarchySeparatorPos); channelShortName = channelName.substring(hierarchySeparatorPos + 1); } else { channelPath = "/"; // for Oracle channelShortName = channelName; } EventChannel eventChannel = new EventChannel(); eventChannel.setConfiguration(config); eventChannel.setName(channelShortName); eventChannel.setPath(channelPath); eventChannel.setIntegrationLogs(Boolean.valueOf(readString(channelDAO, "IntegrationLogs", "false"))); eventChannel.setMaxQueueLength(readLong(channelDAO, "MaxQueueLength", 0)); eventChannel.setMaxConsumers(readLong(channelDAO, "MaxConsumers", 0)); eventChannel.setMaxSuppliers(readLong(channelDAO, "MaxSuppliers", 0)); eventChannel.setRejectNewEvents(Boolean.valueOf(readString(channelDAO, "RejectNewEvents", "false"))); eventChannel.setDiscardPolicy(EventChannelDiscardPolicy.valueOfForEnum(readString(channelDAO, "DiscardPolicy", "AnyOrder"))); eventChannel.setEventReliability(EventChannelEventReliability.valueOfForEnum(readString(channelDAO, "EventReliability", "BestEffort"))); eventChannel.setConnectionReliability(EventChannelConReliability.valueOfForEnum(readString(channelDAO, "ConnectionReliability", "BestEffort"))); eventChannel.setPriority((short)readLong(channelDAO, "Priority", 0)); eventChannel.setTimeout(readLong(channelDAO, "Timeout", 0)); eventChannel.setOrderPolicy(EventChannelOrderPolicy.valueOfForEnum(readString(channelDAO, "OrderPolicy", "AnyOrder"))); eventChannel.setStartTimeSupported(Boolean.valueOf(readString(channelDAO, "StartTimeSupported", "false"))); eventChannel.setStopTimeSupported(Boolean.valueOf(readString(channelDAO, "StopTimeSupported", "false"))); eventChannel.setMaxEventsPerConsumer(readLong(channelDAO, "MaxEventsPerConsumer", 0)); session.persist(eventChannel); Set<Event> eventSet = eventChannel.getEvents(); String[] events = readStringSeq(channelDAO, "Events", null); if (events != null) { for (String eventName : events) { Event event = new Event(); event.setName(eventName); event.setEventChannel(eventChannel); event.setMaxProcessTime(readDouble(channelDAO, eventName+"/MaxProcessTime", 2.0)); eventSet.add(event); session.persist(event); } } } try { DAOProxy notificationServiceMappingDAO = cdbAccess.createDAO("MACI/Channels/NotificationServiceMapping"); String defaultNotSrv = notificationServiceMappingDAO.get_string("DefaultNotificationService"); NotificationServiceMapping mappings = new NotificationServiceMapping(); mappings.setConfiguration(config); mappings.setDefaultNotificationService(defaultNotSrv); session.persist(mappings); String[] domains = readStringSeq(notificationServiceMappingDAO, "Domains", null); if (domains != null) { for (String domain : domains) { String name = notificationServiceMappingDAO.get_string("Domains/" + domain + "/Name"); String notSrv = notificationServiceMappingDAO.get_string("Domains/" + domain + "/NotificationService"); DomainsMapping domainsMapping = new DomainsMapping(); domainsMapping.setNotificationServiceMapping(mappings); domainsMapping.setName(name); domainsMapping.setNotificationService(notSrv); mappings.getDomainsMappings().add(domainsMapping); session.persist(domainsMapping); } } String[] channels = readStringSeq(notificationServiceMappingDAO, "Channels_", null); if (channels != null) { for (String channel : channels) { String name = notificationServiceMappingDAO.get_string("Channels_/" + channel + "/Name"); String notSrv = notificationServiceMappingDAO.get_string("Channels_/" + channel + "/NotificationService"); ChannelMapping channelsMapping = new ChannelMapping(); channelsMapping.setNotificationServiceMapping(mappings); channelsMapping.setName(name); channelsMapping.setNotificationService(notSrv); mappings.getChannelMappings().add(channelsMapping); session.persist(channelsMapping); } } } catch (RuntimeException re) { // no mappings } m_logger.info("Imported Notification Channels from XML."); // plugin importEpilogue() if (plugin != null) { try { plugin.importEpilogue(session, config, cdbAccess); } catch (Throwable th) { // @TODO: Decent exception log. th.printStackTrace(); } } hibernateUtil.commitTransaction(); m_logger.info("Configuration from XML CDB loaded."); } catch (CDBFieldDoesNotExistEx ex) { throw AcsJCDBFieldDoesNotExistEx.fromCDBFieldDoesNotExistEx(ex); } catch (WrongCDBDataTypeEx ex) { throw AcsJWrongCDBDataTypeEx.fromWrongCDBDataTypeEx(ex); } catch (Throwable th) { throw new RuntimeException("Failed to fill-in the DB from CDB.", th); } finally { hibernateUtil.closeSession(); cdbAccess.destroy(); xmlCDB_._release(); servantDelegate.shutdownEmbeddedWDALImpl(); // destroy POA xmlCDBPOA.destroy(true, false); } return true; } catch (Throwable th) { m_logger.log(Level.SEVERE, "Failed to load XML CDB, exiting...", th); return false; } finally { loadInProgress.set(false); } } /** * @param xmlCDB * @param componentName * @param xml * @return XML string, or null, but not an empty string. * @throws CDBXMLErrorEx * @throws DOMException * @throws RuntimeException */ private String getComponentXML(final JDAL xmlCDB, String componentName, String xml) throws CDBXMLErrorEx, DOMException, RuntimeException { // try to create component, i.e. alma, branch (if available) try { // hierarchical check.. String nodes = xmlCDB.list_nodes(COMPONENT_TREE_NAME + "/" + componentName); boolean isHierarhicalWithXML = (nodes != null) && (nodes.trim().length() > 0); if (isHierarhicalWithXML) { try { String nameOnly = componentName; int pos = nameOnly.lastIndexOf('/'); if (pos > 0) nameOnly = nameOnly.substring(pos + 1); // reach for file File xmlFile = new File(m_root + File.separatorChar + COMPONENT_TREE_NAME + File.separatorChar + componentName + File.separatorChar + nameOnly + ".xml"); //System.out.println(xmlFile.getAbsolutePath() + ", " + xmlFile.exists()); final BufferedReader reader = new BufferedReader(new FileReader(xmlFile)); final StringBuffer file = new StringBuffer(); String line; while ((line = reader.readLine()) != null) file.append(line).append('\n'); xml = file.toString(); } catch (Throwable th) { throw new RuntimeException("Failed to read XML for component " + componentName); } } else { xml = xmlCDB.get_DAO(COMPONENT_TREE_NAME + "/" + componentName); } } catch (CDBRecordDoesNotExistEx rdne) { // noop, no data } // Oracle XMLTYPE attributes don't like empty XML, thus we convert it to null if (xml != null && xml.trim().isEmpty()) { xml = null; } return xml; } /** * TODO: Double are limited to Float. This should be fixed! * Note that storing The highest (lowest) possible value (@BINARY_DOUBLE oracle datatype) * in oracle returns an error (even if oracle accepts these values if set with SQL update) */ private final static Double limitDouble(final Double value) { if (value == null) return null; //To handle the case for Round to the nearest rule that make double to go overflow/+infinity and //underflow/-infinity which in turn cause MySQL exception if (value.doubleValue() >= Float.MAX_VALUE) return new Double(Float.MAX_VALUE); else if (value.doubleValue() <= -Float.MAX_VALUE) return new Double(-Float.MAX_VALUE); return new Double(value.floatValue()); } private final static String nonEmptyString(final String value, final String defaultValue) { if (value == null) return null; if (value.length() == 0) return defaultValue; else return value; } private LoggingConfig persistLoggingConfig(Session session, DAOOperations dao, boolean required) throws CDBFieldDoesNotExistEx, WrongCDBDataTypeEx { LoggingConfig loggingConfig = new LoggingConfig(); if (required) { // TODO can be optimized loggingConfig.setMinLogLevelDefault((byte)dao.get_long("LoggingConfig/minLogLevel")); loggingConfig.setMinLogLevelLocalDefault((byte)dao.get_long("LoggingConfig/minLogLevelLocal")); loggingConfig.setCentralizedLogger(dao.get_string("LoggingConfig/centralizedLogger")); loggingConfig.setDispatchPacketSize((byte)dao.get_long("LoggingConfig/dispatchPacketSize")); loggingConfig.setImmediateDispatchLevel((byte)dao.get_long("LoggingConfig/immediateDispatchLevel")); loggingConfig.setFlushPeriodSeconds((byte)dao.get_long("LoggingConfig/flushPeriodSeconds")); loggingConfig.setMaxLogQueueSize(dao.get_long("LoggingConfig/maxLogQueueSize")); loggingConfig.setMaxLogsPerSecond(dao.get_long("LoggingConfig/maxLogsPerSecond")); } else { // TODO can be optimized loggingConfig.setMinLogLevelDefault((byte)readLong(dao, "LoggingConfig/minLogLevel", 2)); loggingConfig.setMinLogLevelLocalDefault((byte)readLong(dao, "LoggingConfig/minLogLevelLocal", 2)); loggingConfig.setCentralizedLogger(readString(dao, "LoggingConfig/centralizedLogger", "Log")); loggingConfig.setDispatchPacketSize((byte)readLong(dao, "LoggingConfig/dispatchPacketSize", 10)); loggingConfig.setImmediateDispatchLevel((byte)readLong(dao, "LoggingConfig/immediateDispatchLevel", 10)); loggingConfig.setFlushPeriodSeconds((byte)readLong(dao, "LoggingConfig/flushPeriodSeconds", 10)); loggingConfig.setMaxLogQueueSize(readLong(dao, "LoggingConfig/maxLogQueueSize", 1000)); loggingConfig.setMaxLogsPerSecond(readLong(dao, "LoggingConfig/maxLogsPerSecond", -1)); } session.persist(loggingConfig); final String[] LC_ATTRIBUTES = { "minLogLevel", "minLogLevelLocal", "centralizedLogger", "dispatchPacketSize", "immediateDispatchLevel", "flushPeriodSeconds", "maxLogQueueSize", "maxLogsPerSecond" }; String[] children; if (required) children = dao.get_string_seq("LoggingConfig/"); else children = readStringSeq(dao, "LoggingConfig/", new String[0]); for (String childName : children) { boolean attribute = false; for (int i = 0; i < LC_ATTRIBUTES.length; i++) if (childName.equals(LC_ATTRIBUTES[i])) { attribute = true; break; } if (!attribute) { NamedLoggerConfig namedLoggerConfig = new NamedLoggerConfig(); namedLoggerConfig.setLoggingConfig(loggingConfig); namedLoggerConfig.setName(dao.get_string("LoggingConfig/"+childName+"/Name")); namedLoggerConfig.setMinLogLevel((byte)dao.get_long("LoggingConfig/"+childName+"/minLogLevel")); namedLoggerConfig.setMinLogLevelLocal((byte)dao.get_long("LoggingConfig/"+childName+"/minLogLevelLocal")); session.persist(namedLoggerConfig); } } return loggingConfig; } /** * Helper method to get all subnodes of the current proxy, removes ".xml" element from the list. */ private String[] getSubnodes(JDAL dal, String node) throws Throwable { ArrayList subnodes = new ArrayList(); LinkedList stack = new LinkedList(); stack.addLast(node); while (!stack.isEmpty()) { String parentNode = stack.removeLast().toString(); String nodes = dal.list_nodes(parentNode); if (nodes.length() > 0) { StringTokenizer tokenizer = new StringTokenizer(nodes); while (tokenizer.hasMoreTokens()) { String nodeName = tokenizer.nextToken(); if (nodeName.endsWith(".xml")) continue; String fullName = parentNode + "/" + nodeName; stack.addLast(fullName); // strip off relative path subnodes.add(fullName.substring(node.length()+1)); } } } String[] retVal = new String[subnodes.size()]; subnodes.toArray(retVal); return retVal; } protected Map<String, Object> getAlmaBranch() { final Map<String, Object> almaRoot = new RootMap<String, Object>(); try { Session session = hibernateUtil.getSession(); schemaResourceResolverLoader.setSession(session); final Set<String> loadedComponents = new HashSet<String>(); // // add control devices // if (plugin != null) { final HibernateWDALPlugin.ControlDeviceBindCallback bindCallback = new HibernateWDALPlugin.ControlDeviceBindCallback() { public void bindToComponentBranch(String name, String path, Object objectToBind) { bindToAlmaBranch(almaRoot, name, path, objectToBind); if (!loadedComponents.contains(path + "/" + name)) loadedComponents.add(path + "/" + name); } public void bindNonExpandedXMLToComponentBranch(Session session, Component component) { alma.TMCDB.maci.Component comp = (alma.TMCDB.maci.Component)session.createCriteria(alma.TMCDB.maci.Component.class). add(Restrictions.eq("ComponentId", component.getComponentId())).uniqueResult(); if (comp == null) throw new RuntimeException("Component with ID " + component.getComponentId() + " does not exist."); bindNonExpandedComponentXMLToAlmaBranch(session, almaRoot, comp); // TODO why do not add to already loaded components list??!!! } }; plugin.loadControlDevices(session, config, bindCallback); } // // add devices // Iterator componentList = session.createCriteria(alma.TMCDB.maci.Component.class). add(Restrictions.eq("Control", false)). add(Restrictions.eq("ConfigurationId", configId)).list().iterator(); while (componentList.hasNext()) { alma.TMCDB.maci.Component component = (alma.TMCDB.maci.Component)componentList.next(); // already loaded by plugins, skip if (loadedComponents.contains(component.Path + "/" + component.getName())) continue; String query = "FROM alma.TMCDB.baci.BACIPropertyType WHERE ComponentId = " + component.ComponentId; List propertyList = session.createQuery(query).list(); if (propertyList.size() > 0) { ComponentData componentData = new ComponentData(); try { componentData.setData(component.XMLDoc); } catch (Throwable e) { // TODO Auto-generated catch block e.printStackTrace(); } // add properties for (Iterator iter = propertyList.iterator(); iter.hasNext(); ) { BACIPropertyType baciProperty = (BACIPropertyType) iter.next(); //componentData._.put(baciProperty.PropertyName, baciProperty); componentData._.put(baciProperty.PropertyName, new EmptyStringHandlerBACIPropertyType(baciProperty)); } // bind object to map tree bindToAlmaBranch(almaRoot, component.getName(), component.Path, componentData); } else if (component.XMLDoc != null) { bindNonExpandedComponentXMLToAlmaBranch(session, almaRoot, component); } } } catch (Throwable th) { th.printStackTrace(); } return almaRoot; } private static class ComponentDAOImplSaver extends DAOImpl implements XMLSaver { private alma.TMCDB.maci.Component component; public ComponentDAOImplSaver(alma.TMCDB.maci.Component component, XMLTreeNode rootNode, POA poa, Logger logger, boolean silent) { super(component.getName(), rootNode, poa, logger, silent); this.component = component; rootNode.m_name = component.getName(); // TODO should be dynamically temp. set on toXML only } public void save() { component.XMLDoc = getRootNode().toString(false); } public void save(String xml) { component.XMLDoc = xml; } } public void bindNonExpandedComponentXMLToAlmaBranch(Session session, Map<String, Object> parentMap, alma.TMCDB.maci.Component component) { // from XMLDOC if (component.URN != null) { // now with XML create DAO object // use CDB XML handler which does not creates strings... XMLHandler xmlSolver = new XMLHandler(false, m_logger); try { synchronized (xmlNodeMonitor) { saxParser.parse(new InputSource(new StringReader(component.XMLDoc)), xmlSolver); } } catch (Exception e) { m_logger.log(AcsLogLevel.ERROR, "Failed to add component '" + component.Path + "/" + component.getName(), e); return; } if (xmlSolver.m_errorString != null){ m_logger.log(AcsLogLevel.ERROR, "Failed to add component '" + component.Path + "/" + component.getName() + "': XML parser error: " + xmlSolver.m_errorString); return; } // create non-CORBA related, silent DAO DAOImpl dao = new ComponentDAOImplSaver(component, xmlSolver.m_rootNode, null, m_logger, true); // bind object to map tree bindToAlmaBranch(parentMap, component.getName(), component.Path, dao); } else { m_logger.finer("No schema found for component " + component.Path + "/" + component.getName()); ComponentData componentData = new ComponentData(); try { componentData.setData(component.XMLDoc); } catch (Throwable e) { // TODO Auto-generated catch block e.printStackTrace(); } // bind object to map tree bindToAlmaBranch(parentMap, component.getName(), component.Path, componentData); } } protected void bindToAlmaBranch(Map<String, Object> parentMap, String name, String path, Object objectToBind) { // now find its submap path = getNormalizedPath(path); final String fullName = path + "/" + name; while (path != null && path.length() > 0) { // remove trailing slashes, to have unique curl (used for key) if (path.charAt(0) == '/') { path = path.substring(1); continue; } int pos = path.indexOf('/'); String parentPath = (pos > 0) ? path.substring(0, pos) : path; String subpath = (pos > 0) ? path.substring(pos+1, path.length()) : null; // hierarchical component (has it own XML) with children components Object parentObj = parentMap.get(parentPath); if (parentObj instanceof ComponentDAOImplSaver) { m_logger.fine("Transforming non-hierachical to hierachical node for " + parentPath + " (of " + fullName + ")"); ComponentData cd = new ComponentData(); try { cd.setData(((ComponentDAOImplSaver)parentObj).component.XMLDoc); } catch (Throwable th) { // should never happen, but still print it out th.printStackTrace(); } parentObj = cd; parentMap.put(parentPath, parentObj); } ComponentData parentComponent = (ComponentData)parentObj; if (parentComponent == null) { parentComponent = new ComponentData(); parentMap.put(parentPath, parentComponent); } parentMap = parentComponent._; path = subpath; } Object current = parentMap.get(name); if (current != null) { if (current instanceof ComponentData && objectToBind instanceof ComponentDAOImplSaver) { m_logger.fine("Overriding XMLDoc of already bound node of " + fullName); try { ((ComponentData)current).setData(((ComponentDAOImplSaver)objectToBind).component.XMLDoc); } catch (Throwable th) { // should never happen, but still print it out th.printStackTrace(); } } else if (current instanceof ComponentData && objectToBind instanceof ComponentData) { m_logger.fine("Overriding XMLDoc of already bound node of " + fullName + ", but keeping its subnodes."); ((ComponentData)current).setData(((ComponentData)objectToBind).getExtraData()); } else { // still override, but with warning m_logger.warning("Overriding component node: " + fullName); parentMap.put(name, objectToBind); } } else { parentMap.put(name, objectToBind); } } public List getListForConfiguration(Session session, Class type) throws Throwable { List<Computer> result = null; try { type.getMethod("getConfiguration", (Class[])null); result = session.createCriteria(type).add(Restrictions.eq("configuration", config)).list(); } catch (NoSuchMethodException nsme) { result = session.createCriteria(type).add(Restrictions.eq("ConfigurationId", configId)).list(); } return result; } public List getListForConfiguration(Session session, Class type, Criterion cr) throws Throwable { List<Computer> result = null; try { type.getMethod("getConfiguration", (Class[])null); result = session.createCriteria(type).add(Restrictions.eq("configuration", config)).add(cr).list(); } catch (NoSuchMethodException nsme) { result = session.createCriteria(type).add(Restrictions.eq("ConfigurationId", configId)).add(cr).list(); } return result; } private String getAcsServices(Session session, Configuration config) throws Throwable { List serviceList = getListForConfiguration(session, AcsService.class); if (serviceList == null || serviceList.size() == 0) return null; StringBuilder sb = new StringBuilder(); for (Object obj : serviceList) { AcsService acsService = (AcsService)obj; String toAdd = acsService.getServiceInstanceName(); if (toAdd == null) { AcsServiceServiceType type = acsService.getServiceType(); switch(type) { case NAMING: case MANAGER: toAdd = null; // noop since it is supported by manager by default break; case IFR: toAdd = "InterfaceRepository"; break; case CDB: toAdd = "CDB"; break; case NOTIFICATION: toAdd = "NotifyEventChannelFactory"; break; case LOGGING: toAdd = "Log"; break; case ALARM: toAdd = "AcsAlarmService"; break; case LOGPROXY: toAdd = "ACSLogSvc"; break; default: m_logger.warning("Unknown AcsService type '" + type + "'"); } } if (toAdd != null) { if (sb.length() > 0) sb.append(','); sb.append(toAdd); } } if (sb.length() > 0) return sb.toString(); else return null; } protected synchronized void initializeRootNode() { m_logger.info("Loading configuration from the database..."); Map<String, Object> rootMap = new RootMap<String, Object>(); rootNode = rootMap; // useful in case of reload (when rootNode was not null) System.gc(); try { Session session = hibernateUtil.getSession(); // plugin loadPrologue() if (plugin != null) { try { plugin.loadPrologue(session, config, rootMap); } catch (Throwable th) { this.m_logger.log(Level.SEVERE, "Failure in plugin " + plugin.getClass().getName(), th); // TODO: or should we let HD fail completely? } } // maci branch Map<String, Object> maciMap = new RootMap<String, Object>(); maciMap.put("Components", getComponentsTableMap()); maciMap.put("Containers", getContainersTableMap()); Object channelsMap = getChannelsTableMap(); if (channelsMap != null) maciMap.put("Channels", channelsMap); Map<String, Object> managersMap = new RootMap<String, Object>(); List managerList = getListForConfiguration(session, alma.TMCDB.maci.Manager.class); if (!managerList.isEmpty()) managersMap.put("Manager", managerList.get(0)); else managersMap.put("Manager", getDefaultMangerConfig()); String additionalServices = getAcsServices(session, config); if (additionalServices != null) { alma.TMCDB.maci.Manager manager = (alma.TMCDB.maci.Manager)managersMap.get("Manager"); String currentServices = manager.getServiceComponents(); if (currentServices == null || currentServices.length() == 0) manager.setServiceComponents(additionalServices); else // there might be duplicates, but they do not harm manager.setServiceComponents(currentServices + "," + additionalServices); } maciMap.put("Managers", managersMap); rootMap.put("MACI", maciMap); // component, i.e. alma, branch rootMap.put(COMPONENT_TREE_NAME, getAlmaBranch()); // plugin loadEpilogue() if (plugin != null) { try { plugin.loadEpilogue(session, config, rootMap); } catch (Throwable th) { this.m_logger.log(Level.SEVERE, "Failure in plugin " + plugin.getClass().getName(), th); // TODO: or should we let HD fail completely? } } //org.hsqldb.util.DatabaseManager.main(new String[0]); // session check if (hibernateUtil.getSession() != mainSession) { throw new RuntimeException("Unexpected change of session..."); } m_logger.info("Configuration loaded."); } catch (Throwable th) { th.printStackTrace(); } } private static final alma.TMCDB.maci.Manager getDefaultMangerConfig() { return new alma.TMCDB.maci.Manager(); } public Map<String, Object> getTableMap(Session session, String keyField, Class type) { Map<String, Object> map = new RootMap<String, Object>(); try { Method accessor = DOMJavaClassIntrospector.getAccessorMethod(type, keyField); Field field = null; if (accessor == null) { try { field = type.getField(keyField); } catch (Throwable th) { throw new IllegalStateException("failed to obtain key "); } } List list = getListForConfiguration(session, type); for (Object data : list) { String baseKey; if (accessor != null) baseKey = accessor.invoke(data, (Object[])null).toString(); else //if (field != null) baseKey = field.get(data).toString(); // should not be null // unique key generation int count = 0; String key = baseKey; while (map.containsKey(key)) key = baseKey + String.valueOf(++count); map.put(key, data); } } catch (Throwable th) { th.printStackTrace(); } return map; } public Map<String, Object> getComponentsTableMap() { final String keyField = "Name"; final Class type = alma.TMCDB.maci.Component.class; Map<String, Object> map = new LinkedHashMap<String, Object>(); try { Session session = hibernateUtil.getSession(); Method accessor = DOMJavaClassIntrospector.getAccessorMethod(type, keyField); Field field = null; if (accessor == null) { try { field = type.getField(keyField); } catch (Throwable th) { throw new IllegalStateException("failed to obtain key "); } } List list = getListForConfiguration(session, type); // Sort the list by path + component to ensure that parent components are added before their children Comparator<alma.TMCDB.maci.Component> comparator = new Comparator<alma.TMCDB.maci.Component>() { public int compare(alma.TMCDB.maci.Component o1, alma.TMCDB.maci.Component o2) { String fullName1 = ((o1.Path == null ? "" : o1.Path) + "/") + o1.getName(); String fullName2 = ((o2.Path == null ? "" : o2.Path) + "/") + o2.getName(); return fullName1.compareTo(fullName2); } }; Collections.sort(list, comparator); for (Object data : list) { String baseKey; if (accessor != null) baseKey = accessor.invoke(data, (Object[])null).toString(); else //if (field != null) baseKey = field.get(data).toString(); // baseKey should not be null Map parentMap = map; alma.TMCDB.maci.Component component = (alma.TMCDB.maci.Component)data; // some cleaning if (component.getComponentLogger().getMinLogLevel() == -1 && component.getComponentLogger().getMinLogLevelLocal() == -1) component.setComponentLogger(null); // now find its map String path = getNormalizedPath(component.Path); while (path != null && path.length() > 0) { // remove trailing slashes, to have unique curl (used for key) if (path.charAt(0) == '/') { path = path.substring(1); continue; } int pos = path.indexOf('/'); String parentPath = (pos > 0) ? path.substring(0, pos) : path; String subpath = (pos > 0) ? path.substring(pos+1, path.length()) : null; alma.TMCDB.maci.ComponentNode parentComponent = (alma.TMCDB.maci.ComponentNode)parentMap.get(parentPath); if (parentComponent == null) { parentComponent = new alma.TMCDB.maci.ComponentNode(); parentMap.put(parentPath, parentComponent); } parentMap = parentComponent._; path = subpath; } // unique key generation int count = 0; String key = baseKey; while (parentMap.containsKey(key)) key = baseKey + String.valueOf(++count); parentMap.put(key, data); if (data instanceof alma.TMCDB.maci.Component) { alma.TMCDB.maci.Component comp = (alma.TMCDB.maci.Component) data; m_logger.finer("Loaded component name=" + comp.Path + comp.getName() + ", type=" + comp.getType() + ", container=" + comp.getContainer() + ", implLang=" + comp.getImplLang()); } else { m_logger.warning("Bad component class '" + data.getClass().getName() + "' read from TMCDB."); } } } catch (Throwable th) { th.printStackTrace(); } return map; } public Map<String, Object> getContainersTableMap() { final String keyField = "Name"; final Class type = alma.TMCDB.maci.Container.class; Map<String, Object> map = new RootMap<String, Object>(); try { Session session = hibernateUtil.getSession(); Method accessor = DOMJavaClassIntrospector.getAccessorMethod(type, keyField); Field field = null; if (accessor == null) { try { field = type.getField(keyField); } catch (Throwable th) { throw new IllegalStateException("failed to obtain key "); } } List list = getListForConfiguration(session, type); // Sort the list by path + component to ensure that parent containers are added before their children Comparator<alma.TMCDB.maci.Container> comparator = new Comparator<alma.TMCDB.maci.Container>() { public int compare(alma.TMCDB.maci.Container o1, alma.TMCDB.maci.Container o2) { String fullName1 = ((o1.Path == null ? "" : o1.Path) + "/") + o1.getName(); String fullName2 = ((o2.Path == null ? "" : o2.Path) + "/") + o2.getName(); return fullName1.compareTo(fullName2); } }; Collections.sort(list, comparator); for (Object data : list) { String baseKey; if (accessor != null) baseKey = accessor.invoke(data, (Object[])null).toString(); else //if (field != null) baseKey = field.get(data).toString(); // baseKey should not be null Map parentMap = map; alma.TMCDB.maci.Container container = (alma.TMCDB.maci.Container)data; // do not include this if (DUMMY_CONTAINER_FLAG.equals(container.getDeployInfo().getTypeModifiers())) continue; // some cleaning if (container.getDeployInfo() != null && container.getDeployInfo().getHost() == null) container.setDeployInfo(null); // now find its map String path = getNormalizedPath(container.Path); while (path != null && path.length() > 0) { // remove trailing slashes, to have unique curl (used for key) if (path.charAt(0) == '/') { path = path.substring(1); continue; } int pos = path.indexOf('/'); String parentPath = (pos > 0) ? path.substring(0, pos) : path; String subpath = (pos > 0) ? path.substring(pos+1, path.length()) : null; alma.TMCDB.maci.ContainerNode parentContainer = (alma.TMCDB.maci.ContainerNode)parentMap.get(parentPath); if (parentContainer == null) { parentContainer = new alma.TMCDB.maci.ContainerNode(); parentMap.put(parentPath, parentContainer); } parentMap = parentContainer._; path = subpath; } // unique key generation int count = 0; String key = baseKey; while (parentMap.containsKey(key)) key = baseKey + String.valueOf(++count); parentMap.put(key, data); if (data instanceof alma.TMCDB.maci.Container) { alma.TMCDB.maci.Container cont = (alma.TMCDB.maci.Container) data; m_logger.finer("Loaded container name=" + cont.Path + cont.getName() + ", implLang=" + cont.getImplLang()); } else { m_logger.warning("Bad container class '" + data.getClass().getName() + "' read from TMCDB."); } } } catch (Throwable th) { th.printStackTrace(); } return map; } public Object getChannelsTableMap() { final String keyField = "Name"; final Class type = alma.TMCDB.maci.EventChannel.class; try { Session session = hibernateUtil.getSession(); Method accessor = DOMJavaClassIntrospector.getAccessorMethod(type, keyField); Field field = null; if (accessor == null) { try { field = type.getField(keyField); } catch (Throwable th) { throw new IllegalStateException("failed to obtain key "); } } boolean channelsExist = false; Channels channels = new Channels(); alma.TMCDB.maci.NotificationServiceMapping mapping = (alma.TMCDB.maci.NotificationServiceMapping)session.createCriteria(alma.TMCDB.maci.NotificationServiceMapping.class).add(Restrictions.eq("ConfigurationId", configId)).uniqueResult(); if (mapping != null) { channels.setNotificationServiceMapping(mapping); channelsExist = true; } List list = getListForConfiguration(session, type); if (list.size() > 0) { channelsExist = true; } Map<String, EventChannelNode> map; if (channelsExist) { map = channels._; } else { return null; //map = new RootMap<String, EventChannelNode>(); } for (Object data : list) { String baseKey; if (accessor != null) baseKey = accessor.invoke(data, (Object[])null).toString(); else //if (field != null) baseKey = field.get(data).toString(); // baseKey should not be null Map parentMap = map; alma.TMCDB.maci.EventChannel channel = (alma.TMCDB.maci.EventChannel)data; // now find its map String path = getNormalizedPath(channel.Path); while (path != null && path.length() > 0) { // remove trailing slashes, to have unique curl (used for key) if (path.charAt(0) == '/') { path = path.substring(1); continue; } int pos = path.indexOf('/'); String parentPath = (pos > 0) ? path.substring(0, pos) : path; String subpath = (pos > 0) ? path.substring(pos+1, path.length()) : null; alma.TMCDB.maci.EventChannelNode parentChannel = (alma.TMCDB.maci.EventChannelNode)parentMap.get(parentPath); if (parentChannel == null) { parentChannel = new alma.TMCDB.maci.EventChannelNode(); parentMap.put(parentPath, parentChannel); } parentMap = parentChannel._; path = subpath; } // unique key generation int count = 0; String key = baseKey; while (parentMap.containsKey(key)) key = baseKey + String.valueOf(++count); parentMap.put(key, data); } return channels; } catch (Throwable th) { th.printStackTrace(); } return null; } // remove alma prefix private static final String getNormalizedPath(String path) { if (path != null && path.length() > 0) { final String ALMA = COMPONENT_TREE_NAME; final String ALMA_PREFIX = ALMA + "/"; if (path.equals(ALMA)) return null; else if (path.startsWith(ALMA_PREFIX)) return path.substring(ALMA_PREFIX.length()); else return path; } else return null; } /* (non-Javadoc) * @see com.cosylab.CDB.DALOperations#get_DAO_Servant(java.lang.String) */ public DAO get_DAO_Servant(String curl) throws CDBXMLErrorEx, CDBRecordDoesNotExistEx { checkAccess(); // remove trailing slashes, to have unique curl (used for key) if (curl.length() > 0 && curl.charAt(0) == '/') curl = curl.substring(1); // make sure there are no identical DAOs created synchronized (daoMap) { // get cached if (daoMap.containsKey(curl)) return daoMap.get(curl); Object node = curl.length() == 0 ? rootNode : DOMJavaClassIntrospector.getNode(curl, rootNode); if (node == null || DOMJavaClassIntrospector.isPrimitive(node.getClass())) { AcsJCDBRecordDoesNotExistEx ex = new AcsJCDBRecordDoesNotExistEx(); ex.setCurl(curl); m_logger.log(AcsLogLevel.NOTICE, "DAL::get_DAO_Servant " + ex.getShortDescription()); throw ex.toCDBRecordDoesNotExistEx(); } try { // create object id byte[] id = curl.getBytes(); Object objImpl = null; DAOPOA daoImpl = null; if (node instanceof DAOPOA) objImpl = daoImpl = (DAOPOA)node; else if (node instanceof DAOImpl) objImpl = daoImpl = new DAOPOATie((DAOImpl)node); else if (node instanceof XMLTreeNode) //objImpl = daoImpl = new DAOImpl(curl, (XMLTreeNode)node, poa, m_logger); objImpl = daoImpl = new DAOPOATie(new NoDestroyDAOImpl(curl, (XMLTreeNode)node, poa, m_logger)); else { //daoImpl = new HibernateDAOImpl(curl, node, poa, m_logger); HibernateWDAOImpl impl = new HibernateWDAOImpl(mainSession, curl, node, poa, m_logger); objImpl = impl; daoImpl = new DAOPOATie(impl); impl.setSetvant(daoImpl); } // activate object poa.activate_object_with_id(id, daoImpl); DAO href = DAOHelper.narrow(poa.servant_to_reference(daoImpl)); // map DAO reference daoMap.put(curl, href); daoObjMap.put(curl, objImpl); m_logger.log(AcsLogLevel.INFO, "Returning DAO servant for: " + curl); return href; } catch (Throwable t) { // @todo not clean, just to be consistent v DAL impl t.printStackTrace(); String info = "DAL::get_DAO_Servant " + t; AcsJCDBXMLErrorEx xmlErr = new AcsJCDBXMLErrorEx(t); xmlErr.setErrorString(info); m_logger.log(AcsLogLevel.NOTICE, info); throw xmlErr.toCDBXMLErrorEx(); } } } /* (non-Javadoc) * @see com.cosylab.CDB.DALOperations#get_DAO(java.lang.String) */ public String get_DAO(String curl) throws CDBXMLErrorEx, CDBRecordDoesNotExistEx { checkAccess(); // remove trailing slashes, to have unique curl (used for key) if (curl.length() > 0 && curl.charAt(0) == '/') curl = curl.substring(1); m_logger.log(AcsLogLevel.INFO, "Returning XML record for: " + curl); Object node = curl.length() == 0 ? rootNode : DOMJavaClassIntrospector.getNode(curl, rootNode); if (node == null || DOMJavaClassIntrospector.isPrimitive(node.getClass())) { AcsJCDBRecordDoesNotExistEx ex = new AcsJCDBRecordDoesNotExistEx(); ex.setCurl(curl); String detailMsg = ( node == null ? "node is null." : "node is primitive (" + node.getClass().getName() + ")."); m_logger.log(AcsLogLevel.NOTICE, detailMsg, ex); throw ex.toCDBRecordDoesNotExistEx(); } else if (node instanceof DAOImpl) { String ret = ((DAOImpl)node).getRootNode().toString(false); m_logger.finest("get_DAO(" + curl + ") returning " + ret); return ret; } // remove last slash if (curl.length() > 0 && curl.charAt(curl.length() - 1) == '/') curl = curl.substring(0, curl.length() - 1); // get node name only String name; int pos = curl.lastIndexOf('/'); if (pos == -1) name = curl; else name = curl.substring(pos+1, curl.length()); // root if (name.length() == 0) name = "root"; try { String ret = "<?xml version='1.0' encoding='ISO-8859-1'?>" + DOMJavaClassIntrospector.toXML(DOMJavaClassIntrospector.getRootNodeXMLName(name, node), node, curl, m_logger); m_logger.finest("get_DAO(" + curl + ") returning " + ret); return ret; } catch (Throwable t) { t.printStackTrace(); String info = "DAL::get_DAO " + t; AcsJCDBXMLErrorEx xmlErr = new AcsJCDBXMLErrorEx(t); xmlErr.setErrorString(info); m_logger.log(AcsLogLevel.NOTICE, info); throw xmlErr.toCDBXMLErrorEx(); } } protected String listNodes(String curl, boolean daosOnly) { final String EMPTY_STRING = ""; if (curl == null) curl = EMPTY_STRING; Object node = DOMJavaClassIntrospector.getNode(curl, rootNode); if (node == null || DOMJavaClassIntrospector.isPrimitive(node.getClass())) { /* AcsJCDBRecordDoesNotExistEx ex = new AcsJCDBRecordDoesNotExistEx(); ex.setCurl(curl); m_logger.log(AcsLogLevel.NOTICE, "list_nodes " + ex.getShortDescription()); throw ex.toCDBRecordDoesNotExistEx(); */ return EMPTY_STRING; } else { if (daosOnly) { if (node instanceof RootMap) return ""; else { if (DOMJavaClassIntrospector.getFields(node).length > 0 || DOMJavaClassIntrospector.getNodes(node).length > 0) return DOMJavaClassIntrospector.stringifyArray(DOMJavaClassIntrospector.getNodes(node), ' ') + " "; else return ""; } } ArrayList<String> listedNodex = new ArrayList<String>(); String[] subnodes = DOMJavaClassIntrospector.getSubnodes(node); for (String subnode : subnodes) { Object childNode = DOMJavaClassIntrospector.getNode(subnode, node); if (childNode == null) continue; boolean hasMapChildren = false; if (!(childNode instanceof RootMap) && DOMJavaClassIntrospector.isMapSubnode(subnode, node)) { hasMapChildren = true; Object subsubMap = DOMJavaClassIntrospector.getChild(DOMJavaClassIntrospector.SUBNODES_MAP_NAME, childNode); if (subsubMap instanceof Map && ((Map)subsubMap).size() > 0) hasMapChildren = false; } if (!hasMapChildren) listedNodex.add(subnode); } return DOMJavaClassIntrospector.stringifyArray(listedNodex.toArray(new String[listedNodex.size()]), ' '); } } /* (non-Javadoc) * @see com.cosylab.CDB.DALOperations#list_nodes(java.lang.String) */ public String list_nodes(String curl) { checkAccess(); String ret = listNodes(curl, false); m_logger.finest("list_nodes(=" + curl + ") returning " + ret); return ret; } /* (non-Javadoc) * @see com.cosylab.CDB.DALOperations#list_daos(java.lang.String) */ public String list_daos(String name) { checkAccess(); String ret = listNodes(name, true); m_logger.finest("list_daos(=" + name + ") returning " + ret); return ret; } /* (non-Javadoc) * @see com.cosylab.CDB.DALOperations#configuration_name() */ public String configuration_name() { return configName; } /* (non-Javadoc) * @see com.cosylab.CDB.WDALOperations#add_node(java.lang.String, java.lang.String) */ public void add_node(String curl, String xml) throws CDBExceptionEx, CDBXMLErrorEx, CDBRecordAlreadyExistsEx { checkAccess(); throw new NO_IMPLEMENT(); } /* (non-Javadoc) * @see com.cosylab.CDB.WDALOperations#remove_node(java.lang.String) */ public void remove_node(String curl) throws CDBRecordIsReadOnlyEx, CDBRecordDoesNotExistEx { checkAccess(); throw new NO_IMPLEMENT(); } /* (non-Javadoc) * @see com.cosylab.CDB.WDALOperations#get_WDAO_Servant(java.lang.String) */ public WDAO get_WDAO_Servant(String curl) throws CDBRecordIsReadOnlyEx, CDBXMLErrorEx, CDBRecordDoesNotExistEx { checkAccess(); // remove trailing slashes, to have unique curl (used for key) if (curl.length() > 0 && curl.charAt(0) == '/') curl = curl.substring(1); // make sure there are no identical DAOs created synchronized (wdaoMap) { // get cached if (wdaoMap.containsKey(curl)) return (WDAO)wdaoMap.get(curl); Object node = curl.length() == 0 ? rootNode : DOMJavaClassIntrospector.getNode(curl, rootNode); if (node == null || DOMJavaClassIntrospector.isPrimitive(node.getClass())) { AcsJCDBRecordDoesNotExistEx ex = new AcsJCDBRecordDoesNotExistEx(); ex.setCurl(curl); m_logger.log(AcsLogLevel.NOTICE, "WDAL::get_WDAO_Servant " + ex.getShortDescription()); throw ex.toCDBRecordDoesNotExistEx(); } try { Object objImpl = null; WDAOPOA wdaoImpl = null; if (node instanceof WDAOPOA) objImpl = wdaoImpl = (WDAOPOA)node; //else if (node instanceof XMLTreeNode) //{ // DAOImpl daoImpl = new DAOImpl(curl, (XMLTreeNode)node, poa, m_logger); // objImpl = wdaoImpl = new WDAOImpl(this, curl, daoImpl, poa, m_logger); //} else { HibernateWDAOImpl impl = new HibernateWDAOImpl(mainSession, curl, node, poa, m_logger); objImpl = impl; wdaoImpl = new WDAOPOATie(impl); impl.setSetvant(wdaoImpl); } // create object id byte[] id = ("WDAO"+curl).getBytes(); // activate object poa.activate_object_with_id(id, wdaoImpl); WDAO href = WDAOHelper.narrow(poa.servant_to_reference(wdaoImpl)); // map DAO reference wdaoMap.put(curl, href); wdaoObjMap.put(curl, objImpl); m_logger.log(AcsLogLevel.INFO, "Returning WDAO servant for: " + curl); return href; } catch (Throwable t) { // @todo not clean, just to be consistent v DAL impl String info = "WDAL::get_WDAO_Servant " + t; AcsJCDBXMLErrorEx xmlErr = new AcsJCDBXMLErrorEx(t); xmlErr.setErrorString(info); m_logger.log(AcsLogLevel.NOTICE, info); throw xmlErr.toCDBXMLErrorEx(); } } } /* (non-Javadoc) * @see com.cosylab.CDB.WDALOperations#set_DAO(java.lang.String, java.lang.String) */ public void set_DAO(String curl, String xml) throws CDBFieldDoesNotExistEx, CDBRecordIsReadOnlyEx, CDBExceptionEx, CDBXMLErrorEx, CDBRecordDoesNotExistEx { checkAccess(); m_logger.log(AcsLogLevel.INFO, "set_DAO: " + curl); // read given xml and iterate through its content and check if something was changed DAOImpl daoImp = null; XMLHandler daoXMLSolver = null; // get content of the given xml string using parser without any shemas and validation // since given xml string come from a client that have no shemas and it is full expanded version // of existing xml or it is small composed xml of few properties XMLHandler xmlSolver = new XMLHandler(false, m_logger); // TODO markArrays == 2 impl. is a mess... I think lot of code could be removed! //xmlSolver.setMarkArrays(2); parseXML(xml, xmlSolver); Object node = DOMJavaClassIntrospector.getNode(curl, rootNode); if (node == null) { AcsJCDBRecordDoesNotExistEx ex = new AcsJCDBRecordDoesNotExistEx(); ex.setCurl(curl); throw ex.toCDBRecordDoesNotExistEx(); } // node is saved as XML if (node instanceof XMLSaver) { XMLSaver saver = (XMLSaver)node; Transaction tr = null; try { tr = mainSession.beginTransaction(); saver.save(xml); tr.commit(); } catch (Throwable th) { if (tr != null) tr.rollback(); m_logger.log(AcsLogLevel.NOTICE, "Failed to set DAO: " + curl, th); AcsJCDBExceptionEx cdbex = new AcsJCDBExceptionEx(th); throw cdbex.toCDBExceptionEx(); } return; } // get original xml that we will use to compare xml = get_DAO(curl); daoXMLSolver = new XMLHandler(false, m_logger); parseXML(xml, daoXMLSolver); daoImp = new DAOImpl(curl, daoXMLSolver.m_rootNode, poa, m_logger); // iterater throuth given xml and put changed attributes in map LinkedHashMap map = new LinkedHashMap(); try{ checkforChanges("", xmlSolver.m_rootNode, map, daoImp); saveChanges(curl, map); }catch(AcsJCDBFieldDoesNotExistEx e){ throw e.toCDBFieldDoesNotExistEx(); }catch(AcsJCDBXMLErrorEx e){ throw e.toCDBXMLErrorEx(); } } /** * Save changes given by map to the node identified by curl * * @param curl * @param propertyMap * * @throws CDBXMLErrorEx * @throws CDBExceptionEx * @throws CDBFieldDoesNotExistEx */ public void saveChanges(String curl, Map propertyMap) throws CDBXMLErrorEx, CDBExceptionEx, CDBFieldDoesNotExistEx, CDBRecordDoesNotExistEx { Object node = curl.length() == 0 ? rootNode : DOMJavaClassIntrospector.getNode(curl, rootNode); if (node == null || DOMJavaClassIntrospector.isPrimitive(node.getClass())) { AcsJCDBRecordDoesNotExistEx ex = new AcsJCDBRecordDoesNotExistEx(); ex.setCurl(curl); m_logger.log(AcsLogLevel.NOTICE, "WDAL::saveChanges " + ex.getShortDescription()); throw ex.toCDBRecordDoesNotExistEx(); } boolean commit = false; Transaction tr = mainSession.beginTransaction(); try { HibernateWDAOImpl wdao = new HibernateWDAOImpl(mainSession, curl, node, poa, m_logger, false, false); for (Object key : propertyMap.keySet()) { String propertyName = key.toString(); wdao.set_field_data(propertyName, propertyMap.get(propertyName).toString()); } commit = true; } catch (CDBFieldIsReadOnlyEx fne) { AcsJCDBExceptionEx cdbex = new AcsJCDBExceptionEx(fne); throw cdbex.toCDBExceptionEx(); } catch (WrongCDBDataTypeEx fne) { AcsJCDBExceptionEx cdbex = new AcsJCDBExceptionEx(fne); throw cdbex.toCDBExceptionEx(); } finally { if (commit) tr.commit(); else tr.rollback(); } /// TODO revert memory state?!!! } // ------------------------------------------------------------------------------ // code below copied from DALImpl // ------------------------------------------------------------------------------ /** * Recursively scans nodes and check every property with current xml * * @param name * @param node * @param map * @param dao * * @throws AcsJCDBFieldDoesNotExistEx * @throws AcsJCDBXMLErrorEx */ private void checkforChanges(String name, XMLTreeNode node, Map map, DAOImpl dao) throws AcsJCDBFieldDoesNotExistEx, AcsJCDBXMLErrorEx { String propertyName; String currentValue; String value; // if this node represents an array then add its contents into map // this will be the case when we cheking full expanded version of a XML //if(node.isArrayNode()) { // XMLTreeNode arrNode = (XMLTreeNode)node.m_subNodesMap.get(XMLTreeNode.ARRAY_MARKER); for(Iterator iter = node.m_subNodesMap.keySet().iterator(); iter.hasNext();) { String key = (String)iter.next(); XMLTreeNode childNode = (XMLTreeNode)node.m_subNodesMap.get(key); if(childNode.isMapNode()){ for(Iterator iterator = childNode.m_fieldMap.keySet().iterator();iterator.hasNext();) { String childKey = (String)iterator.next(); map.put(XMLTreeNode.MAP_TYPE + "/" + key + "/" + childKey, childNode.m_fieldMap.get(childKey)); } node.m_subNodesMap.clear(); } } // node attributes i.e 'CommandLine' in node 'Manager' for(Iterator iter = node.m_fieldMap.keySet().iterator(); iter.hasNext();) { String key = (String)iter.next(); propertyName = name + "/" + key; try { currentValue = dao.get_field_data(propertyName); } catch(Exception e) { // TODO additional elements in maps will cause an exception... they are not supported // TODO also if an element is removed, this will not be detected e.printStackTrace(); AcsJCDBXMLErrorEx xmlErr = new AcsJCDBXMLErrorEx(e); throw xmlErr; } value = (String)node.m_fieldMap.get(key); if(!value.equals(currentValue)) { map.put(propertyName, value); } } // subnodes for this node i.e. 'current' for 'TEST_PS_1' for(Iterator iter = node.m_subNodesMap.keySet().iterator(); iter.hasNext();) { String key = (String)iter.next(); checkforChanges(name + "/" + key, (XMLTreeNode)node.m_subNodesMap.get(key), map, dao); } } private void parseXML(String xml, XMLHandler xmlSolver) throws CDBXMLErrorEx { try { SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser saxParser = factory.newSAXParser(); synchronized (xmlNodeMonitor) { saxParser.parse(new InputSource(new StringReader(xml)), xmlSolver); } if(xmlSolver.m_errorString != null) { String info = "XML parser error: " + xmlSolver.m_errorString; CDBXMLErrorEx xmlErr = new CDBXMLErrorEx(); m_logger.log(AcsLogLevel.NOTICE, info); throw xmlErr; } } catch(Throwable t) { String info = "SAXException: " + t.getMessage(); m_logger.log(AcsLogLevel.NOTICE, info); AcsJCDBXMLErrorEx xmlErr = new AcsJCDBXMLErrorEx(t); xmlErr.setErrorString(info); throw xmlErr.toCDBXMLErrorEx(); } } /** * Recovery related implementation. * Load list of listeners from the recovery file and notifies them to clear cache. * NOTICE: This method should be called when DAL POA is alrady initialized and active. * NOTE: Method execution depends on <code>recoveryRead</code> variable. */ public void recoverClients() { if( recoveryRead ) { // load listeners and notify them loadListeners(); new Thread (){ public void run() { clear_cache_all(); } }.start(); } } public void shutdown() { shutdown.set(true); orb.shutdown(false); } private void objectChangedForMap(String curl, Map map, Map objMap) { synchronized (map) { if (map.containsKey(curl)) { DAO dao = (DAO) map.get(curl); Object objDAO = objMap.get(curl); //New Implementation! dao.destroy(); byte[] id = curl.getBytes(); try { poa.deactivate_object(id); } catch (Throwable th) { th.printStackTrace(); } objMap.remove(curl); map.remove(curl); Object node = curl.length() == 0 ? rootNode : DOMJavaClassIntrospector.getNode(curl, rootNode); if (node == null || DOMJavaClassIntrospector.isPrimitive(node.getClass())) { return; } try { get_DAO_Servant(curl); } catch(Throwable th) { th.printStackTrace(); } //End new implementation. //Object node = curl.length() == 0 ? rootNode : DOMJavaClassIntrospector.getNode(curl, rootNode); //if (node == null || DOMJavaClassIntrospector.isPrimitive(node.getClass())) //{ // // no longer exists // dao.destroy(); // objMap.remove(curl); // map.remove(curl); //} // //if (objDAO instanceof DAOImpl) //{ // if (node instanceof XMLTreeNode) // ((DAOImpl)objDAO).setRootNode((XMLTreeNode)node); // else // { // // type changed, destroy this one and reactivate new // dao.destroy(); // objMap.remove(curl); // map.remove(curl); // try { // get_DAO_Servant(curl); // } catch (Throwable th) { th.printStackTrace(); } // } //} //else if (objDAO instanceof HibernateWDAOImpl) //{ // if (node instanceof XMLTreeNode) // { // // type changed, destroy this one and reactivate new // dao.destroy(); // map.remove(curl); // try { // get_DAO_Servant(curl); // } catch (Throwable th) { th.printStackTrace(); } // } // else // ((HibernateWDAOImpl)objDAO).setRootNode(node); //} } } } /** * @param curl */ protected void object_changed(String curl) { objectChangedForMap(curl, daoMap, daoObjMap); objectChangedForMap(curl, wdaoMap, wdaoObjMap); } /** * @return File */ protected File getStorageFile() { if (listenersStorageFile != null) return listenersStorageFile; String filePath = FileHelper.getTempFileName("ACS_RECOVERY_FILE", "CDB_Recovery.txt"); m_logger.log(AcsLogLevel.INFO, "Recovery file: " + filePath); listenersStorageFile = new File(filePath); // if file do not exists create a new one so we can set permission on it if( !listenersStorageFile.exists() ) { try { listenersStorageFile.createNewFile(); } catch (Exception e) { // nop } } FileHelper.setFileAttributes("g+w", filePath); return listenersStorageFile; } /** * */ public void loadListeners() { File storageFile = getStorageFile(); if (storageFile == null || !storageFile.exists()) return; try { InputStream in = new FileInputStream(storageFile); BufferedReader reader = new BufferedReader(new InputStreamReader(in)); // load listeners String line; while (true) { line = reader.readLine(); if (line == null || line.length() == 0) break; Integer id = new Integer(line); line = reader.readLine(); if (line == null || line.length() == 0) break; // try to narrow it DALChangeListener listener = DALChangeListenerHelper.narrow(orb.string_to_object(line)); synchronized (regListeners) { regListeners.put(id, listener); } } // then listened curls String curl; while (true) { curl = reader.readLine(); if (curl == null) break; ArrayList<Integer> arr = new ArrayList<Integer>(); while (true) { line = reader.readLine(); if (line == null || line.length() == 0) break; arr.add(new Integer(line)); } synchronized (listenedCurls) { listenedCurls.put(curl, arr); } } } catch (Exception e) { e.printStackTrace(); } } static final long LISTENER_RECOVERY_FILE_SAVE_FREQ_MS = 10000; // 10s private void startRecoverySaver() { if (lastSaveTime.compareAndSet(0, System.currentTimeMillis())) { new Thread(new Runnable() { @Override public void run() { saveLoop(); } }, "recovery file saver").start(); } } private void saveLoop() { while (!shutdown.get()) { // NOTE: solution with "sleep(LISTENER_RECOVERY_FILE_SAVE_FREQ_MS)" // gives worst time of 2*LISTENER_RECOVERY_FILE_SAVE_FREQ_MS time between saves try { Thread.sleep(1000); } catch (InterruptedException ie) { /* noop */ } long now = System.currentTimeMillis(); if ((now - lastSaveTime.get()) >= LISTENER_RECOVERY_FILE_SAVE_FREQ_MS) saveListenersInternal(); } } /** * @return boolean */ public boolean saveListeners() { saveRequest.set(true); return true; } /** * @return boolean */ private boolean saveListenersInternal() { synchronized (lastSaveTime) { if (!saveRequest.getAndSet(false)) return true; // set last time this method was called, also in case of failure lastSaveTime.set(System.currentTimeMillis()); String key, ior; File storageFile = getStorageFile(); if (storageFile == null) return false; try { OutputStream out = new FileOutputStream(storageFile); //listenedCurls.store(new FileOutputStream(storageFile), "Listeners"); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out)); // write listeners synchronized (regListeners) { Iterator reg = regListeners.keySet().iterator(); while (reg.hasNext()) { Integer id = (Integer) reg.next(); writer.write(id.toString()); writer.newLine(); ior = orb.object_to_string(regListeners.get(id)); writer.write(ior); writer.newLine(); } } // write listened curls synchronized (listenedCurls) { Iterator<String> iter = listenedCurls.keySet().iterator(); while (iter.hasNext()) { key = iter.next(); ArrayList arr = listenedCurls.get(key); if(arr.size() == 0 ) continue; // don't write curls without listeners // separator writer.newLine(); writer.write(key); writer.newLine(); for (int i = 0; i < arr.size(); i++) { writer.write(arr.get(i).toString()); writer.newLine(); } } } writer.flush(); } catch (Exception e) { e.printStackTrace(); return false; } return true; } } public int add_change_listener(DALChangeListener listener) { int id; while (true) { id = idPool.nextInt(Integer.MAX_VALUE); Integer key = new Integer(id); synchronized (regListeners) { if (!regListeners.containsKey(key)) { regListeners.put(key, listener); break; } } } return id; } public void listen_for_changes(String curl, int listenerID) { synchronized (listenedCurls) { ArrayList<Integer> listeners = listenedCurls.get(curl); if (listeners == null) { listeners = new ArrayList<Integer>(); listenedCurls.put(curl, listeners); } listeners.add(listenerID); saveListeners(); } } public void remove_change_listener(int listenerID) { synchronized (listenedCurls) { Iterator iter = listenedCurls.keySet().iterator(); // deattach this listener from its curls while (iter.hasNext()) { String curl = (String) iter.next(); ArrayList<Integer> listeners = listenedCurls.get(curl); if (listeners != null) { //listeners.remove(listener); for (int i = 0; i < listeners.size(); i++) { Integer id = listeners.get(i); if (id.intValue() == listenerID) { listeners.remove(i); i--; // just to test shifted } } } } // and delete it from list synchronized (regListeners) { regListeners.remove(new Integer(listenerID)); } saveListeners(); } } /** * Cleans listened curls from invalid listeners * to avoid repeatedly calling invalid listeners */ protected void cleanListenedCurls() { Iterator iter = listenedCurls.keySet().iterator(); while (iter.hasNext()) { String curl = (String) iter.next(); ArrayList listeners = (ArrayList) listenedCurls.get(curl); if (listeners == null) continue; for (int i = 0; i < listeners.size(); i++) { DALChangeListener listener = null; synchronized (regListeners) { listener = (DALChangeListener) regListeners.get(listeners.get(i)); } if( listener == null ) { listeners.remove(i); i--; } } } } protected void clearCache(String curl) { // NOTICE: this really does not reload the data from DB... // first take care of our own map m_logger.info("clear_cache(curl): clearCache1"); object_changed(curl); m_logger.info("clear_cache(curl): clearCache2"); // then notify all registered listeners synchronized (listenedCurls) { boolean needToSave = false; ArrayList<Integer> listeners = listenedCurls.get(curl); m_logger.info("clear_cache(curl): clearCache3"); if (listeners == null) { return; } ArrayList<Integer> invalidListeners = new ArrayList<Integer>(); m_logger.info("clear_cache(curl): clearCache4"); for (int i = 0; i < listeners.size(); i++) { DALChangeListener listener = null; synchronized (regListeners) { listener = regListeners.get(listeners.get(i)); } try { //System.out.println("Calling " + listener + " ..."); listener.object_changed(curl); //System.out.println("Done " + listener); } catch (RuntimeException e) { // silent here because who knows what happend with clients invalidListeners.add(listeners.get(i)); } } m_logger.info("clear_cache(curl): clearCache5"); // now remove invalid listeners if any for (int i = 0; i < invalidListeners.size(); i++) { listeners.remove(invalidListeners.get(i)); synchronized (regListeners) { regListeners.remove(invalidListeners.get(i)); } needToSave = true; } m_logger.info("clear_cache(curl): clearCache6"); if (needToSave) { cleanListenedCurls(); saveListeners(); } m_logger.info("clear_cache(curl): clearCache7"); } } public void clear_cache(String curl) { System.out.println("clear_cache(curl)"); if (loadInProgress.get()) { m_logger.warning("Incoming Corba call denied (NO_RESOURCES) because data is being loaded."); throw new NO_RESOURCES("load in progress"); } curl = curl.replaceAll("/+","/"); //Reload curl data from DB if(curl.matches("/")) { System.out.println("clear_cache_all()"); clear_cache_all(); return; } else { loadInProgress.set(true); m_logger.info("clear_cache(curl): Main1"); try { hibernateUtil.getSession().clear(); } catch (Throwable th) { th.printStackTrace(); } m_logger.info("clear_cache(curl): Main2"); String c = curl.replaceFirst("^/", ""); c = curl.replaceFirst("/$", ""); if (plugin != null) { try { Map<String, Object> rootMap = (Map<String, Object>) rootNode; Session session = hibernateUtil.getSession(); plugin.updatePrologue(session, config, rootMap, c); } catch (Throwable th) { this.m_logger.log(Level.SEVERE, "Failure in plugin " + plugin.getClass().getName(), th); th.printStackTrace(); } } m_logger.info("clear_cache(curl): Main3"); if(c.startsWith("MACI")) { loadMACI(c, true); //} else if (c.startsWith("Alarms"){ // loadAlarms(c); } else if (c.startsWith(COMPONENT_TREE_NAME)){ loadComponentsTree(c, true); } else { System.out.println("Unsupported curl: "+ curl); } m_logger.info("clear_cache(curl): Main4"); if (plugin != null) { try { Map<String, Object> rootMap = (Map<String, Object>) rootNode; Session session = hibernateUtil.getSession(); plugin.updateEpilogue(session, config, rootMap, c); } catch (Throwable th) { this.m_logger.log(Level.SEVERE, "Failure in plugin " + plugin.getClass().getName(), th); th.printStackTrace(); } } m_logger.info("clear_cache(curl): Main5"); loadInProgress.set(false); } //Set<String> curls = new HashSet<String>(); //curls.add(curl); //synchronized (daoMap) { // Iterator iter = daoMap.keySet().iterator(); // while (iter.hasNext()) { // String c = (String) iter.next(); // if(c.startsWith(curl)) // curls.add(c); // } //} //synchronized (wdaoMap) { // Iterator iter = wdaoMap.keySet().iterator(); // while (iter.hasNext()) { // String c = (String) iter.next(); // if(c.startsWith(curl)) // curls.add(c); // } //} // //synchronized (listenedCurls) { // Iterator iter = listenedCurls.keySet().iterator(); // while (iter.hasNext()) { // String c = (String) iter.next(); // if(c.startsWith(curl)) // curls.add(c); // } //} Set<String> curls = new HashSet<String>(); synchronized (daoMap) { curls.addAll(daoMap.keySet()); } m_logger.info("clear_cache(curl): Main6"); synchronized (wdaoMap) { curls.addAll(wdaoMap.keySet()); } m_logger.info("clear_cache(curl): Main7"); synchronized (listenedCurls) { Iterator iter = listenedCurls.keySet().iterator(); while (iter.hasNext()) { String c = (String) iter.next(); curls.add(c); } } m_logger.info("clear_cache(curl): Main8"); for (String c : curls) clearCache(c); m_logger.info("clear_cache(curl): Main9"); } protected void loadMACI(String curl, boolean reload) { System.out.println("loadMACI"); m_logger.info("clear_cache(curl): MACI1"); if(curl.matches("MACI")) { Map<String, Object> rootMap = (Map<String, Object>) rootNode; if(reload) { rootMap.put("MACI", (Object) null); System.gc(); } m_logger.info("clear_cache(curl): MACI2a"); rootMap.put("MACI", new RootMap<String, Object>()); m_logger.info("clear_cache(curl): MACI3a"); loadComponents("Components", false); m_logger.info("clear_cache(curl): MACI4a"); loadContainers("Containers", false); m_logger.info("clear_cache(curl): MACI5a"); loadChannels("Channels", false); m_logger.info("clear_cache(curl): MACI7a"); loadManagers("Managers", false); m_logger.info("clear_cache(curl): MACI6a"); //loadAcsServices("AcsServices", false); } else { String c = curl.replaceFirst("MACI/",""); if(c.startsWith("Components")){ loadComponents(c, true); } else if(c.startsWith("Containers")){ loadContainers(c, true); } else if(c.startsWith("Managers")){ loadManagers(c, true); } else if(c.startsWith("Channels")){ loadChannels(c, true); //} else if(c.startsWith("AcsServices")){ // loadAcsServices(c, true); } else { System.out.println("Unsupported curl: MACI/"+ curl); } m_logger.info("clear_cache(curl): MACI2b"); } } protected void loadComponents(String curl, boolean reload) { System.out.println("loadComponents"); m_logger.info("clear_cache(curl): Components1"); if(curl.matches("Components")) { Map<String, Object> rootMap = (Map<String, Object>) rootNode; if(reload) { ((Map<String, Object>)rootMap.get("MACI")).put("Components", null); System.gc(); } m_logger.info("clear_cache(curl): Components2a"); ((Map<String, Object>)rootMap.get("MACI")).put("Components", getComponentsTableMap()); m_logger.info("clear_cache(curl): Components3a"); } else { String c = curl.replaceFirst("Components/",""); updateComponentsTableMap(c); m_logger.info("clear_cache(curl): Components2b"); } } protected void loadContainers(String curl, boolean reload) { System.out.println("loadContainers"); m_logger.info("clear_cache(curl): Containers1"); if(curl.matches("Containers")) { Map<String, Object> rootMap = (Map<String, Object>) rootNode; if(reload) { ((Map<String, Object>)rootMap.get("MACI")).put("Containers", null); System.gc(); } m_logger.info("clear_cache(curl): Containers2a"); ((Map<String, Object>)rootMap.get("MACI")).put("Containers", getContainersTableMap()); m_logger.info("clear_cache(curl): Containers3a"); } else { String c = curl.replaceFirst("Containers/",""); updateContainersTableMap(c); m_logger.info("clear_cache(curl): Containers2b"); } } protected void loadManagers(String curl, boolean reload) { System.out.println("loadManagers"); m_logger.info("clear_cache(curl): Managers1"); if(curl.matches("Managers")) { Map<String, Object> rootMap = (Map<String, Object>) rootNode; if(reload) { ((Map<String, Object>)rootMap.get("MACI")).put("Managers", null); System.gc(); } m_logger.info("clear_cache(curl): Managers2a"); ((Map<String, Object>)rootMap.get("MACI")).put("Managers", getManagersTableMap()); m_logger.info("clear_cache(curl): Managers3a"); } else { String c = curl.replaceFirst("Managers/",""); if(c.equals("Manager")) { updateManagersTableMap(c); } else { System.out.println("Only one manager with name 'Manager' is accepted at the moment"); //updateManagersTableMap(c); } m_logger.info("clear_cache(curl): Managers2b"); } } protected void loadChannels(String curl, boolean reload) { System.out.println("loadChannels"); m_logger.info("clear_cache(curl): Channels1"); if(curl.matches("Channels")) { Map<String, Object> rootMap = (Map<String, Object>) rootNode; if(reload) { ((Map<String, Object>)rootMap.get("MACI")).put("Channels", null); System.gc(); } m_logger.info("clear_cache(curl): Channels2a"); ((Map<String, Object>)rootMap.get("MACI")).put("Channels", getChannelsTableMap()); m_logger.info("clear_cache(curl): Channels3a"); } else { String c = curl.replaceFirst("Channels/",""); updateChannelsTableMap(c); m_logger.info("clear_cache(curl): Channels2b"); } } //protected void loadAcsServices(String curl, boolean reload) { // System.out.println("loadAcsServices"); // if(curl.matches("AcsServices")) { // } else { // String c = curl.replaceFirst("AcsServices/",""); // } //} //protected void loadAlarms(String curl) { // if(curl.matches("Alarms")) { // loadAdministrative("Administrative"); // loadAlarmDefinitions("AlarmDefinitions"); // } else { // String c = curl.replaceFirst("Alarms/",""); // if(c.startsWith("Administrative")) { // loadAdministrative(c); // } else if(c.startsWith("AlarmDefinitions")) { // loadAlarmDefinitions(c); // } else { // System.out.println("Unsupported curl: ", curl); // } // } //} //protected void loadAdministrative(String curl) { // if(curl.matches("Administrative")) { // loadAlarmSystemConfiguration("AlarmSystemConfiguration"); // loadCategories("Categories"); // loadReductionDefinitions("ReductionDefinitions"); // } else { // String c = curl.replaceFirst("Administrative/"); // } //} //protected void loadAlarmDefinitions(String curl) { // if(curl.matches("AlarmDefinitions")) { // } else { // String c = curl.replaceFirst("AlarmDefinitions/"); // } //} protected void loadComponentsTree(String curl, boolean reload) { System.out.println("loadComponentsTree"); m_logger.info("clear_cache(curl): TREE1"); if(curl.matches(new String(COMPONENT_TREE_NAME))) { Map<String, Object> rootMap = (Map<String, Object>) rootNode; if(reload) { rootMap.put(COMPONENT_TREE_NAME, null); System.gc(); } m_logger.info("clear_cache(curl): TREE2a"); rootMap.put(COMPONENT_TREE_NAME, getAlmaBranch()); } else { String c = curl.replaceFirst(new String(COMPONENT_TREE_NAME+"/"),""); updateAlmaBranch(c); m_logger.info("clear_cache(curl): TREE2b"); } } public Map<String, Object> getManagersTableMap() { m_logger.info("clear_cache(curl): ManagersTable1"); Map<String, Object> managersMap = new RootMap<String, Object>(); try { Session session = hibernateUtil.getSession(); m_logger.info("clear_cache(curl): ManagersTable2"); List managerList = getListForConfiguration(session, alma.TMCDB.maci.Manager.class); m_logger.info("clear_cache(curl): ManagersTable3"); if (!managerList.isEmpty()) managersMap.put("Manager", managerList.get(0)); else managersMap.put("Manager", getDefaultMangerConfig()); m_logger.info("clear_cache(curl): ManagersTable4"); String additionalServices = getAcsServices(session, config); m_logger.info("clear_cache(curl): ManagersTable5"); if (additionalServices != null) { alma.TMCDB.maci.Manager manager = (alma.TMCDB.maci.Manager)managersMap.get("Manager"); m_logger.info("clear_cache(curl): ManagersTable6"); String currentServices = manager.getServiceComponents(); m_logger.info("clear_cache(curl): ManagersTable7"); if (currentServices == null || currentServices.length() == 0) manager.setServiceComponents(additionalServices); else // there might be duplicates, but they do not harm manager.setServiceComponents(currentServices + "," + additionalServices); m_logger.info("clear_cache(curl): ManagersTable8"); } } catch (Throwable th) { th.printStackTrace(); } m_logger.info("clear_cache(curl): ManagersTable9"); return managersMap; } protected Criterion getRegularExpressionRestriction(String columnName, String re) { if(forceInMemory) { return Restrictions.sqlRestriction("REGEXP_MATCHES("+columnName+", ?)", re, org.hibernate.Hibernate.STRING); //HSQLDB } else { //return Restrictions.sqlRestriction(columnName+" rlike ?", re, org.hibernate.Hibernate.STRING); //MySQL return Restrictions.sqlRestriction("REGEXP_LIKE("+columnName+", ?)", re, org.hibernate.Hibernate.STRING); //Oracle } } protected void updateComponentsTableMap(String curl) { m_logger.info("clear_cache(curl): ComponentsTable1"); final String keyField = "Name"; final Class type = alma.TMCDB.maci.Component.class; Map<String, Object> rootMap = (Map<String, Object>) rootNode; Map<String, Object> map = (Map<String, Object>)((Map<String, Object>) rootMap.get("MACI")).get("Components"); m_logger.info("clear_cache(curl): ComponentsTable2"); try { Session session = hibernateUtil.getSession(); Method accessor = DOMJavaClassIntrospector.getAccessorMethod(type, keyField); m_logger.info("clear_cache(curl): ComponentsTable3"); Field field = null; if (accessor == null) { try { field = type.getField(keyField); } catch (Throwable th) { throw new IllegalStateException("failed to obtain key "); } } m_logger.info("clear_cache(curl): ComponentsTable4"); String els[] = curl.split("/"); String rpath = "^/*"; String rsubpath = "^/*"; String rcpath = "^/*"; String rcname = els[els.length - 1]; for (int i = 0; i < els.length; i++) { rpath += els[i]; rsubpath += els[i]; if (i < els.length - 1) { rpath += "/+"; rsubpath += "/+"; rcpath += els[i]; if( i < els.length - 2) rcpath += "/+"; } } rpath += "/*$"; rsubpath += "/+.*"; rcpath += "/*$"; System.out.println(rpath); System.out.println(rsubpath); System.out.println(rcpath+"|"+rcname); m_logger.info("clear_cache(curl): ComponentsTable5"); //Consider the cases where the curl matches exactly the Path, where //it is part of the path and when it matches exactly the path and //the component name. Criterion cr = Restrictions.disjunction() .add(getRegularExpressionRestriction("Path", rpath)) .add(getRegularExpressionRestriction("Path", rsubpath)) .add(Restrictions.and(getRegularExpressionRestriction("Path", rcpath), Restrictions.eq("Name",rcname))); m_logger.info("clear_cache(curl): ComponentsTable6"); List list = getListForConfiguration(session, type, cr); m_logger.info("clear_cache(curl): ComponentsTable7"); System.out.println("\nFound the following Components"); for(Object data : list) { System.out.println(((alma.TMCDB.maci.Component)data).Path+"/"+((alma.TMCDB.maci.Component)data).getName()); } m_logger.info("clear_cache(curl): ComponentsTable8"); //Remove the entries from existing maps. System.out.println("\nChecking maps to remove"); Map rParentMap = map; for(int i = 0; i < els.length; i++) { System.out.println("Checking path "+els[i]+"."); System.out.println("Parent keys: "+rParentMap.keySet().toString()); Object data = rParentMap.get(els[i]); if (data == null) { System.out.println("No element found with the given curl"); break; } else { if (data instanceof alma.TMCDB.maci.Component) { System.out.println("Instance of Component (Component!)."); } else if (data instanceof alma.TMCDB.maci.ComponentNode) { System.out.println("Instance of ComponentNode (Path!)."); } else { System.out.println("Unknown type! Details: "+data.toString()); } if (i < els.length - 1) { System.out.println("There are elements remaining, so we proceed to next element in path."); rParentMap = ((alma.TMCDB.maci.ComponentNode) data)._; } else { System.out.println("There are no elements remaining, we remove all entries from this element in path and on."); rParentMap.remove(els[i]); } } } m_logger.info("clear_cache(curl): ComponentsTable9"); // Sort the list by path + component to ensure that parent components are added before their children Comparator<alma.TMCDB.maci.Component> comparator = new Comparator<alma.TMCDB.maci.Component>() { public int compare(alma.TMCDB.maci.Component o1, alma.TMCDB.maci.Component o2) { String fullName1 = ((o1.Path == null ? "" : o1.Path) + "/") + o1.getName(); String fullName2 = ((o2.Path == null ? "" : o2.Path) + "/") + o2.getName(); return fullName1.compareTo(fullName2); } }; Collections.sort(list, comparator); m_logger.info("clear_cache(curl): ComponentsTable10"); for (Object data : list) { String baseKey; if (accessor != null) baseKey = accessor.invoke(data, (Object[])null).toString(); else //if (field != null) baseKey = field.get(data).toString(); // baseKey should not be null Map parentMap = map; alma.TMCDB.maci.Component component = (alma.TMCDB.maci.Component)data; // some cleaning if (component.getComponentLogger().getMinLogLevel() == -1 && component.getComponentLogger().getMinLogLevelLocal() == -1) component.setComponentLogger(null); // now find its map String path = getNormalizedPath(component.Path); while (path != null && path.length() > 0) { // remove trailing slashes, to have unique curl (used for key) if (path.charAt(0) == '/') { path = path.substring(1); continue; } int pos = path.indexOf('/'); String parentPath = (pos > 0) ? path.substring(0, pos) : path; String subpath = (pos > 0) ? path.substring(pos+1, path.length()) : null; alma.TMCDB.maci.ComponentNode parentComponent = (alma.TMCDB.maci.ComponentNode)parentMap.get(parentPath); if (parentComponent == null) { parentComponent = new alma.TMCDB.maci.ComponentNode(); parentMap.put(parentPath, parentComponent); } parentMap = parentComponent._; path = subpath; } // unique key generation int count = 0; String key = baseKey; while (parentMap.containsKey(key)) key = baseKey + String.valueOf(++count); parentMap.put(key, data); if (data instanceof alma.TMCDB.maci.Component) { alma.TMCDB.maci.Component comp = (alma.TMCDB.maci.Component) data; m_logger.finer("Loaded component name=" + comp.Path + comp.getName() + ", type=" + comp.getType() + ", container=" + comp.getContainer() + ", implLang=" + comp.getImplLang()); } else { m_logger.warning("Bad component class '" + data.getClass().getName() + "' read from TMCDB."); } m_logger.info("clear_cache(curl): ComponentsTable11"); } m_logger.info("clear_cache(curl): ComponentsTable12"); } catch (Throwable th) { th.printStackTrace(); } m_logger.info("clear_cache(curl): ComponentsTable13"); } public void updateContainersTableMap(String curl) { m_logger.info("clear_cache(curl): ContainersTable1"); final String keyField = "Name"; final Class type = alma.TMCDB.maci.Container.class; Map<String, Object> rootMap = (Map<String, Object>) rootNode; Map<String, Object> map = (Map<String, Object>)((Map<String, Object>) rootMap.get("MACI")).get("Containers"); m_logger.info("clear_cache(curl): ContainersTable2"); try { Session session = hibernateUtil.getSession(); Method accessor = DOMJavaClassIntrospector.getAccessorMethod(type, keyField); Field field = null; if (accessor == null) { try { field = type.getField(keyField); } catch (Throwable th) { throw new IllegalStateException("failed to obtain key "); } } m_logger.info("clear_cache(curl): ContainersTable3"); String els[] = curl.split("/"); String rpath = "^/*"; String rsubpath = "^/*"; String rcpath = "^/*"; String rcname = els[els.length - 1]; for (int i = 0; i < els.length; i++) { rpath += els[i]; rsubpath += els[i]; if (i < els.length - 1) { rpath += "/+"; rsubpath += "/+"; rcpath += els[i]; if( i < els.length - 2) rcpath += "/+"; } } rpath += "/*$"; rsubpath += "/+.*"; rcpath += "/*$"; System.out.println(rpath); System.out.println(rsubpath); System.out.println(rcpath+"|"+rcname); m_logger.info("clear_cache(curl): ContainersTable4"); //Consider the cases where the curl matches exactly the Path, where //it is part of the path and when it matches exactly the path and //the component name. Criterion cr = Restrictions.disjunction() .add(getRegularExpressionRestriction("Path", rpath)) .add(getRegularExpressionRestriction("Path", rsubpath)) .add(Restrictions.and(getRegularExpressionRestriction("Path", rcpath), Restrictions.eq("Name",rcname))); m_logger.info("clear_cache(curl): ContainersTable5"); List list = getListForConfiguration(session, type, cr); m_logger.info("clear_cache(curl): ContainersTable6"); System.out.println("\nFound the following Containers"); for(Object data : list) { System.out.println(((alma.TMCDB.maci.Container)data).Path+"/"+((alma.TMCDB.maci.Container)data).getName()); } //Remove the entries from existing maps. System.out.println("\nChecking maps to remove"); m_logger.info("clear_cache(curl): ContainersTable7"); Map rParentMap = map; for(int i = 0; i < els.length; i++) { System.out.println("Checking path "+els[i]+"."); System.out.println("Parent keys: "+rParentMap.keySet().toString()); Object data = rParentMap.get(els[i]); if (data == null) { System.out.println("No element found with the given curl"); break; } else { if (data instanceof alma.TMCDB.maci.Container) { System.out.println("Instance of Container (Container!)."); } else if (data instanceof alma.TMCDB.maci.ContainerNode) { System.out.println("Instance of ContainerNode (Path!)."); } else { System.out.println("Unknown type! Details: "+data.toString()); } if (i < els.length - 1) { System.out.println("There are elements remaining, so we proceed to next element in path."); rParentMap = ((alma.TMCDB.maci.ContainerNode) data)._; } else { System.out.println("There are no elements remaining, we remove all entries from this element in path and on."); rParentMap.remove(els[i]); } } } m_logger.info("clear_cache(curl): ContainersTable8"); // Sort the list by path + component to ensure that parent containers are added before their children Comparator<alma.TMCDB.maci.Container> comparator = new Comparator<alma.TMCDB.maci.Container>() { public int compare(alma.TMCDB.maci.Container o1, alma.TMCDB.maci.Container o2) { String fullName1 = ((o1.Path == null ? "" : o1.Path) + "/") + o1.getName(); String fullName2 = ((o2.Path == null ? "" : o2.Path) + "/") + o2.getName(); return fullName1.compareTo(fullName2); } }; Collections.sort(list, comparator); m_logger.info("clear_cache(curl): ContainersTable9"); for (Object data : list) { String baseKey; if (accessor != null) baseKey = accessor.invoke(data, (Object[])null).toString(); else //if (field != null) baseKey = field.get(data).toString(); // baseKey should not be null Map parentMap = map; alma.TMCDB.maci.Container container = (alma.TMCDB.maci.Container)data; // do not include this if (DUMMY_CONTAINER_FLAG.equals(container.getDeployInfo().getTypeModifiers())) continue; // some cleaning if (container.getDeployInfo() != null && container.getDeployInfo().getHost() == null) container.setDeployInfo(null); // now find its map String path = getNormalizedPath(container.Path); while (path != null && path.length() > 0) { // remove trailing slashes, to have unique curl (used for key) if (path.charAt(0) == '/') { path = path.substring(1); continue; } int pos = path.indexOf('/'); String parentPath = (pos > 0) ? path.substring(0, pos) : path; String subpath = (pos > 0) ? path.substring(pos+1, path.length()) : null; alma.TMCDB.maci.ContainerNode parentContainer = (alma.TMCDB.maci.ContainerNode)parentMap.get(parentPath); if (parentContainer == null) { parentContainer = new alma.TMCDB.maci.ContainerNode(); parentMap.put(parentPath, parentContainer); } parentMap = parentContainer._; path = subpath; } // unique key generation int count = 0; String key = baseKey; while (parentMap.containsKey(key)) key = baseKey + String.valueOf(++count); parentMap.put(key, data); if (data instanceof alma.TMCDB.maci.Container) { alma.TMCDB.maci.Container cont = (alma.TMCDB.maci.Container) data; m_logger.finer("Loaded container name=" + cont.Path + cont.getName() + ", implLang=" + cont.getImplLang()); } else { m_logger.warning("Bad container class '" + data.getClass().getName() + "' read from TMCDB."); } m_logger.info("clear_cache(curl): ContainersTable10"); } m_logger.info("clear_cache(curl): ContainersTable11"); } catch (Throwable th) { th.printStackTrace(); } m_logger.info("clear_cache(curl): ContainersTable12"); } protected void updateManagersTableMap(String curl) { m_logger.info("clear_cache(curl): ManagersTable1"); Map<String, Object> rootMap = (Map<String, Object>) rootNode; Map<String, Object> managersMap = (Map<String, Object>) rootMap.get("Managers"); m_logger.info("clear_cache(curl): ManagersTable2"); try { Session session = hibernateUtil.getSession(); Criterion cr = Restrictions.eq("Name", curl); List managerList = getListForConfiguration(session, alma.TMCDB.maci.Manager.class, cr); m_logger.info("clear_cache(curl): ManagersTable3"); if (!managerList.isEmpty()) managersMap.put("Manager", managerList.get(0)); else managersMap.put("Manager", getDefaultMangerConfig()); m_logger.info("clear_cache(curl): ManagersTable4"); String additionalServices = getAcsServices(session, config); m_logger.info("clear_cache(curl): ManagersTable5"); if (additionalServices != null) { alma.TMCDB.maci.Manager manager = (alma.TMCDB.maci.Manager)managersMap.get("Manager"); String currentServices = manager.getServiceComponents(); m_logger.info("clear_cache(curl): ManagersTable6"); if (currentServices == null || currentServices.length() == 0) manager.setServiceComponents(additionalServices); else // there might be duplicates, but they do not harm manager.setServiceComponents(currentServices + "," + additionalServices); m_logger.info("clear_cache(curl): ManagersTable7"); } } catch (Throwable th) { th.printStackTrace(); } m_logger.info("clear_cache(curl): ManagersTable8"); } public void updateChannelsTableMap(String curl) { m_logger.info("clear_cache(curl): ChannelsTable1"); final String keyField = "Name"; final Class type = alma.TMCDB.maci.EventChannel.class; Map<String, Object> rootMap = (Map<String, Object>) rootNode; Channels channels = (Channels)((Map<String, Object>) rootMap.get("MACI")).get("Channels"); m_logger.info("clear_cache(curl): ChannelsTable2"); try { Session session = hibernateUtil.getSession(); Method accessor = DOMJavaClassIntrospector.getAccessorMethod(type, keyField); Field field = null; if (accessor == null) { try { field = type.getField(keyField); } catch (Throwable th) { throw new IllegalStateException("failed to obtain key "); } } if (channels == null) channels = new Channels(); Map<String, EventChannelNode> map; map = channels._; m_logger.info("clear_cache(curl): ChannelsTable3"); alma.TMCDB.maci.NotificationServiceMapping mapping = (alma.TMCDB.maci.NotificationServiceMapping)session.createCriteria(alma.TMCDB.maci.NotificationServiceMapping.class).add(Restrictions.eq("ConfigurationId", configId)).uniqueResult(); m_logger.info("clear_cache(curl): ChannelsTable4"); if (mapping != null) { channels.setNotificationServiceMapping(mapping); } m_logger.info("clear_cache(curl): ChannelsTable5"); String els[] = curl.split("/"); String rpath = "^/*"; String rsubpath = "^/*"; String rcpath = "^/*"; String rcname = els[els.length - 1]; for (int i = 0; i < els.length; i++) { rpath += els[i]; rsubpath += els[i]; if (i < els.length - 1) { rpath += "/+"; rsubpath += "/+"; rcpath += els[i]; if( i < els.length - 2) rcpath += "/+"; } } rpath += "/*$"; rsubpath += "/+.*"; rcpath += "/*$"; System.out.println(rpath); System.out.println(rsubpath); System.out.println(rcpath+"|"+rcname); m_logger.info("clear_cache(curl): ChannelsTable6"); //Consider the cases where the curl matches exactly the Path, where //it is part of the path and when it matches exactly the path and //the component name. Criterion cr = Restrictions.disjunction() .add(getRegularExpressionRestriction("Path", rpath)) .add(getRegularExpressionRestriction("Path", rsubpath)) .add(Restrictions.and(getRegularExpressionRestriction("Path", rcpath), Restrictions.eq("Name",rcname))); List list = getListForConfiguration(session, type, cr); m_logger.info("clear_cache(curl): ChannelsTable7"); System.out.println("\nFound the following Containers"); for(Object data : list) { System.out.println(((alma.TMCDB.maci.Container)data).Path+"/"+((alma.TMCDB.maci.Container)data).getName()); } //Remove the entries from existing maps. System.out.println("\nChecking maps to remove"); m_logger.info("clear_cache(curl): ChannelsTable8"); Map<String, EventChannelNode> rParentMap = map; for(int i = 0; i < els.length; i++) { System.out.println("Checking path "+els[i]+"."); System.out.println("Parent keys: "+rParentMap.keySet().toString()); Object data = rParentMap.get(els[i]); if (data == null) { System.out.println("No element found with the given curl"); break; } else { if (data instanceof alma.TMCDB.maci.EventChannel) { System.out.println("Instance of EventChannel (EventChannel!)."); } else if (data instanceof alma.TMCDB.maci.EventChannelNode) { System.out.println("Instance of ContainerNode (Path!)."); } else { System.out.println("Unknown type! Details: "+data.toString()); } if (i < els.length - 1) { System.out.println("There are elements remaining, so we proceed to next element in path."); rParentMap = ((alma.TMCDB.maci.EventChannelNode) data)._; } else { System.out.println("There are no elements remaining, we remove all entries from this element in path and on."); rParentMap.remove(els[i]); } } } m_logger.info("clear_cache(curl): ChannelsTable9"); for (Object data : list) { String baseKey; if (accessor != null) baseKey = accessor.invoke(data, (Object[])null).toString(); else //if (field != null) baseKey = field.get(data).toString(); // baseKey should not be null Map parentMap = map; alma.TMCDB.maci.EventChannel channel = (alma.TMCDB.maci.EventChannel)data; // now find its map String path = getNormalizedPath(channel.Path); while (path != null && path.length() > 0) { // remove trailing slashes, to have unique curl (used for key) if (path.charAt(0) == '/') { path = path.substring(1); continue; } int pos = path.indexOf('/'); String parentPath = (pos > 0) ? path.substring(0, pos) : path; String subpath = (pos > 0) ? path.substring(pos+1, path.length()) : null; alma.TMCDB.maci.EventChannelNode parentChannel = (alma.TMCDB.maci.EventChannelNode)parentMap.get(parentPath); if (parentChannel == null) { parentChannel = new alma.TMCDB.maci.EventChannelNode(); parentMap.put(parentPath, parentChannel); } parentMap = parentChannel._; path = subpath; } // unique key generation int count = 0; String key = baseKey; while (parentMap.containsKey(key)) key = baseKey + String.valueOf(++count); parentMap.put(key, data); m_logger.info("clear_cache(curl): ChannelsTable10"); } m_logger.info("clear_cache(curl): ChannelsTable11"); } catch (Throwable th) { th.printStackTrace(); } m_logger.info("clear_cache(curl): ChannelsTable12"); } protected void updateAlmaBranch(String curl) { m_logger.info("clear_cache(curl): AlmaBranch1"); Map<String, Object> rootMap = (Map<String, Object>) rootNode; final Map<String, Object> almaRoot = (Map<String, Object>) rootMap.get(COMPONENT_TREE_NAME); m_logger.info("clear_cache(curl): AlmaBranch2"); try { Session session = hibernateUtil.getSession(); schemaResourceResolverLoader.setSession(session); String els[] = curl.split("/"); String rpath = "^/*"; String rsubpath = "^/*"; String rcpath = "^/*"; String rcname = els[els.length - 1]; for (int i = 0; i < els.length; i++) { rpath += els[i]; rsubpath += els[i]; if (i < els.length - 1) { rpath += "/+"; rsubpath += "/+"; rcpath += els[i]; if( i < els.length - 2) rcpath += "/+"; } } rpath += "/*$"; rsubpath += "/+.*"; rcpath += "/*$"; System.out.println(rpath); System.out.println(rsubpath); System.out.println(rcpath+"|"+rcname); m_logger.info("clear_cache(curl): AlmaBranch3"); //Consider the cases where the curl matches exactly the Path, where //it is part of the path and when it matches exactly the path and //the component name. Criterion cr = Restrictions.disjunction() .add(getRegularExpressionRestriction("Path", rpath)) .add(getRegularExpressionRestriction("Path", rsubpath)) .add(Restrictions.and(getRegularExpressionRestriction("Path", rcpath), Restrictions.eq("Name",rcname))); //Remove the entries from existing maps. System.out.println("\nChecking maps to remove"); m_logger.info("clear_cache(curl): AlmaBranch4"); Map rParentMap = almaRoot; for(int i = 0; i < els.length; i++) { System.out.println("Checking path "+els[i]+"."); System.out.println("Parent keys: "+rParentMap.keySet().toString()); Object data = rParentMap.get(els[i]); if (data == null) { System.out.println("No element found with the given curl"); break; } else { if (data instanceof ComponentDAOImplSaver) { System.out.println("Instance of ComponentDAOImplSaver (Component!)."); } else if (data instanceof ComponentData) { System.out.println("Instance of ComponentData (Path!)."); } else { System.out.println("Unknown type! Details: "+data.toString()); } if (i < els.length - 1) { System.out.println("There are elements remaining, so we proceed to next element in path."); rParentMap = ((ComponentData) data)._; } else { System.out.println("There are no elements remaining, we remove all entries from this element in path and on."); rParentMap.remove(els[i]); } } } m_logger.info("clear_cache(curl): AlmaBranch5"); final Set<String> loadedComponents = new HashSet<String>(); // // add control devices // m_logger.info("clear_cache(curl): AlmaBranch6"); if (plugin != null) { final HibernateWDALPlugin.ControlDeviceBindCallback bindCallback = new HibernateWDALPlugin.ControlDeviceBindCallback() { public void bindToComponentBranch(String name, String path, Object objectToBind) { bindToAlmaBranch(almaRoot, name, path, objectToBind); if (!loadedComponents.contains(path + "/" + name)) loadedComponents.add(path + "/" + name); } public void bindNonExpandedXMLToComponentBranch(Session session, Component component) { alma.TMCDB.maci.Component comp = (alma.TMCDB.maci.Component)session.createCriteria(alma.TMCDB.maci.Component.class). add(Restrictions.eq("ComponentId", component.getComponentId())).uniqueResult(); if (comp == null) throw new RuntimeException("Component with ID " + component.getComponentId() + " does not exist."); bindNonExpandedComponentXMLToAlmaBranch(session, almaRoot, comp); } }; plugin.updateControlDevices(session, config, bindCallback, curl); } m_logger.info("clear_cache(curl): AlmaBranch7"); // // add devices // Iterator componentList = session.createCriteria(alma.TMCDB.maci.Component.class). add(Restrictions.eq("Control", false)). add(Restrictions.eq("ConfigurationId", configId)).add(cr).list().iterator(); System.out.println("\nFound the following Components"); m_logger.info("clear_cache(curl): AlmaBranch8"); //while(componentList.hasNext()) { // Object data = componentList.next(); // System.out.println(((alma.TMCDB.maci.Component)data).Path+"/"+((alma.TMCDB.maci.Component)data).getName()); //} while (componentList.hasNext()) { alma.TMCDB.maci.Component component = (alma.TMCDB.maci.Component)componentList.next(); System.out.println(component.Path+"/"+component.getName()); // already loaded by plugins, skip if (loadedComponents.contains(component.Path + "/" + component.getName())) continue; String query = "FROM alma.TMCDB.baci.BACIPropertyType WHERE ComponentId = " + component.ComponentId; List propertyList = session.createQuery(query).list(); System.out.println("Size: " + propertyList.size()); if (propertyList.size() > 0) { ComponentData componentData = new ComponentData(); try { componentData.setData(component.XMLDoc); } catch (Throwable e) { // TODO Auto-generated catch block e.printStackTrace(); } // add properties for (Iterator iter = propertyList.iterator(); iter.hasNext(); ) { BACIPropertyType baciProperty = (BACIPropertyType) iter.next(); //componentData._.put(baciProperty.PropertyName, baciProperty); componentData._.put(baciProperty.PropertyName, new EmptyStringHandlerBACIPropertyType(baciProperty)); } // bind object to map tree bindToAlmaBranch(almaRoot, component.getName(), component.Path, componentData); } else if (component.XMLDoc != null) { bindNonExpandedComponentXMLToAlmaBranch(session, almaRoot, component); } m_logger.info("clear_cache(curl): AlmaBranch9"); } m_logger.info("clear_cache(curl): AlmaBranch10"); } catch (Throwable th) { th.printStackTrace(); } m_logger.info("clear_cache(curl): AlmaBranch11"); } volatile boolean firstTime = true; public void clear_cache_all() { if (recoveryRead && firstTime) firstTime = false; else { reloadData(); } Set<String> curls = new HashSet<String>(); synchronized (daoMap) { curls.addAll(daoMap.keySet()); } synchronized (wdaoMap) { curls.addAll(wdaoMap.keySet()); } synchronized (listenedCurls) { Iterator iter = listenedCurls.keySet().iterator(); while (iter.hasNext()) { String curl = (String) iter.next(); curls.add(curl); } } for (String curl : curls) clearCache(curl); } // /////////////////////////////////////////////////////////// // LoggingConfigurable interface // /////////////////////////////////////////////////////////// // init logging LogConfig logConfig = ClientLogManager.getAcsLogManager().getLogConfig(); /** * Gets the log levels of the default logging configuration. These levels * are used by all loggers that have not been configured individually. */ public LogLevels get_default_logLevels() { LogLevels logLevels = new LogLevels(); logLevels.useDefault = false; logLevels.minLogLevel = (short) logConfig.getDefaultMinLogLevel().value; logLevels.minLogLevelLocal = (short) logConfig.getDefaultMinLogLevelLocal().value; return logLevels; } /** * Sets the log levels of the default logging configuration. These levels * are used by all loggers that have not been configured individually. */ public void set_default_logLevels(LogLevels levels) throws IllegalLogLevelsEx { try { logConfig.setDefaultMinLogLevel(AcsLogLevelDefinition.fromInteger(levels.minLogLevel)); logConfig.setDefaultMinLogLevelLocal(AcsLogLevelDefinition.fromInteger(levels.minLogLevelLocal)); } catch (AcsJIllegalArgumentEx ex) { //throw ex.toIllegalArgumentEx(); IllegalLogLevelsEx ille = new IllegalLogLevelsEx(ex.getErrorDesc()); throw ille; } } /** * Gets the names of all loggers, to allow configuring their levels * individually. The names are those that appear in the log records in the * field "SourceObject". This includes the container logger, ORB logger, * component loggers, and (only C++) GlobalLogger. * <p> * The returned logger names are randomly ordered. */ public String[] get_logger_names() { Set<String> loggerNames = logConfig.getLoggerNames(); return loggerNames.toArray(new String[loggerNames.size()]); } /** * Gets log levels for a particular named logger. If the returned field * LogLevels.useDefault is true, then the logger uses the default levels, * see get_default_logLevels(); otherwise the returned local and remote * levels apply. * <p> * For possible convenience, the default levels are returned in addition to * setting {@link LogLevels#useDefault} to <code>true</code>. */ public LogLevels get_logLevels(String logger_name) throws LoggerDoesNotExistEx { UnnamedLogger xsdLevels = logConfig.getNamedLoggerConfig(logger_name); boolean useDefault = !logConfig.hasCustomConfig(logger_name); LogLevels ret = AcsLogLevelDefinition.createIdlLogLevelsFromXsd(useDefault, xsdLevels); return ret; } /** * Sets log levels for a particular named logger. If levels.useDefault is * true, then the logger will be reset to using default levels; otherwise it * will use the supplied local and remote levels. */ public void set_logLevels(String logger_name, LogLevels levels) throws LoggerDoesNotExistEx, IllegalLogLevelsEx { if (levels.useDefault) { logConfig.clearNamedLoggerConfig(logger_name); } else { try { UnnamedLogger config = AcsLogLevelDefinition.createXsdLogLevelsFromIdl(levels); logConfig.setNamedLoggerConfig(logger_name, config); } catch (AcsJIllegalArgumentEx ex) { //throw ex.toIllegalArgumentEx(); IllegalLogLevelsEx ille = new IllegalLogLevelsEx(ex.getErrorDesc()); throw ille; } } } /** * Commands the container or manager to read in again the logging * configuration from the CDB and to reconfigure the loggers accordingly. * This allows for persistent changes in the logging configuration to become * effective, and also for changes of more advanced parameters. * <p> * Note that unlike for the logging initialization in {@link #initialize()}, * now we give precedence to the CDB values over any previous settings. */ public void refresh_logging_config() { try { logConfig.initialize(true); } catch (LogConfigException ex) { // if the CDB can't be read, we still want to run the container, thus we only log the problem here m_logger.log(Level.FINE, "Failed to configure logging (default values will be used).", ex); } } /** ************************ END LoggingConfigurable ************************ */ }