/* * TeleStax, Open Source Cloud Communications * Copyright 2012, Telestax Inc and individual contributors * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This 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 software 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 software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.mobicents.smsc.domain; import java.io.File; import java.io.FileNotFoundException; import java.util.Date; import java.util.List; import javax.management.InstanceAlreadyExistsException; import javax.management.InstanceNotFoundException; import javax.management.MBeanRegistrationException; import javax.management.MBeanServer; import javax.management.NotCompliantMBeanException; import javax.management.ObjectName; import javolution.text.TextBuilder; import javolution.util.FastList; import org.apache.log4j.Logger; import org.jboss.mx.util.MBeanServerLocator; import org.mobicents.smsc.cassandra.DBOperations; import org.mobicents.smsc.library.SmsSetCache; import org.mobicents.smsc.mproc.MProcRuleFactory; import org.restcomm.smpp.SmppManagement; /** * @author Amit Bhayani * @author sergey vetyutnev * */ public class SmscManagement implements SmscManagementMBean { private static final Logger logger = Logger.getLogger(SmscManagement.class); public static final String JMX_DOMAIN = "org.mobicents.smsc"; public static final String JMX_LAYER_SMSC_MANAGEMENT = "SmscManagement"; public static final String JMX_LAYER_SIP_MANAGEMENT = "SipManagement"; public static final String JMX_LAYER_MPROC_MANAGEMENT = "MProcManagement"; public static final String JMX_LAYER_ARCHIVE_SMS = "ArchiveSms"; public static final String JMX_LAYER_MAP_VERSION_CACHE = "MapVersionCache"; public static final String JMX_LAYER_SMSC_STATS = "SmscStats"; public static final String JMX_LAYER_SMSC_PROPERTIES_MANAGEMENT = "SmscPropertiesManagement"; public static final String JMX_LAYER_SMSC_DATABASE_MANAGEMENT = "SmscDatabaseManagement"; public static final String JMX_LAYER_HOME_ROUTING_MANAGEMENT = "HomeRoutingManagement"; public static final String JMX_LAYER_HTTPUSER_MANAGEMENT = "HttpUserManagement"; public static final String JMX_LAYER_DATABASE_SMS_ROUTING_RULE = "DatabaseSmsRoutingRule"; public static final String SMSC_PERSIST_DIR_KEY = "smsc.persist.dir"; public static final String USER_DIR_KEY = "user.dir"; private static final String PERSIST_FILE_NAME = "smsc.xml"; private final TextBuilder persistFile = TextBuilder.newInstance(); private final String name; private String persistDir = null; private SmppManagement smppManagement; private SipManagement sipManagement = null; private MProcManagement mProcManagement = null; private SmscPropertiesManagement smscPropertiesManagement = null; private HomeRoutingManagement homeRoutingManagement = null; private HttpUsersManagement httpUsersManagement = null; private SmscDatabaseManagement smscDatabaseManagement = null; private ArchiveSms archiveSms; private MapVersionCache mapVersionCache; private MBeanServer mbeanServer = null; private String smsRoutingRuleClass; private boolean isStarted = false; private static SmscManagement instance = null; private static SmscStatProvider smscStatProvider = null; private SmsRoutingRule smsRoutingRule = null; private FastList<MProcRuleFactory> mprocFactories = new FastList<MProcRuleFactory>(); private SmscManagement(String name) { this.name = name; // this.smppManagement = SmppManagement.getInstance("SmppManagement"); } public static SmscManagement getInstance(String name) { if (instance == null) { instance = new SmscManagement(name); } return instance; } public static SmscManagement getInstance() { return instance; } public String getName() { return name; } public String getPersistDir() { return persistDir; } public void setPersistDir(String persistDir) { this.persistDir = persistDir; // this.smppManagement.setPersistDir(persistDir); } public SmppManagement getSmppManagement() { return smppManagement; } public void setSmppManagement(SmppManagement smppManagement) { this.smppManagement = smppManagement; } public SmsRoutingRule getSmsRoutingRule() { return smsRoutingRule; } public ArchiveSms getArchiveSms() { return archiveSms; } /** * @return the smsRoutingRuleClass */ public String getSmsRoutingRuleClass() { return smsRoutingRuleClass; } /** * @param smsRoutingRuleClass * the smsRoutingRuleClass to set */ public void setSmsRoutingRuleClass(String smsRoutingRuleClass) { this.smsRoutingRuleClass = smsRoutingRuleClass; } public List getMProcRuleFactories() { return this.mprocFactories; } public List<MProcRuleFactory> getMProcRuleFactories2() { return this.mprocFactories; } public void setMProcRuleFactories(List ruleFactories) { this.mprocFactories = new FastList<MProcRuleFactory>(); for (Object obj : ruleFactories) { if (obj != null && obj instanceof MProcRuleFactory) { MProcRuleFactory ruleFactory = (MProcRuleFactory) obj; this.mprocFactories.add(ruleFactory); if (this.mProcManagement != null) { this.mProcManagement.bindAlias(ruleFactory); } } } } public void registerRuleFactory(MProcRuleFactory ruleFactory) { this.mprocFactories.add(ruleFactory); if (this.mProcManagement != null) { this.mProcManagement.bindAlias(ruleFactory); } } public void deregisterRuleFactory(String ruleFactoryName) { for (MProcRuleFactory rc : this.mprocFactories) { if (ruleFactoryName.equals(rc.getRuleClassName())) { this.mprocFactories.remove(rc); return; } } } public MProcRuleFactory getRuleFactory(String ruleFactoryName) { MProcRuleFactory ruleClass = null; for (MProcRuleFactory rc : this.mprocFactories) { if (ruleFactoryName.equals(rc.getRuleClassName())) { ruleClass = rc; break; } } return ruleClass; } public void start() throws Exception { logger.warn("Starting SmscManagemet " + name); SmscStatProvider.getInstance().setSmscStartTime(new Date()); // Step 0 clear SmsSetCashe SmsSetCache.getInstance().clearProcessingSmsSet(); // Step 1 Get the MBeanServer try { this.mbeanServer = MBeanServerLocator.locateJBoss(); } catch (Exception e) { this.logger.error("Exception when obtaining of MBeanServer: " + e.getMessage(), e); } // Step 2 Setup SMSC Properties / home routing properties this.smscPropertiesManagement = SmscPropertiesManagement.getInstance(this.name); this.smscPropertiesManagement.setPersistDir(this.persistDir); this.smscPropertiesManagement.start(); ObjectName smscObjNname = new ObjectName(SmscManagement.JMX_DOMAIN + ":layer=" + JMX_LAYER_SMSC_PROPERTIES_MANAGEMENT + ",name=" + this.getName()); this.registerMBean(this.smscPropertiesManagement, SmscPropertiesManagementMBean.class, true, smscObjNname); this.homeRoutingManagement = HomeRoutingManagement.getInstance(this.name); this.homeRoutingManagement.setPersistDir(this.persistDir); this.homeRoutingManagement.start(); ObjectName hrObjNname = new ObjectName(SmscManagement.JMX_DOMAIN + ":layer=" + JMX_LAYER_HOME_ROUTING_MANAGEMENT + ",name=" + this.getName()); this.registerMBean(this.homeRoutingManagement, HomeRoutingManagementMBean.class, true, hrObjNname); this.httpUsersManagement = HttpUsersManagement.getInstance(this.name); this.httpUsersManagement.setPersistDir(this.persistDir); this.httpUsersManagement.start(); ObjectName httpUsersObjNname = new ObjectName(SmscManagement.JMX_DOMAIN + ":layer=" + JMX_LAYER_HTTPUSER_MANAGEMENT + ",name=" + this.getName()); this.registerMBean(this.httpUsersManagement, HttpUsersManagementMBean.class, true, httpUsersObjNname); String hosts = smscPropertiesManagement.getDbHosts(); int port = smscPropertiesManagement.getDbPort(); DBOperations.getInstance().start(hosts, port, this.smscPropertiesManagement.getKeyspaceName(), this.smscPropertiesManagement.getCassandraUser(), this.smscPropertiesManagement.getCassandraPass(), this.smscPropertiesManagement.getFirstDueDelay(), this.smscPropertiesManagement.getReviseSecondsOnSmscStart(), this.smscPropertiesManagement.getProcessingSmsSetTimeout(), this.smscPropertiesManagement.getMinMessageId(), this.smscPropertiesManagement.getMaxMessageId()); // Step 3 SmsSetCashe.start() SmsSetCache.start(this.smscPropertiesManagement.getCorrelationIdLiveTime(), this.smscPropertiesManagement.getSriResponseLiveTime(), 30); // Step 4 Setup ArchiveSms this.archiveSms = ArchiveSms.getInstance(this.name); this.archiveSms.start(); ObjectName arhiveObjNname = new ObjectName(SmscManagement.JMX_DOMAIN + ":layer=" + JMX_LAYER_ARCHIVE_SMS + ",name=" + this.getName()); this.registerMBean(this.archiveSms, ArchiveSmsMBean.class, false, arhiveObjNname); // Step 5 Setup MAP Version Cache MBean this.mapVersionCache = MapVersionCache.getInstance(this.name); ObjectName mapVersionCacheObjNname = new ObjectName(SmscManagement.JMX_DOMAIN + ":layer=" + JMX_LAYER_MAP_VERSION_CACHE + ",name=" + this.getName()); this.registerMBean(this.mapVersionCache, MapVersionCacheMBean.class, false, mapVersionCacheObjNname); smscStatProvider = SmscStatProvider.getInstance(); ObjectName smscStatProviderObjNname = new ObjectName(SmscManagement.JMX_DOMAIN + ":layer=" + JMX_LAYER_SMSC_STATS + ",name=" + this.getName()); this.registerMBean(smscStatProvider, SmscStatProviderMBean.class, false, smscStatProviderObjNname); // Step 11 Setup SIP this.sipManagement = SipManagement.getInstance(this.name); this.sipManagement.setPersistDir(this.persistDir); this.sipManagement.start(); ObjectName sipObjNname = new ObjectName(SmscManagement.JMX_DOMAIN + ":layer=" + JMX_LAYER_SIP_MANAGEMENT + ",name=" + this.getName()); this.registerMBean(this.sipManagement, SipManagementMBean.class, false, sipObjNname); // Step 12 Setup MProcRules this.mProcManagement = MProcManagement.getInstance(this.name); this.mProcManagement.setPersistDir(this.persistDir); this.mProcManagement.setSmscManagement(this); this.mProcManagement.start(); ObjectName mProcObjNname = new ObjectName(SmscManagement.JMX_DOMAIN + ":layer=" + JMX_LAYER_MPROC_MANAGEMENT + ",name=" + this.getName()); this.registerMBean(this.mProcManagement, MProcManagementMBean.class, false, mProcObjNname); // Step 13 Set Routing Rule class if (this.smsRoutingRuleClass != null) { smsRoutingRule = (SmsRoutingRule) Class.forName(this.smsRoutingRuleClass).newInstance(); if (smsRoutingRule instanceof DatabaseSmsRoutingRule) { ObjectName dbSmsRoutingRuleObjName = new ObjectName(SmscManagement.JMX_DOMAIN + ":layer=" + JMX_LAYER_DATABASE_SMS_ROUTING_RULE + ",name=" + this.getName()); this.registerMBean((DatabaseSmsRoutingRule) smsRoutingRule, DatabaseSmsRoutingRuleMBean.class, true, dbSmsRoutingRuleObjName); } } else { smsRoutingRule = new DefaultSmsRoutingRule(); } smsRoutingRule.setEsmeManagement(this.smppManagement.getEsmeManagement()); smsRoutingRule.setSipManagement(sipManagement); smsRoutingRule.setSmscPropertiesManagement(smscPropertiesManagement); SmsRouteManagement.getInstance().setSmsRoutingRule(smsRoutingRule); this.persistFile.clear(); if (persistDir != null) { this.persistFile.append(persistDir).append(File.separator).append(this.name).append("_") .append(PERSIST_FILE_NAME); } else { persistFile.append(System.getProperty(SMSC_PERSIST_DIR_KEY, System.getProperty(USER_DIR_KEY))) .append(File.separator).append(this.name).append("_").append(PERSIST_FILE_NAME); } logger.info(String.format("SMSC configuration file path %s", persistFile.toString())); try { this.load(); } catch (FileNotFoundException e) { logger.warn(String.format("Failed to load the SS7 configuration file. \n%s", e.getMessage())); } logger.warn("Started SmscManagemet " + name); // Step 13 Start SmscDatabaseManagement this.smscDatabaseManagement = SmscDatabaseManagement.getInstance(this.name); this.smscDatabaseManagement.start(); ObjectName smscDatabaseManagementObjName = new ObjectName(SmscManagement.JMX_DOMAIN + ":layer=" + JMX_LAYER_SMSC_DATABASE_MANAGEMENT + ",name=" + this.getName()); this.registerMBean(this.smscDatabaseManagement, SmscDatabaseManagement.class, true, smscDatabaseManagementObjName); } public void stop() throws Exception { logger.info("Stopping SmscManagemet " + name); this.smscPropertiesManagement.stop(); ObjectName smscObjNname = new ObjectName(SmscManagement.JMX_DOMAIN + ":layer=" + JMX_LAYER_SMSC_PROPERTIES_MANAGEMENT + ",name=" + this.getName()); this.unregisterMbean(smscObjNname); this.homeRoutingManagement.stop(); ObjectName hrObjNname = new ObjectName(SmscManagement.JMX_DOMAIN + ":layer=" + JMX_LAYER_HOME_ROUTING_MANAGEMENT + ",name=" + this.getName()); this.unregisterMbean(hrObjNname); this.httpUsersManagement.stop(); ObjectName httpUsersObjNname = new ObjectName(SmscManagement.JMX_DOMAIN + ":layer=" + JMX_LAYER_HTTPUSER_MANAGEMENT + ",name=" + this.getName()); this.unregisterMbean(httpUsersObjNname); // DBOperations_C1.getInstance().stop(); DBOperations.getInstance().stop(); this.archiveSms.stop(); ObjectName arhiveObjNname = new ObjectName(SmscManagement.JMX_DOMAIN + ":layer=" + JMX_LAYER_ARCHIVE_SMS + ",name=" + this.getName()); this.unregisterMbean(arhiveObjNname); ObjectName mapVersionCacheObjNname = new ObjectName(SmscManagement.JMX_DOMAIN + ":layer=" + JMX_LAYER_MAP_VERSION_CACHE + ",name=" + this.getName()); this.unregisterMbean(mapVersionCacheObjNname); ObjectName smscStatProviderObjNname = new ObjectName(SmscManagement.JMX_DOMAIN + ":layer=" + JMX_LAYER_SMSC_STATS + ",name=" + this.getName()); this.unregisterMbean(smscStatProviderObjNname); if (smsRoutingRule instanceof DatabaseSmsRoutingRule) { ObjectName dbSmsRoutingRuleObjName = new ObjectName(SmscManagement.JMX_DOMAIN + ":layer=" + JMX_LAYER_DATABASE_SMS_ROUTING_RULE + ",name=" + this.getName()); this.unregisterMbean(dbSmsRoutingRuleObjName); } this.mProcManagement.stop(); ObjectName mProcObjNname = new ObjectName(SmscManagement.JMX_DOMAIN + ":layer=" + JMX_LAYER_MPROC_MANAGEMENT + ",name=" + this.getName()); this.unregisterMbean(mProcObjNname); this.sipManagement.stop(); ObjectName sipObjNname = new ObjectName(SmscManagement.JMX_DOMAIN + ":layer=" + JMX_LAYER_SIP_MANAGEMENT + ",name=" + this.getName()); this.unregisterMbean(sipObjNname); this.smscDatabaseManagement.stop(); ObjectName smscDatabaseManagementObjName = new ObjectName(SmscManagement.JMX_DOMAIN + ":layer=" + JMX_LAYER_SMSC_DATABASE_MANAGEMENT + ",name=" + this.getName()); this.unregisterMbean(smscDatabaseManagementObjName); SmsSetCache.stop(); this.isStarted = false; this.store(); logger.info("Stopped SmscManagemet " + name); } /** * Persist */ public void store() { } /** * Load and create LinkSets and Link from persisted file * * @throws Exception */ public void load() throws FileNotFoundException { } @Override public boolean isStarted() { return this.isStarted; } protected <T> void registerMBean(T implementation, Class<T> mbeanInterface, boolean isMXBean, ObjectName name) { try { if (this.mbeanServer != null) this.mbeanServer.registerMBean(implementation, name); } catch (InstanceAlreadyExistsException e) { logger.error(String.format("Error while registering MBean %s", mbeanInterface.getName()), e); } catch (MBeanRegistrationException e) { logger.error(String.format("Error while registering MBean %s", mbeanInterface.getName()), e); } catch (NotCompliantMBeanException e) { logger.error(String.format("Error while registering MBean %s", mbeanInterface.getName()), e); } } protected void unregisterMbean(ObjectName name) { try { if (this.mbeanServer != null) this.mbeanServer.unregisterMBean(name); } catch (MBeanRegistrationException e) { logger.error(String.format("Error while unregistering MBean %s", name), e); } catch (InstanceNotFoundException e) { logger.error(String.format("Error while unregistering MBean %s", name), e); } } }