Skip to content

Commit

Permalink
Merge branch 'master' into issue-2073
Browse files Browse the repository at this point in the history
* master:
  Minor patch for Restcomm testsuite failing tests
  Patch for CallManager to properly handle numbers that start with + This close #2158
  Patch to fix Outbound call never reach the completed state when inbound call sends BYE This close #2157
  Patch that fixes various Restcomm testsuite failing tests

Conflicts resolved:
	restcomm/restcomm.telephony/src/main/java/org/restcomm/connect/telephony/CallManager.java
#2106
  • Loading branch information
Maria Farooq committed May 17, 2017
2 parents 75c49e5 + 8861c67 commit 7cde747
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2514,7 +2514,10 @@ public void execute(final Object message) throws Exception {
} else if (outboundCall != null) {
outboundCall.tell(new Cancel(), source);
}
if (dialBranches == null) {
//Issue https://github.com/RestComm/Restcomm-Connect/issues/2157. If outbound call != null,
//then checking the DialBranch here will cause race condition that will prevent outbound call to move
//to completed state because checkDialBranch() method will ask for the next verb which could be the End.tag
if (dialBranches == null && outboundCall == null) {
checkDialBranch(message,sender,action);
}
dialChildren = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -404,8 +404,8 @@ public void onReceive(Object message) throws Exception {
final State state = fsm.state();

if(logger.isInfoEnabled()) {
logger.info("********** MmsCallController Current State: \"" + state.toString());
logger.info("********** MmsCallController Processing Message: \"" + klass.getName() + " sender : " + sender.getClass());
logger.info("********** MmsCallController "+ self.path()+" Current State: \"" + state.toString());
logger.info("********** MmsCallController "+ self.path()+" Processing Message: \"" + klass.getName() + " sender : " + sender.getClass());
}

if (Observe.class.equals(klass)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,7 @@ private void executeStatusCallback(final CallbackState state) {
if (statusCallback != null) {
if (statusCallbackEvent.contains(state.toString())) {
if (logger.isDebugEnabled()) {
String msg = String.format("About to execute Call StatusCallback to %s for state %s",statusCallback.toString(), state.text);
String msg = String.format("About to execute Call StatusCallback for state %s to StatusCallback %s. Call from %s to %s direction %s", state.text, statusCallback.toString(), from.toString(), to.toString(), direction);
logger.debug(msg);
}
if (statusCallbackMethod == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1072,17 +1072,18 @@ private IncomingPhoneNumber getMostOptimalIncomingPhoneNumber(final SipServletRe
// Format the destination to an E.164 phone number.
final PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance();
String formatedPhone = null;
//Don't format to E.164 if contains# or * as this is
//for a Regex or USSD call
if (phone.contains("*") || phone.contains("#")){
formatedPhone = phone;
}else{
if (!(phone.contains("*") || phone.contains("#"))) {
try {
formatedPhone = phoneNumberUtil.format(phoneNumberUtil.parse(phone, "US"), PhoneNumberFormat.E164);
} catch (NumberParseException e) {
logger.error("Exception when try to format : " + e);
}
}
if (formatedPhone == null) {
//Don't format to E.164 if phone contains # or * as this is
//for a Regex or USSD short number
formatedPhone = phone;
}
List<IncomingPhoneNumber> numbers = null;
IncomingPhoneNumber number = null;
// Try to find an application defined for the phone number.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ public synchronized void testDialClientAlice_BobDisconnects() throws Interrupted
null));
assertTrue(aliceCall.waitForAck(50 * 1000));

Thread.sleep(3000);
Thread.sleep(3500);

// hangup.
aliceCall.listenForDisconnect();
Expand All @@ -233,12 +233,13 @@ public synchronized void testDialClientAlice_BobDisconnects() throws Interrupted
assertTrue(aliceCall.waitForDisconnect(30 * 1000));
assertTrue(aliceCall.respondToDisconnect());

Thread.sleep(1000);
//Check recording
JsonArray recording = RestcommCallsTool.getInstance().getCallRecordings(deploymentUrl.toString(),adminAccountSid,adminAuthToken,callSid);
assertNotNull(recording);
assertEquals(1, recording.size());
double duration = recording.get(0).getAsJsonObject().get("duration").getAsDouble();
assertTrue(duration==3.0);
assertEquals(3.0 , duration, 0);
assertTrue(recording.get(0).getAsJsonObject().get("file_uri").getAsString().startsWith("http://localhost:8080/restcomm/2012-04-24/Accounts/ACae6e420f425248d6a26948c17a9e2acf/Recordings/"));

assertTrue(recording.get(0).getAsJsonObject().get("s3_uri").getAsString().startsWith("http://127.0.0.1:8090/s3"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,12 +231,13 @@ public synchronized void testDialClientAlice_BobDisconnects() throws Interrupted
assertTrue(aliceCall.waitForDisconnect(30 * 1000));
assertTrue(aliceCall.respondToDisconnect());

Thread.sleep(1000);
//Check recording
JsonArray recording = RestcommCallsTool.getInstance().getCallRecordings(deploymentUrl.toString(),adminAccountSid,adminAuthToken,callSid);
assertNotNull(recording);
assertEquals(1, recording.size());
double duration = recording.get(0).getAsJsonObject().get("duration").getAsDouble();
assertTrue(duration==3.0);
assertEquals(3.0, duration, 0);
assertTrue(recording.get(0).getAsJsonObject().get("file_uri").getAsString().startsWith("http://localhost:8080/restcomm/2012-04-24/Accounts/ACae6e420f425248d6a26948c17a9e2acf/Recordings/"));

//Since we are in secure mode the s3_uri shouldn't be here
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ public void testDialStatusCallbackMethodGET() throws ParseException, Interrupted
assertTrue(liveCallsArraySize==0);
}

private String dialStatusCallbackGet = "<Response><Dial><Client statusCallback=\"http://127.0.0.1:8090/status\" statusCallbackMethod=\"GET\">alice</Client></Dial></Response>";
@Test
public void testDialStatusCallbackBobDisconnects() throws ParseException, InterruptedException {

Expand All @@ -394,6 +395,10 @@ public void testDialStatusCallbackBobDisconnects() throws ParseException, Interr
.willReturn(aResponse()
.withStatus(200)));

stubFor(get(urlPathMatching("/status.*"))
.willReturn(aResponse()
.withStatus(200)));

// Register Alice
SipURI uri = aliceSipStack.getAddressFactory().createSipURI(null, "127.0.0.1:5080");
assertTrue(alicePhone.register(uri, "alice", "1234", aliceContact, 3600, 3600));
Expand Down Expand Up @@ -450,6 +455,7 @@ public void testDialStatusCallbackBobDisconnects() throws ParseException, Interr

logger.info("About to check the StatusCallback Requests");
List<LoggedRequest> requests = findAll(postRequestedFor(urlPathMatching("/status.*")));
// List<LoggedRequest> requests = findAll(getRequestedFor(urlPathMatching("/status.*")));
assertEquals(4, requests.size());
String requestBody = requests.get(0).getBodyAsString();
assertTrue(requestBody.contains("SequenceNumber=0"));
Expand Down Expand Up @@ -996,7 +1002,7 @@ public synchronized void testDialForkNoAnswerButHenriqueStatusCallbackOnAll() th
private String rcmlToReturn = "<Response><Dial timeout=\"50\"><Client statusCallback=\"http://127.0.0.1:8090/status\" statusCallbackMethod=\"get\">alice</Client> </Dial></Response>";
//Non regression test for https://telestax.atlassian.net/browse/RESTCOMM-585
@Test //TODO Fails when the whole test class runs but Passes when run individually
public synchronized void testDialForkNoAnswerExecuteRCML_ReturnedFromActionURLWithStatusCallbacks() throws InterruptedException, ParseException, MalformedURLException {
public synchronized void testDialForkNoAnswerExecuteRCML_ReturnedFromActionURLWithStatusCallbacks_BobDisconnects() throws InterruptedException, ParseException, MalformedURLException {

stubFor(get(urlPathEqualTo("/1111"))
.willReturn(aResponse()
Expand Down Expand Up @@ -1088,6 +1094,7 @@ public synchronized void testDialForkNoAnswerExecuteRCML_ReturnedFromActionURLWi
// assertTrue(liveCalls == 2);
// assertTrue(liveCallsArraySize == 2);

Thread.sleep(1000);

//Now Fotini should receive a call
assertTrue(aliceCall.waitForIncomingCall(30 * 1000));
Expand All @@ -1096,18 +1103,162 @@ public synchronized void testDialForkNoAnswerExecuteRCML_ReturnedFromActionURLWi
String receivedBody = new String(aliceCall.getLastReceivedRequest().getRawContent());
assertTrue(aliceCall.sendIncomingCallResponse(Response.OK, "OK-Alice", 3600, receivedBody, "application", "sdp", null, null));
assertTrue(aliceCall.waitForAck(5000));
aliceCall.listenForDisconnect();

assertTrue(MonitoringServiceTool.getInstance().getStatistics(deploymentUrl.toString(), adminAccountSid, adminAuthToken) == 2);
assertTrue(MonitoringServiceTool.getInstance().getLiveCallsArraySize(deploymentUrl.toString(), adminAccountSid, adminAuthToken) == 2);

Thread.sleep(2000);
Thread.sleep(5000);

// hangup.

aliceCall.listenForDisconnect();

assertTrue(bobCall.disconnect());

assertTrue(aliceCall.waitForDisconnect(50 * 1000));
assertTrue(aliceCall.respondToDisconnect());

Thread.sleep(10000);

logger.info("About to check the Requests");
List<LoggedRequest> requests = findAll(getRequestedFor(urlPathMatching("/1111")));
assertTrue(requests.size() == 1);
// requests.get(0).g;
String requestBody = new URL(requests.get(0).getAbsoluteUrl()).getQuery();// .getQuery();// .getBodyAsString();
List<String> params = Arrays.asList(requestBody.split("&"));
String callSid = "";
for (String param : params) {
if (param.contains("CallSid")) {
callSid = param.split("=")[1];
}
}
JsonObject cdr = RestcommCallsTool.getInstance().getCall(deploymentUrl.toString(), adminAccountSid, adminAuthToken, callSid);
JsonObject jsonObj = cdr.getAsJsonObject();
assertTrue(jsonObj.get("status").getAsString().equalsIgnoreCase("completed"));
assertTrue(MonitoringServiceTool.getInstance().getStatistics(deploymentUrl.toString(), adminAccountSid, adminAuthToken) == 0);
assertTrue(MonitoringServiceTool.getInstance().getLiveCallsArraySize(deploymentUrl.toString(), adminAccountSid, adminAuthToken) == 0);

logger.info("About to check the StatusCallback Requests");
requests = findAll(getRequestedFor(urlPathMatching("/status.*")));
assertEquals(13, requests.size());
}

//Non regression test for https://telestax.atlassian.net/browse/RESTCOMM-585
@Test //TODO Fails when the whole test class runs but Passes when run individually
public synchronized void testDialForkNoAnswerExecuteRCML_ReturnedFromActionURLWithStatusCallbacks_AliceDisconnects() throws InterruptedException, ParseException, MalformedURLException {

stubFor(get(urlPathEqualTo("/1111"))
.willReturn(aResponse()
.withStatus(200)
.withHeader("Content-Type", "text/xml")
.withBody(dialForkWithActionUrl)));

stubFor(post(urlEqualTo("/action"))
.willReturn(aResponse()
.withStatus(200)
.withHeader("Content-Type", "text/xml")
.withBody(rcmlToReturn)));

stubFor(get(urlPathMatching("/status.*"))
.willReturn(aResponse()
.withStatus(200)));

// Register Alice
SipURI uri = aliceSipStack.getAddressFactory().createSipURI(null, "127.0.0.1:5080");
assertTrue(alicePhone.register(uri, "alice", "1234", aliceContact, 3600, 3600));

// Prepare Alice to receive call
final SipCall aliceCall = alicePhone.createSipCall();
aliceCall.listenForIncomingCall();

// Prepare George phone to receive call
final SipCall georgeCall = georgePhone.createSipCall();
georgeCall.listenForIncomingCall();

// Prepare Henrique phone to receive call
// henriquePhone.setLoopback(true);
final SipCall henriqueCall = henriquePhone.createSipCall();
henriqueCall.listenForIncomingCall();


// Initiate a call using Bob
final SipCall bobCall = bobPhone.createSipCall();

bobCall.initiateOutgoingCall(bobContact, "sip:1111@127.0.0.1:5080", null, body, "application", "sdp", null, null);
assertLastOperationSuccess(bobCall);

assertTrue(bobCall.waitOutgoingCallResponse(5 * 1000));

final int response = bobCall.getLastReceivedResponse().getStatusCode();
assertTrue(response == Response.TRYING || response == Response.RINGING);
if (response == Response.TRYING) {
assertTrue(bobCall.waitOutgoingCallResponse(5 * 1000));
assertEquals(Response.RINGING, bobCall.getLastReceivedResponse().getStatusCode());
}

assertTrue(bobCall.waitOutgoingCallResponse(5 * 1000));
assertEquals(Response.OK, bobCall.getLastReceivedResponse().getStatusCode());
bobCall.sendInviteOkAck();
assertTrue(!(bobCall.getLastReceivedResponse().getStatusCode() >= 400));

assertTrue(georgeCall.waitForIncomingCall(30 * 1000));
assertTrue(georgeCall.sendIncomingCallResponse(100, "Trying-George", 600));
assertTrue(georgeCall.sendIncomingCallResponse(180, "Ringing-George", 600));
assertTrue(aliceCall.waitForIncomingCall(30 * 1000));
assertTrue(aliceCall.sendIncomingCallResponse(100, "Trying-Alice", 600));
assertTrue(aliceCall.sendIncomingCallResponse(180, "Ringing-Alice", 600));
assertTrue(henriqueCall.waitForIncomingCall(30 * 1000));
assertTrue(henriqueCall.sendIncomingCallResponse(100, "Trying-Henrique", 600));
assertTrue(henriqueCall.sendIncomingCallResponse(Response.RINGING, "Ringing-Henrique", 3600));

//No one will answer the call and RCML will move to the next verb to call Fotini

assertTrue(georgeCall.listenForCancel());
assertTrue(aliceCall.listenForCancel());
assertTrue(henriqueCall.listenForCancel());

Thread.sleep(1000);

SipTransaction georgeCancelTransaction = georgeCall.waitForCancel(50 * 1000);
SipTransaction henriqueCancelTransaction = henriqueCall.waitForCancel(50 * 1000);
SipTransaction aliceCancelTransaction = aliceCall.waitForCancel(50 * 1000);
assertNotNull(georgeCancelTransaction);
assertNotNull(aliceCancelTransaction);
assertNotNull(henriqueCancelTransaction);
georgeCall.respondToCancel(georgeCancelTransaction, 200, "OK - George", 600);
aliceCall.respondToCancel(aliceCancelTransaction, 200, "OK - Alice", 600);
henriqueCall.respondToCancel(henriqueCancelTransaction, 200, "OK - Henrique", 600);

// int liveCalls = MonitoringServiceTool.getInstance().getStatistics(deploymentUrl.toString(), adminAccountSid, adminAuthToken);
// int liveCallsArraySize = MonitoringServiceTool.getInstance().getLiveCallsArraySize(deploymentUrl.toString(), adminAccountSid, adminAuthToken);
// //There will be the initial call from Bob and the new call to Fotini
// logger.info("&&&& LiveCalls: "+liveCalls);
// logger.info("&&&& LiveCallsArraySize: "+liveCallsArraySize);
// assertTrue(liveCalls == 2);
// assertTrue(liveCallsArraySize == 2);


//Now Fotini should receive a call
assertTrue(aliceCall.waitForIncomingCall(30 * 1000));
assertTrue(aliceCall.sendIncomingCallResponse(100, "Trying-Alice", 600));
assertTrue(aliceCall.sendIncomingCallResponse(180, "Ringing-Alice", 600));
String receivedBody = new String(aliceCall.getLastReceivedRequest().getRawContent());
assertTrue(aliceCall.sendIncomingCallResponse(Response.OK, "OK-Alice", 3600, receivedBody, "application", "sdp", null, null));
assertTrue(aliceCall.waitForAck(5000));

bobCall.listenForDisconnect();

assertTrue(MonitoringServiceTool.getInstance().getStatistics(deploymentUrl.toString(), adminAccountSid, adminAuthToken) == 2);
assertTrue(MonitoringServiceTool.getInstance().getLiveCallsArraySize(deploymentUrl.toString(), adminAccountSid, adminAuthToken) == 2);

Thread.sleep(2000);

// hangup.

assertTrue(aliceCall.disconnect());

assertTrue(bobCall.waitForDisconnect(50 * 1000));
assertTrue(bobCall.respondToDisconnect());

Thread.sleep(10000);

Expand Down

0 comments on commit 7cde747

Please sign in to comment.