Skip to content
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 @@ -43,6 +43,7 @@

/**
* @author quintana.thomas@gmail.com (Thomas Quintana)
* @author maria.farooq@telestax.com (Maria Farooq)
*/
public abstract class GenericEndpoint extends UntypedActor {

Expand Down Expand Up @@ -150,6 +151,7 @@ protected void onJainMgcpResponseEvent(JainMgcpResponseEvent message, ActorRef s
broadcast(new EndpointStateChanged(EndpointState.DESTROYED));
} else {
logger.error("Could not destroy endpoint " + this.id.toString() + ". Return Code: " + returnCode.toString());
broadcast(new EndpointStateChanged(EndpointState.FAILED));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@

/**
* @author thomas.quintana@telestax.com (Thomas Quintana)
* @author maria.farooq@telestax.com (Maria Farooq)
*/
public abstract class AbstractMockMediaGateway extends UntypedActor {
// Call agent.
Expand Down Expand Up @@ -89,12 +90,13 @@ private ActorRef getBridgeEndpoint(final Object message) {
final CreateBridgeEndpoint request = (CreateBridgeEndpoint) message;
final ActorRef gateway = self();
final MediaSession session = request.session();
final String endpointName = request.endpointName();
return getContext().actorOf(new Props(new UntypedActorFactory() {
private static final long serialVersionUID = 1L;

@Override
public Actor create() throws Exception {
return new BridgeEndpoint(gateway, session, agent, domain, timeout,null);
return new BridgeEndpoint(gateway, session, agent, domain, timeout, endpointName);
}
}));
}
Expand All @@ -103,12 +105,13 @@ private ActorRef getConferenceEndpoint(final Object message) {
final CreateConferenceEndpoint request = (CreateConferenceEndpoint) message;
final ActorRef gateway = self();
final MediaSession session = request.session();
final String endpointName = request.endpointName();
return getContext().actorOf(new Props(new UntypedActorFactory() {
private static final long serialVersionUID = 1L;

@Override
public UntypedActor create() throws Exception {
return new ConferenceEndpoint(gateway, session, agent, domain, timeout,null);
return new ConferenceEndpoint(gateway, session, agent, domain, timeout, endpointName);
}
}));
}
Expand All @@ -117,12 +120,13 @@ private ActorRef getIvrEndpoint(final Object message) {
final CreateIvrEndpoint request = (CreateIvrEndpoint) message;
final ActorRef gateway = self();
final MediaSession session = request.session();
final String endpointName = request.endpointName();
return getContext().actorOf(new Props(new UntypedActorFactory() {
private static final long serialVersionUID = 1L;

@Override
public UntypedActor create() throws Exception {
return new IvrEndpoint(gateway, session, agent, domain, timeout,null);
return new IvrEndpoint(gateway, session, agent, domain, timeout, endpointName);
}
}));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
/*
* TeleStax, Open Source Cloud Communications
* Copyright 2011-2014, Telestax Inc and individual contributors
* by the @authors tag.
*
* This program is free software: you can redistribute it and/or modify
* under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation; either version 3 of
* the License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
package org.restcomm.connect.mgcp;

import static org.junit.Assert.assertTrue;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mobicents.protocols.mgcp.jain.pkg.AUMgcpEvent;
import org.mobicents.protocols.mgcp.jain.pkg.AUPackage;
import org.restcomm.connect.commons.patterns.Observe;
import org.restcomm.connect.commons.patterns.Observing;
import org.restcomm.connect.commons.patterns.StopObserving;

import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;
import akka.testkit.JavaTestKit;
import jain.protocol.ip.mgcp.JainMgcpEvent;
import jain.protocol.ip.mgcp.JainMgcpResponseEvent;
import jain.protocol.ip.mgcp.message.DeleteConnection;
import jain.protocol.ip.mgcp.message.DeleteConnectionResponse;
import jain.protocol.ip.mgcp.message.NotificationRequest;
import jain.protocol.ip.mgcp.message.NotificationRequestResponse;
import jain.protocol.ip.mgcp.message.Notify;
import jain.protocol.ip.mgcp.message.parms.EventName;
import jain.protocol.ip.mgcp.message.parms.ReturnCode;
import jain.protocol.ip.mgcp.pkg.MgcpEvent;

/**
* @author maria.farooq@telestax.com (Maria Farooq)
*/
public class EndpointTest {
private static ActorSystem system;

public EndpointTest() {
super();
}

@BeforeClass
public static void before() throws Exception {
system = ActorSystem.create();
}

@AfterClass
public static void after() throws Exception {
system.shutdown();
}


/**
* https://github.com/RestComm/Restcomm-Connect/issues/2310
*/
@Test
public void testDeleteEnpointSuccessScenario() {
new JavaTestKit(system) {
{
final ActorRef observer = getRef();
// Create a new mock media gateway to simulate the real thing.
final ActorRef gateway = system.actorOf(new Props(MockMediaGateway.class));
// Create a media session. This is just an identifier that groups
// a set of end points, connections, and lists in to one call.
gateway.tell(new CreateMediaSession(), observer);
final MediaGatewayResponse<MediaSession> mediaSessionResponse = expectMsgClass(MediaGatewayResponse.class);
assertTrue(mediaSessionResponse.succeeded());
final MediaSession session = mediaSessionResponse.get();
// Create an IVR end point.
gateway.tell(new CreateIvrEndpoint(session, "mobicents/ivr/1"), observer);
final MediaGatewayResponse<ActorRef> endpointResponse = expectMsgClass(MediaGatewayResponse.class);
assertTrue(endpointResponse.succeeded());
final ActorRef endpoint = endpointResponse.get();
// Start observing events from the IVR end point.
endpoint.tell(new Observe(observer), observer);
final Observing observingResponse = expectMsgClass(Observing.class);
assertTrue(observingResponse.succeeded());

// Destroy Endpoint
endpoint.tell(new DestroyEndpoint(), observer);

final EndpointStateChanged endpointStateChanged = expectMsgClass(EndpointStateChanged.class);
assertTrue(endpointStateChanged.getState().equals(EndpointState.DESTROYED));
// Stop observing events from the IVR end point.
endpoint.tell(new StopObserving(observer), observer);
}
};
}


/**
* https://github.com/RestComm/Restcomm-Connect/issues/2310
*/
@Test
public void testDeleteEnpointFailureScenario() {
new JavaTestKit(system) {
{
final ActorRef observer = getRef();
// Create a new mock media gateway to simulate the real thing.
final ActorRef gateway = system.actorOf(new Props(FailingMockMediaGateway.class));
// Create a media session. This is just an identifier that groups
// a set of end points, connections, and lists in to one call.
gateway.tell(new CreateMediaSession(), observer);
final MediaGatewayResponse<MediaSession> mediaSessionResponse = expectMsgClass(MediaGatewayResponse.class);
assertTrue(mediaSessionResponse.succeeded());
final MediaSession session = mediaSessionResponse.get();
// Create an IVR end point.
gateway.tell(new CreateIvrEndpoint(session, "mobicents/ivr/1"), observer);
final MediaGatewayResponse<ActorRef> endpointResponse = expectMsgClass(MediaGatewayResponse.class);
assertTrue(endpointResponse.succeeded());
final ActorRef endpoint = endpointResponse.get();
// Start observing events from the IVR end point.
endpoint.tell(new Observe(observer), observer);
final Observing observingResponse = expectMsgClass(Observing.class);
assertTrue(observingResponse.succeeded());

// Destroy Endpoint
endpoint.tell(new DestroyEndpoint(), observer);

final EndpointStateChanged endpointStateChanged = expectMsgClass(EndpointStateChanged.class);
assertTrue(endpointStateChanged.getState().equals(EndpointState.FAILED));
// Stop observing events from the IVR end point.
endpoint.tell(new StopObserving(observer), observer);
}
};
}

private static final class MockMediaGateway extends AbstractMockMediaGateway {
@SuppressWarnings("unused")
public MockMediaGateway() {
super();
}

@Override
protected void event(final Object message, final ActorRef sender) {
final ActorRef self = self();
if (message instanceof JainMgcpEvent) {
System.out.println(message.toString());
}
final Class<?> klass = message.getClass();
if (NotificationRequest.class.equals(klass)) {
// Send a successful response for this request.
final NotificationRequest request = (NotificationRequest) message;
final JainMgcpResponseEvent response = new NotificationRequestResponse(this,
ReturnCode.Transaction_Executed_Normally);
sender.tell(response, self);
System.out.println(response.toString());
// Send the notification.
final MgcpEvent event = AUMgcpEvent.auoc.withParm("rc=100 dc=1");
final EventName[] events = { new EventName(AUPackage.AU, event) };
final Notify notify = new Notify(this, request.getEndpointIdentifier(), request.getRequestIdentifier(), events);
notify.setTransactionHandle((int) transactionIdPool.get());
sender.tell(notify, self);
System.out.println(notify.toString());
}else if(DeleteConnection.class.equals(klass)){
final JainMgcpResponseEvent response = new DeleteConnectionResponse(this,
ReturnCode.Transaction_Executed_Normally);
sender.tell(response, self);
}else{
System.out.println("inside else");
}
}
}

private static final class FailingMockMediaGateway extends AbstractMockMediaGateway {
@SuppressWarnings("unused")
public FailingMockMediaGateway() {
super();
}

@Override
protected void event(final Object message, final ActorRef sender) {
final ActorRef self = self();
if (message instanceof JainMgcpEvent) {
System.out.println("event received: "+message.toString());
}
final Class<?> klass = message.getClass();
if (NotificationRequest.class.equals(klass)) {
// Send a successful response for this request.
final NotificationRequest request = (NotificationRequest) message;
final JainMgcpResponseEvent response = new NotificationRequestResponse(this,
ReturnCode.Transaction_Executed_Normally);
response.setTransactionHandle(request.getTransactionHandle());
sender.tell(response, self);
System.out.println(response.toString());
// Send the notification.
final MgcpEvent event = AUMgcpEvent.auoc.withParm("rc=300");
final EventName[] events = { new EventName(AUPackage.AU, event) };
final Notify notify = new Notify(this, request.getEndpointIdentifier(), request.getRequestIdentifier(), events);
notify.setTransactionHandle((int) transactionIdPool.get());
sender.tell(notify, self);
System.out.println(notify.toString());
} else if(DeleteConnection.class.equals(klass)){
final JainMgcpResponseEvent response = new DeleteConnectionResponse(this,
ReturnCode.Endpoint_Unknown);
sender.tell(response, self);
}else{
System.out.println("inside else");
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,9 @@ protected boolean is(State state) {

protected void onEndpointStateChanged(EndpointStateChanged message, ActorRef self, ActorRef sender) throws Exception {
if (is(deactivating)) {
if (sender.equals(this.ivr) && EndpointState.DESTROYED.equals(message.getState())) {
if (sender.equals(this.ivr) && (EndpointState.DESTROYED.equals(message.getState()) || EndpointState.FAILED.equals(message.getState()))) {
if(EndpointState.FAILED.equals(message.getState()))
logger.error("Could not destroy ivr endpoint on media server: " + this.ivrEndpointName + ". corresponding actor path is: " + this.ivr.path());
this.ivr.tell(new StopObserving(self), self);
this.fsm.transition(message, inactive);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@

/**
* @author Henrique Rosa (henrique.rosa@telestax.com)
* @author maria.farooq@telestax.com (Maria Farooq)
*
*/
public class MmsBridgeController extends MediaServerController {
Expand Down Expand Up @@ -347,7 +348,9 @@ private void onMediaGroupStateChanged(MediaGroupStateChanged message, ActorRef s

private void onEndpointStateChanged(EndpointStateChanged message, ActorRef self, ActorRef sender) throws Exception {
if (is(stopping)) {
if (sender.equals(this.endpoint) && EndpointState.DESTROYED.equals(message.getState())) {
if (sender.equals(this.endpoint) && (EndpointState.DESTROYED.equals(message.getState()) || EndpointState.FAILED.equals(message.getState()))) {
if(EndpointState.FAILED.equals(message.getState()))
logger.error("Could not destroy endpoint on media server. corresponding actor path is: " + this.endpoint.path());
this.endpoint.tell(new StopObserving(self), self);
context().stop(endpoint);
endpoint = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@

/**
* @author Henrique Rosa (henrique.rosa@telestax.com)
* @author maria.farooq@telestax.com (Maria Farooq)
*
*/
public class MmsCallController extends MediaServerController {
Expand Down Expand Up @@ -722,7 +723,9 @@ private void onCollect(Collect message, ActorRef self, ActorRef sender) {

private void onEndpointStateChanged(EndpointStateChanged message, ActorRef self, ActorRef sender) throws Exception {
if (is(stopping)) {
if (sender.equals(this.bridgeEndpoint) && EndpointState.DESTROYED.equals(message.getState())) {
if (sender.equals(this.bridgeEndpoint) && (EndpointState.DESTROYED.equals(message.getState()) || EndpointState.FAILED.equals(message.getState()))) {
if(EndpointState.FAILED.equals(message.getState()))
logger.error("Could not destroy endpoint on media server. corresponding actor path is: " + this.bridgeEndpoint.path());
this.bridgeEndpoint.tell(new StopObserving(self), self);
context().stop(bridgeEndpoint);
bridgeEndpoint = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,9 @@ private void onMediaGroupResponse(MediaGroupResponse<String> message, ActorRef s

private void onEndpointStateChanged(EndpointStateChanged message, ActorRef self, ActorRef sender) throws Exception {
if (is(stopping)) {
if (sender.equals(this.cnfEndpoint) && EndpointState.DESTROYED.equals(message.getState())) {
if (sender.equals(this.cnfEndpoint) && (EndpointState.DESTROYED.equals(message.getState()) || EndpointState.FAILED.equals(message.getState()))) {
if(EndpointState.FAILED.equals(message.getState()))
logger.error("Could not destroy endpoint on media server. corresponding actor path is: " + this.cnfEndpoint.path());
this.cnfEndpoint.tell(new StopObserving(self), self);
context().stop(cnfEndpoint);
cnfEndpoint = null;
Expand Down