Skip to content

Commit

Permalink
Fixing of #268 - Gracefull server shutdown
Browse files Browse the repository at this point in the history
  • Loading branch information
vetss committed Nov 23, 2017
1 parent 7c5c06b commit 4df153b
Show file tree
Hide file tree
Showing 8 changed files with 222 additions and 13 deletions.
7 changes: 7 additions & 0 deletions core/domain/pom.xml
Expand Up @@ -14,6 +14,13 @@
<description>SMSC Gateway Domain Object</description>

<dependencies>
<dependency>
<groupId>org.jboss.jbossas</groupId>
<artifactId>jboss-as-system-jmx</artifactId>
<version>${jboss.version}</version>
<scope>compile</scope>
</dependency>

<!-- javolution -->
<dependency>
<groupId>javolution</groupId>
Expand Down
Expand Up @@ -119,6 +119,8 @@ public interface SMSCOAMMessages {

public static final String DATA_CODING_BAD_VALUES = "Value of data coding schema is bad (possible values: 0-255)";

public static final String GSD_STARTED = "Gracefull ShutDown procedure has started";

/**
* Generic constants
*/
Expand Down
Expand Up @@ -1987,8 +1987,8 @@ public String ccMccmnsValueUpdate(String[] args) throws Exception {

public String gsd(String[] args) throws Exception {
SmscManagement smscManagement = SmscManagement.getInstance();
smscManagement.gsd();
return "gsd .....";
smscManagement.forceGracefullShutdown();
return SMSCOAMMessages.GSD_STARTED;
}

public String execute(String[] args) {
Expand Down
136 changes: 125 additions & 11 deletions core/domain/src/main/java/org/mobicents/smsc/domain/SmscManagement.java
Expand Up @@ -26,16 +26,23 @@
import java.io.FileNotFoundException;
import java.lang.management.ManagementFactory;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanInfo;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MBeanServerConnection;
import javax.management.MBeanServerFactory;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectInstance;
import javax.management.ObjectName;

import javolution.text.TextBuilder;
Expand All @@ -46,7 +53,6 @@
import org.mobicents.smsc.cassandra.DBOperations;
import org.mobicents.smsc.library.SmsSetCache;
import org.mobicents.smsc.mproc.MProcRuleFactory;
import org.restcomm.slee.resource.smpp.heartbeat.SmppLoadBalancerHeartBeatingServiceImplMBean;
import org.restcomm.smpp.SmppManagement;

/**
Expand Down Expand Up @@ -106,6 +112,12 @@ public class SmscManagement implements SmscManagementMBean {
private SmsRoutingRule smsRoutingRule = null;
private FastList<MProcRuleFactory> mprocFactories = new FastList<MProcRuleFactory>();

// private ScheduledExecutorService executor = Executors.newScheduledThreadPool(1, new DefaultThreadFactory(
// "SmscManagement-Thread"));
private ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);

private Future gsdTimerFuture;

private SmscManagement(String name) {
this.name = name;

Expand Down Expand Up @@ -216,21 +228,112 @@ public MProcRuleFactory getRuleFactory(String ruleFactoryName) {
return ruleClass;
}

public void gsd() {
public void forceGracefullShutdown() {
String[] MBEAN_NAMES_LIST = { "org.mobicents.resources.smpp-server-ra-ra:type=load-balancer-heartbeat-service,name=SmppServerRA" };

if (smscPropertiesManagement.isGracefullShuttingDown()) {
logger.info("Gracefull ShutDown procedure was already initiated");
return;
}

logger.info("Gracefull ShutDown procedure is initiating");

try {
logger.info("Gracefull ShutDown : initiated of stopping of RAs - load-balancer-heartbeat-service");
MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
String beanName = "org.mobicents.resources.smpp-server-ra-ra:type=load-balancer-heartbeat-service,name=SmppServerRA";
ObjectName objectName = new ObjectName(beanName);
logger.info("********* 00001 : " + objectName);

if (ManagementFactory.getPlatformMBeanServer().isRegistered(objectName)) {
ManagementFactory.getPlatformMBeanServer().invoke(objectName, "stop", new Object[] {}, new String[] {});
logger.info("********* 000020");
for (String beanName : MBEAN_NAMES_LIST) {
ObjectName objectName = new ObjectName(beanName);
if (mBeanServer.isRegistered(objectName)) {
mBeanServer.invoke(objectName, "stop", new Object[] {}, new String[] {});
logger.info("load-balancer-heartbeat-service stopped: " + beanName);
} else {
logger.info("load-balancer-heartbeat-service not found: " + beanName);
}
}
} catch (Exception ee) {
logger.error("********* : " + ee);
logger.error("Exception when stopping of RAs - load-balancer-heartbeat-service : " + ee.getMessage(), ee);
}

smscPropertiesManagement.setGracefullShutDownStart(new Date());
smscPropertiesManagement.setGracefullShuttingDown(true);

gracefullShutdownTimerRestart();
}

private void gracefullShutdownTimerRestart() {
GracefullShutdownTask t = new GracefullShutdownTask();
this.gsdTimerFuture = this.executor.schedule(t, 1000, TimeUnit.MILLISECONDS);
}

private void gracefullShutdownTimerStop() {
Future f = this.gsdTimerFuture;
if (f != null)
f.cancel(false);
}

private void gracefullShutdownTimerEvent() {
this.gsdTimerFuture = null;
if (!this.isStarted)
return;

logger.info("******* gracefullShutdownTimerEvent");

if (System.currentTimeMillis() - smscPropertiesManagement.getGracefullShutDownStart().getTime() > smscPropertiesManagement
.getMinGracefullShutDownTime() * 1000) {
if (System.currentTimeMillis() - smscPropertiesManagement.getGracefullShutDownStart().getTime() > smscPropertiesManagement
.getMaxGracefullShutDownTime() * 1000) {
logger.info("Shutdown after maxGracefullShutDownTime is expire");
startServerShutdown();
return;
}
if (SmsSetCache.getInstance().getProcessingSmsSetSize() == 0) {
logger.info("Shutdown after minGracefullShutDownTime is expire and no more open dialogs");
startServerShutdown();
return;
}
}

gracefullShutdownTimerRestart();
}

private void startServerShutdown() {
try {
MBeanServer mbeanServer = null;
for (Iterator i = MBeanServerFactory.findMBeanServer(null).iterator(); i.hasNext();) {
MBeanServer server = (MBeanServer) i.next();
if (server.getDefaultDomain().equals("jboss")) {
mbeanServer = server;
break;
}
}

if (mbeanServer != null) {
// jboss 5

logger.info("Gracefull ShutDown procedure: Found jboss 5 mbeanServer=" + mbeanServer);
ObjectName mbeanName = new ObjectName("jboss.system:type=Server");
MBeanInfo jbossServerMBean = mbeanServer.getMBeanInfo(mbeanName);
if (jbossServerMBean != null) {
Object[] args = {};
String[] sigs = {};
mbeanServer.invoke(mbeanName, "shutdown", args, sigs);
logger.info("jboss 5 Gracefull ShutDown procedure: started of server shutting down");
} else {
logger.warn("jboss 5 Gracefull ShutDown procedure: can not find server jboss.system:type=Server - can not make shutdown");
}
} else {
// wildfly
// TODO: implement it

MBeanServerConnection mbeanServerConnection = ManagementFactory.getPlatformMBeanServer();
ObjectName mbeanName = new ObjectName("jboss.as:management-root=server");
Object[] args = { false };
String[] sigs = { "java.lang.Boolean" };
mbeanServerConnection.invoke(mbeanName, "shutdown", args, sigs);
}
} catch (Exception e1){
logger.info("Gracefull ShutDown procedure Exception: " + e1.getMessage(), e1);
}
}

public void start() throws Exception {
Expand Down Expand Up @@ -375,12 +478,16 @@ public void start() throws Exception {
+ JMX_LAYER_SMSC_DATABASE_MANAGEMENT + ",name=" + this.getName());
this.registerMBean(this.smscDatabaseManagement, SmscDatabaseManagement.class, true, smscDatabaseManagementObjName);

this.isStarted = true;

logger.warn("Started SmscManagemet " + name);
}

public void stop() throws Exception {
logger.info("Stopping SmscManagemet " + name);

gracefullShutdownTimerStop();

this.smscPropertiesManagement.stop();
ObjectName smscObjNname = new ObjectName(SmscManagement.JMX_DOMAIN + ":layer="
+ JMX_LAYER_SMSC_PROPERTIES_MANAGEMENT + ",name=" + this.getName());
Expand Down Expand Up @@ -487,4 +594,11 @@ protected void unregisterMbean(ObjectName name) {
logger.error(String.format("Error while unregistering MBean %s", name), e);
}
}

public class GracefullShutdownTask implements Runnable {
@Override
public void run() {
gracefullShutdownTimerEvent();
}
}
}
Expand Up @@ -32,4 +32,6 @@ public interface SmscManagementMBean {

public boolean isStarted();

public void forceGracefullShutdown();

}
Expand Up @@ -27,6 +27,7 @@
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.Map;
import java.util.Map.Entry;

Expand Down Expand Up @@ -143,6 +144,8 @@ public class SmscPropertiesManagement implements SmscPropertiesManagementMBean {
private static final String MAX_MESSAGE_ID = "maxMessageId";

private static final String DELIVERY_PAUSE = "deliveryPause";
private static final String MIN_GRACEFULL_SHUTDOWN_TIME = "minGracefullShutDownTime";
private static final String MAX_GRACEFULL_SHUTDOWN_TIME = "maxGracefullShutDownTime";

private static final String CASSANDRA_USER = "cassandraUser";
private static final String CASSANDRA_PASS = "cassandraPass";
Expand Down Expand Up @@ -423,6 +426,17 @@ public class SmscPropertiesManagement implements SmscPropertiesManagementMBean {
// them into a database)
private boolean deliveryPause = false;

// we set it to true when a gracefull shutDown procedure has started
private boolean gracefullShuttingDown = false;
// time when a a gracefull shutDown was initiated
private Date gracefullShutDownStart = null;
// min time from starting of gracefull shutDown to a real shutDown
// before each the server will be up even when no dialogs in processing (in seconds)
private int minGracefullShutDownTime = 20;
// max time from starting of gracefull shutDown to a real shutDown
// after which the server will be brought even when dialogs in processing (in seconds)
private int maxGracefullShutDownTime = 90;

// this flag is not a storable option but a flag
// this flag is set to true when Schedule RA is inactivated or inactivating
// and is set to false when Schedule RA is activated
Expand Down Expand Up @@ -1343,6 +1357,48 @@ public void setDeliveryPause(boolean deliveryPause) {
this.store();
}

@Override
public boolean isGracefullShuttingDown() {
return gracefullShuttingDown;
}

@Override
public void setGracefullShuttingDown(boolean gracefullShuttingDown) {
this.gracefullShuttingDown = gracefullShuttingDown;
}

@Override
public Date getGracefullShutDownStart() {
return gracefullShutDownStart;
}

@Override
public void setGracefullShutDownStart(Date gracefullShutDownStart) {
this.gracefullShutDownStart = gracefullShutDownStart;
}

@Override
public int getMinGracefullShutDownTime() {
return minGracefullShutDownTime;
}

@Override
public void setMinGracefullShutDownTime(int minGracefullShutDownTime) {
this.minGracefullShutDownTime = minGracefullShutDownTime;
this.store();
}

@Override
public int getMaxGracefullShutDownTime() {
return maxGracefullShutDownTime;
}

@Override
public void setMaxGracefullShutDownTime(int maxGracefullShutDownTime) {
this.maxGracefullShutDownTime = maxGracefullShutDownTime;
this.store();
}

@Override
public boolean isSmscStopped() {
return smscStopped;
Expand Down Expand Up @@ -1632,6 +1688,8 @@ public void store() {
writer.write(this.fetchMaxRows, FETCH_MAX_ROWS, Integer.class);

writer.write(this.deliveryPause, DELIVERY_PAUSE, Boolean.class);
writer.write(this.minGracefullShutDownTime, MIN_GRACEFULL_SHUTDOWN_TIME, Integer.class);
writer.write(this.maxGracefullShutDownTime, MAX_GRACEFULL_SHUTDOWN_TIME, Integer.class);

writer.write(this.removingLiveTablesDays, REMOVING_LIVE_TABLES_DAYS, Integer.class);
writer.write(this.removingArchiveTablesDays, REMOVING_ARCHIVE_TABLES_DAYS, Integer.class);
Expand Down Expand Up @@ -1821,6 +1879,12 @@ public void load() throws FileNotFoundException {
if (valB != null) {
this.deliveryPause = valB.booleanValue();
}
val = reader.read(MIN_GRACEFULL_SHUTDOWN_TIME, Integer.class);
if (val != null)
this.minGracefullShutDownTime = val;
val = reader.read(MAX_GRACEFULL_SHUTDOWN_TIME, Integer.class);
if (val != null)
this.maxGracefullShutDownTime = val;

val = reader.read(REMOVING_LIVE_TABLES_DAYS, Integer.class);
if (val != null)
Expand Down
Expand Up @@ -22,6 +22,7 @@

package org.mobicents.smsc.domain;

import java.util.Date;
import java.util.Map;

import org.mobicents.protocols.ss7.indicator.GlobalTitleIndicator;
Expand Down Expand Up @@ -413,4 +414,20 @@ public interface SmscPropertiesManagementMBean {

public void setInCluster(boolean inCluster);

public boolean isGracefullShuttingDown();

public void setGracefullShuttingDown(boolean gracefullShuttingDown);

public Date getGracefullShutDownStart();

public void setGracefullShutDownStart(Date gracefullShutDownStart);

public int getMinGracefullShutDownTime();

public void setMinGracefullShutDownTime(int minGracefullShutDownTme);

public int getMaxGracefullShutDownTime();

public void setMaxGracefullShutDownTime(int maxGracefullShutDownTme);

}
Expand Up @@ -446,6 +446,9 @@ protected void onTimerTick() {
// checking if SMSC is paused by a used
if (smscPropertiesManagement.isDeliveryPause())
return;
// checking if SMSC is in a gracefull shutdown procedure
if (smscPropertiesManagement.isGracefullShuttingDown())
return;

try {
if (this.tracer.isFineEnabled())
Expand Down

0 comments on commit 4df153b

Please sign in to comment.