Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#66 added configurable timeouts for CAP/MAP stacks #300

Merged
merged 1 commit into from
May 24, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,15 @@
*/
public interface CAPDialog extends Serializable {

// Invoke timers
int _Timer_CircuitSwitchedCallControl_Short = 6000; // 1 - 10 sec
int _Timer_CircuitSwitchedCallControl_Medium = 30000; // 1 - 60 sec
int _Timer_CircuitSwitchedCallControl_Long = 300000; // 1 s - 30 minutes
int _Timer_Sms_Short = 10000; // 1 - 20 sec
int _Timer_Gprs_Short = 10000; // 1 - 20 sec

int _Timer_Default = -1;

// Invoke timers
int getTimerCircuitSwitchedCallControlShort();
int getTimerCircuitSwitchedCallControlMedium();
int getTimerCircuitSwitchedCallControlLong();
int getTimerSmsShort();
int getTimerGprsShort();

/*
* Setting this property to true lead that all sent to TCAP messages of this Dialog will be marked as "ReturnMessageOnError"
* (SCCP will return the notification is the message has non been delivered to the peer)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,15 @@ public abstract class CAPDialogImpl implements CAPDialog {
boolean returnMessageOnError = false;
protected MessageType tcapMessageType;
protected DelayedAreaState delayedAreaState;
private CAPStackConfigurationManagement capStackConfigurationManagement;

protected CAPDialogImpl(CAPApplicationContext appCntx, Dialog tcapDialog, CAPProviderImpl capProviderImpl,
CAPServiceBase capService) {
this.appCntx = appCntx;
this.tcapDialog = tcapDialog;
this.capProviderImpl = capProviderImpl;
this.capService = capService;
this.capStackConfigurationManagement = CAPStackConfigurationManagement.getInstance();
}

public SccpAddress getLocalAddress() {
Expand Down Expand Up @@ -625,4 +627,29 @@ public long getIdleTaskTimeout() {
public void setIdleTaskTimeout(long idleTaskTimeoutMs) {
tcapDialog.setIdleTaskTimeout(idleTaskTimeoutMs);
}

@Override
public int getTimerCircuitSwitchedCallControlShort() {
return capStackConfigurationManagement.getTimerCircuitSwitchedCallControlShort();
}

@Override
public int getTimerCircuitSwitchedCallControlMedium() {
return capStackConfigurationManagement.getTimerCircuitSwitchedCallControlMedium();
}

@Override
public int getTimerCircuitSwitchedCallControlLong() {
return capStackConfigurationManagement.getTimerCircuitSwitchedCallControlLong();
}

@Override
public int getTimerSmsShort() {
return capStackConfigurationManagement.getTimerSmsShort();
}

@Override
public int getTimerGprsShort() {
return capStackConfigurationManagement.getTimerGprsShort();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
package org.restcomm.protocols.ss7.cap;

import javolution.text.TextBuilder;
import javolution.xml.XMLBinding;
import javolution.xml.XMLObjectReader;
import javolution.xml.XMLObjectWriter;
import javolution.xml.stream.XMLStreamException;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class CAPStackConfigurationManagement {
private static final String PERSIST_FILE_NAME = "management.xml";
private static final String CAP_MANAGEMENT_PERSIST_DIR_KEY = "capmanagement.persist.dir";
private static final String USER_DIR_KEY = "user.dir";
private static final String TAB_INDENT = "\t";
private static final String DEFAULT_CONFIG_FILE_NAME = "CapStack";

private static final String TIMER_CIRCUITSWITCHEDCALLCONTROL_SHORT = "timercircuitswitchedcallcontrolshort";
private static final String TIMER_CIRCUITSWITCHEDCALLCONTROL_MEDIUM = "timercircuitswitchedcallcontrolmedium";
private static final String TIMER_CIRCUITSWITCHEDCALLCONTROL_LONG = "timercircuitswitchedcallcontrollong";
private static final String TIMER_SMS_SHORT = "timersmsshort";
private static final String TIMER_GPRS_SHORT = "timergprsshort";

private static final XMLBinding binding = new XMLBinding();
private static CAPStackConfigurationManagement instance = new CAPStackConfigurationManagement();

private final TextBuilder persistFile = TextBuilder.newInstance();
private String configFileName = DEFAULT_CONFIG_FILE_NAME;
private String persistDir = null;

private int _Timer_CircuitSwitchedCallControl_Short = 6000; // 1 - 10 sec
private int _Timer_CircuitSwitchedCallControl_Medium = 30000; // 1 - 60 sec
private int _Timer_CircuitSwitchedCallControl_Long = 300000; // 1 s - 30 minutes
private int _Timer_Sms_Short = 10000; // 1 - 20 sec
private int _Timer_Gprs_Short = 10000; // 1 - 20 sec

private CAPStackConfigurationManagement() {
}

public static CAPStackConfigurationManagement getInstance() {
return instance;
}

public void setPersistDir(String persistDir) {
this.persistDir = persistDir;
this.setPersistFile();
}

private void setPersistFile() {
this.persistFile.clear();

if (persistDir != null) {
this.persistFile.append(persistDir).append(File.separator).append(this.configFileName).append("_").append(PERSIST_FILE_NAME);
} else {
persistFile.append(System.getProperty(CAP_MANAGEMENT_PERSIST_DIR_KEY, System.getProperty(USER_DIR_KEY))).append(File.separator).append(this.configFileName)
.append("_").append(PERSIST_FILE_NAME);
}
}

/**
* Persist
*/
public void store() {
// TODO : Should we keep reference to Objects rather than recreating
// everytime?
try {
XMLObjectWriter writer = XMLObjectWriter.newInstance(new FileOutputStream(persistFile.toString()));

writer.setBinding(binding);
writer.setIndentation(TAB_INDENT);

writer.write(this._Timer_CircuitSwitchedCallControl_Short, TIMER_CIRCUITSWITCHEDCALLCONTROL_SHORT, Integer.class);
writer.write(this._Timer_CircuitSwitchedCallControl_Medium, TIMER_CIRCUITSWITCHEDCALLCONTROL_MEDIUM, Integer.class);
writer.write(this._Timer_CircuitSwitchedCallControl_Long, TIMER_CIRCUITSWITCHEDCALLCONTROL_LONG, Integer.class);
writer.write(this._Timer_Sms_Short, TIMER_SMS_SHORT, Integer.class);
writer.write(this._Timer_Gprs_Short, TIMER_GPRS_SHORT, Integer.class);

writer.close();
} catch (Exception e) {
System.err.println(String.format("Error while persisting the CAP Resource state in file=%s", persistFile.toString()));
e.printStackTrace();
}
}

/**
* Load and create LinkSets and Link from persisted file
* <p>
* load() is called from CAPStackImpl
*/
public void load() {
try {
setPersistFile();
XMLObjectReader reader = XMLObjectReader.newInstance(new FileInputStream(persistFile.toString()));
reader.setBinding(binding);
load(reader);
} catch (XMLStreamException | FileNotFoundException e) {
System.err.println(String.format("Error while load the CAP Resource state from file=%s", persistFile.toString()));
e.printStackTrace();
}
}

private void load(XMLObjectReader reader) throws XMLStreamException {
Integer val = reader.read(TIMER_CIRCUITSWITCHEDCALLCONTROL_SHORT, Integer.class);
if (val != null)
this._Timer_CircuitSwitchedCallControl_Short = val;

val = reader.read(TIMER_CIRCUITSWITCHEDCALLCONTROL_MEDIUM, Integer.class);
if (val != null)
this._Timer_CircuitSwitchedCallControl_Medium = val;

val = reader.read(TIMER_CIRCUITSWITCHEDCALLCONTROL_LONG, Integer.class);
if (val != null)
this._Timer_CircuitSwitchedCallControl_Long = val;

val = reader.read(TIMER_SMS_SHORT, Integer.class);
if (val != null)
this._Timer_Sms_Short = val;

val = reader.read(TIMER_GPRS_SHORT, Integer.class);
if (val != null)
this._Timer_Gprs_Short = val;

reader.close();
}

public void setConfigFileName(String configFileName) {
this.configFileName = configFileName;
}

public int getTimerCircuitSwitchedCallControlShort() {
return _Timer_CircuitSwitchedCallControl_Short;
}

public int getTimerCircuitSwitchedCallControlMedium() {
return _Timer_CircuitSwitchedCallControl_Medium;
}

public int getTimerCircuitSwitchedCallControlLong() {
return _Timer_CircuitSwitchedCallControl_Long;
}

public int getTimerSmsShort() {
return _Timer_Sms_Short;
}

public int getTimerGprsShort() {
return _Timer_Gprs_Short;
}

public void set_Timer_CircuitSwitchedCallControl_Short(int _Timer_CircuitSwitchedCallControl_Short) {
this._Timer_CircuitSwitchedCallControl_Short = _Timer_CircuitSwitchedCallControl_Short;
this.store();
}

public void set_Timer_CircuitSwitchedCallControl_Medium(int _Timer_CircuitSwitchedCallControl_Medium) {
this._Timer_CircuitSwitchedCallControl_Medium = _Timer_CircuitSwitchedCallControl_Medium;
this.store();
}

public void set_Timer_CircuitSwitchedCallControl_Long(int _Timer_CircuitSwitchedCallControl_Long) {
this._Timer_CircuitSwitchedCallControl_Long = _Timer_CircuitSwitchedCallControl_Long;
this.store();
}

public void set_Timer_Sms_Short(int _Timer_Sms_Short) {
this._Timer_Sms_Short = _Timer_Sms_Short;
this.store();
}

public void set_Timer_Gprs_Short(int _Timer_Gprs_Short) {
this._Timer_Gprs_Short = _Timer_Gprs_Short;
this.store();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,30 @@ public class CAPStackImpl implements CAPStack {

private final String name;

private CAPStackConfigurationManagement capStackCfgManagement;

private String persistDir = null;

public CAPStackImpl(String name, SccpProvider sccpPprovider, int ssn) {
this.name = name;
this.tcapStack = new TCAPStackImpl(name, sccpPprovider, ssn);
TCAPProvider tcapProvider = tcapStack.getProvider();
capProvider = new CAPProviderImpl(name, tcapProvider);

this.state = State.CONFIGURED;

this.capStackCfgManagement = CAPStackConfigurationManagement.getInstance();
this.capStackCfgManagement.setConfigFileName(this.name);
}

public CAPStackImpl(String name, TCAPProvider tcapProvider) {
this.name = name;
capProvider = new CAPProviderImpl(name, tcapProvider);
this.tcapStack = tcapProvider.getStack();
this.state = State.CONFIGURED;

this.capStackCfgManagement = CAPStackConfigurationManagement.getInstance();
this.capStackCfgManagement.setConfigFileName(this.name);
}

@Override
Expand All @@ -72,6 +82,9 @@ public CAPProvider getCAPProvider() {

@Override
public void start() throws Exception {
this.capStackCfgManagement.setPersistDir(this.persistDir);
this.capStackCfgManagement.load();

if (state != State.CONFIGURED) {
throw new IllegalStateException("Stack has not been configured or is already running!");
}
Expand All @@ -96,13 +109,18 @@ public void stop() {
}

this.state = State.CONFIGURED;
this.capStackCfgManagement.store();
}

@Override
public TCAPStack getTCAPStack() {
return this.tcapStack;
}

public void setPersistDir(String persistDir) {
this.persistDir = persistDir;
}

private enum State {
IDLE, CONFIGURED, RUNNING;
}
Expand Down
Loading