Skip to content

Commit abcc72b

Browse files
author
maria-farooq
authored
Merge pull request #2314 from RestComm/issue-2310
Issue 2310
2 parents 9c5eddc + 05e3f69 commit abcc72b

7 files changed

Lines changed: 241 additions & 7 deletions

File tree

restcomm/restcomm.mgcp/src/main/java/org/restcomm/connect/mgcp/GenericEndpoint.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343

4444
/**
4545
* @author quintana.thomas@gmail.com (Thomas Quintana)
46+
* @author maria.farooq@telestax.com (Maria Farooq)
4647
*/
4748
public abstract class GenericEndpoint extends UntypedActor {
4849

@@ -150,6 +151,7 @@ protected void onJainMgcpResponseEvent(JainMgcpResponseEvent message, ActorRef s
150151
broadcast(new EndpointStateChanged(EndpointState.DESTROYED));
151152
} else {
152153
logger.error("Could not destroy endpoint " + this.id.toString() + ". Return Code: " + returnCode.toString());
154+
broadcast(new EndpointStateChanged(EndpointState.FAILED));
153155
}
154156
}
155157
}

restcomm/restcomm.mgcp/src/test/java/org/restcomm/connect/mgcp/AbstractMockMediaGateway.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434

3535
/**
3636
* @author thomas.quintana@telestax.com (Thomas Quintana)
37+
* @author maria.farooq@telestax.com (Maria Farooq)
3738
*/
3839
public abstract class AbstractMockMediaGateway extends UntypedActor {
3940
// Call agent.
@@ -89,12 +90,13 @@ private ActorRef getBridgeEndpoint(final Object message) {
8990
final CreateBridgeEndpoint request = (CreateBridgeEndpoint) message;
9091
final ActorRef gateway = self();
9192
final MediaSession session = request.session();
93+
final String endpointName = request.endpointName();
9294
return getContext().actorOf(new Props(new UntypedActorFactory() {
9395
private static final long serialVersionUID = 1L;
9496

9597
@Override
9698
public Actor create() throws Exception {
97-
return new BridgeEndpoint(gateway, session, agent, domain, timeout,null);
99+
return new BridgeEndpoint(gateway, session, agent, domain, timeout, endpointName);
98100
}
99101
}));
100102
}
@@ -103,12 +105,13 @@ private ActorRef getConferenceEndpoint(final Object message) {
103105
final CreateConferenceEndpoint request = (CreateConferenceEndpoint) message;
104106
final ActorRef gateway = self();
105107
final MediaSession session = request.session();
108+
final String endpointName = request.endpointName();
106109
return getContext().actorOf(new Props(new UntypedActorFactory() {
107110
private static final long serialVersionUID = 1L;
108111

109112
@Override
110113
public UntypedActor create() throws Exception {
111-
return new ConferenceEndpoint(gateway, session, agent, domain, timeout,null);
114+
return new ConferenceEndpoint(gateway, session, agent, domain, timeout, endpointName);
112115
}
113116
}));
114117
}
@@ -117,12 +120,13 @@ private ActorRef getIvrEndpoint(final Object message) {
117120
final CreateIvrEndpoint request = (CreateIvrEndpoint) message;
118121
final ActorRef gateway = self();
119122
final MediaSession session = request.session();
123+
final String endpointName = request.endpointName();
120124
return getContext().actorOf(new Props(new UntypedActorFactory() {
121125
private static final long serialVersionUID = 1L;
122126

123127
@Override
124128
public UntypedActor create() throws Exception {
125-
return new IvrEndpoint(gateway, session, agent, domain, timeout,null);
129+
return new IvrEndpoint(gateway, session, agent, domain, timeout, endpointName);
126130
}
127131
}));
128132
}
Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
/*
2+
* TeleStax, Open Source Cloud Communications
3+
* Copyright 2011-2014, Telestax Inc and individual contributors
4+
* by the @authors tag.
5+
*
6+
* This program is free software: you can redistribute it and/or modify
7+
* under the terms of the GNU Affero General Public License as
8+
* published by the Free Software Foundation; either version 3 of
9+
* the License, or (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU Affero General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Affero General Public License
17+
* along with this program. If not, see <http://www.gnu.org/licenses/>
18+
*
19+
*/
20+
package org.restcomm.connect.mgcp;
21+
22+
import static org.junit.Assert.assertTrue;
23+
24+
import org.junit.AfterClass;
25+
import org.junit.BeforeClass;
26+
import org.junit.Test;
27+
import org.mobicents.protocols.mgcp.jain.pkg.AUMgcpEvent;
28+
import org.mobicents.protocols.mgcp.jain.pkg.AUPackage;
29+
import org.restcomm.connect.commons.patterns.Observe;
30+
import org.restcomm.connect.commons.patterns.Observing;
31+
import org.restcomm.connect.commons.patterns.StopObserving;
32+
33+
import akka.actor.ActorRef;
34+
import akka.actor.ActorSystem;
35+
import akka.actor.Props;
36+
import akka.testkit.JavaTestKit;
37+
import jain.protocol.ip.mgcp.JainMgcpEvent;
38+
import jain.protocol.ip.mgcp.JainMgcpResponseEvent;
39+
import jain.protocol.ip.mgcp.message.DeleteConnection;
40+
import jain.protocol.ip.mgcp.message.DeleteConnectionResponse;
41+
import jain.protocol.ip.mgcp.message.NotificationRequest;
42+
import jain.protocol.ip.mgcp.message.NotificationRequestResponse;
43+
import jain.protocol.ip.mgcp.message.Notify;
44+
import jain.protocol.ip.mgcp.message.parms.EventName;
45+
import jain.protocol.ip.mgcp.message.parms.ReturnCode;
46+
import jain.protocol.ip.mgcp.pkg.MgcpEvent;
47+
48+
/**
49+
* @author maria.farooq@telestax.com (Maria Farooq)
50+
*/
51+
public class EndpointTest {
52+
private static ActorSystem system;
53+
54+
public EndpointTest() {
55+
super();
56+
}
57+
58+
@BeforeClass
59+
public static void before() throws Exception {
60+
system = ActorSystem.create();
61+
}
62+
63+
@AfterClass
64+
public static void after() throws Exception {
65+
system.shutdown();
66+
}
67+
68+
69+
/**
70+
* https://github.com/RestComm/Restcomm-Connect/issues/2310
71+
*/
72+
@Test
73+
public void testDeleteEnpointSuccessScenario() {
74+
new JavaTestKit(system) {
75+
{
76+
final ActorRef observer = getRef();
77+
// Create a new mock media gateway to simulate the real thing.
78+
final ActorRef gateway = system.actorOf(new Props(MockMediaGateway.class));
79+
// Create a media session. This is just an identifier that groups
80+
// a set of end points, connections, and lists in to one call.
81+
gateway.tell(new CreateMediaSession(), observer);
82+
final MediaGatewayResponse<MediaSession> mediaSessionResponse = expectMsgClass(MediaGatewayResponse.class);
83+
assertTrue(mediaSessionResponse.succeeded());
84+
final MediaSession session = mediaSessionResponse.get();
85+
// Create an IVR end point.
86+
gateway.tell(new CreateIvrEndpoint(session, "mobicents/ivr/1"), observer);
87+
final MediaGatewayResponse<ActorRef> endpointResponse = expectMsgClass(MediaGatewayResponse.class);
88+
assertTrue(endpointResponse.succeeded());
89+
final ActorRef endpoint = endpointResponse.get();
90+
// Start observing events from the IVR end point.
91+
endpoint.tell(new Observe(observer), observer);
92+
final Observing observingResponse = expectMsgClass(Observing.class);
93+
assertTrue(observingResponse.succeeded());
94+
95+
// Destroy Endpoint
96+
endpoint.tell(new DestroyEndpoint(), observer);
97+
98+
final EndpointStateChanged endpointStateChanged = expectMsgClass(EndpointStateChanged.class);
99+
assertTrue(endpointStateChanged.getState().equals(EndpointState.DESTROYED));
100+
// Stop observing events from the IVR end point.
101+
endpoint.tell(new StopObserving(observer), observer);
102+
}
103+
};
104+
}
105+
106+
107+
/**
108+
* https://github.com/RestComm/Restcomm-Connect/issues/2310
109+
*/
110+
@Test
111+
public void testDeleteEnpointFailureScenario() {
112+
new JavaTestKit(system) {
113+
{
114+
final ActorRef observer = getRef();
115+
// Create a new mock media gateway to simulate the real thing.
116+
final ActorRef gateway = system.actorOf(new Props(FailingMockMediaGateway.class));
117+
// Create a media session. This is just an identifier that groups
118+
// a set of end points, connections, and lists in to one call.
119+
gateway.tell(new CreateMediaSession(), observer);
120+
final MediaGatewayResponse<MediaSession> mediaSessionResponse = expectMsgClass(MediaGatewayResponse.class);
121+
assertTrue(mediaSessionResponse.succeeded());
122+
final MediaSession session = mediaSessionResponse.get();
123+
// Create an IVR end point.
124+
gateway.tell(new CreateIvrEndpoint(session, "mobicents/ivr/1"), observer);
125+
final MediaGatewayResponse<ActorRef> endpointResponse = expectMsgClass(MediaGatewayResponse.class);
126+
assertTrue(endpointResponse.succeeded());
127+
final ActorRef endpoint = endpointResponse.get();
128+
// Start observing events from the IVR end point.
129+
endpoint.tell(new Observe(observer), observer);
130+
final Observing observingResponse = expectMsgClass(Observing.class);
131+
assertTrue(observingResponse.succeeded());
132+
133+
// Destroy Endpoint
134+
endpoint.tell(new DestroyEndpoint(), observer);
135+
136+
final EndpointStateChanged endpointStateChanged = expectMsgClass(EndpointStateChanged.class);
137+
assertTrue(endpointStateChanged.getState().equals(EndpointState.FAILED));
138+
// Stop observing events from the IVR end point.
139+
endpoint.tell(new StopObserving(observer), observer);
140+
}
141+
};
142+
}
143+
144+
private static final class MockMediaGateway extends AbstractMockMediaGateway {
145+
@SuppressWarnings("unused")
146+
public MockMediaGateway() {
147+
super();
148+
}
149+
150+
@Override
151+
protected void event(final Object message, final ActorRef sender) {
152+
final ActorRef self = self();
153+
if (message instanceof JainMgcpEvent) {
154+
System.out.println(message.toString());
155+
}
156+
final Class<?> klass = message.getClass();
157+
if (NotificationRequest.class.equals(klass)) {
158+
// Send a successful response for this request.
159+
final NotificationRequest request = (NotificationRequest) message;
160+
final JainMgcpResponseEvent response = new NotificationRequestResponse(this,
161+
ReturnCode.Transaction_Executed_Normally);
162+
sender.tell(response, self);
163+
System.out.println(response.toString());
164+
// Send the notification.
165+
final MgcpEvent event = AUMgcpEvent.auoc.withParm("rc=100 dc=1");
166+
final EventName[] events = { new EventName(AUPackage.AU, event) };
167+
final Notify notify = new Notify(this, request.getEndpointIdentifier(), request.getRequestIdentifier(), events);
168+
notify.setTransactionHandle((int) transactionIdPool.get());
169+
sender.tell(notify, self);
170+
System.out.println(notify.toString());
171+
}else if(DeleteConnection.class.equals(klass)){
172+
final JainMgcpResponseEvent response = new DeleteConnectionResponse(this,
173+
ReturnCode.Transaction_Executed_Normally);
174+
sender.tell(response, self);
175+
}else{
176+
System.out.println("inside else");
177+
}
178+
}
179+
}
180+
181+
private static final class FailingMockMediaGateway extends AbstractMockMediaGateway {
182+
@SuppressWarnings("unused")
183+
public FailingMockMediaGateway() {
184+
super();
185+
}
186+
187+
@Override
188+
protected void event(final Object message, final ActorRef sender) {
189+
final ActorRef self = self();
190+
if (message instanceof JainMgcpEvent) {
191+
System.out.println("event received: "+message.toString());
192+
}
193+
final Class<?> klass = message.getClass();
194+
if (NotificationRequest.class.equals(klass)) {
195+
// Send a successful response for this request.
196+
final NotificationRequest request = (NotificationRequest) message;
197+
final JainMgcpResponseEvent response = new NotificationRequestResponse(this,
198+
ReturnCode.Transaction_Executed_Normally);
199+
response.setTransactionHandle(request.getTransactionHandle());
200+
sender.tell(response, self);
201+
System.out.println(response.toString());
202+
// Send the notification.
203+
final MgcpEvent event = AUMgcpEvent.auoc.withParm("rc=300");
204+
final EventName[] events = { new EventName(AUPackage.AU, event) };
205+
final Notify notify = new Notify(this, request.getEndpointIdentifier(), request.getRequestIdentifier(), events);
206+
notify.setTransactionHandle((int) transactionIdPool.get());
207+
sender.tell(notify, self);
208+
System.out.println(notify.toString());
209+
} else if(DeleteConnection.class.equals(klass)){
210+
final JainMgcpResponseEvent response = new DeleteConnectionResponse(this,
211+
ReturnCode.Endpoint_Unknown);
212+
sender.tell(response, self);
213+
}else{
214+
System.out.println("inside else");
215+
}
216+
}
217+
}
218+
}

restcomm/restcomm.mscontrol.mms/src/main/java/org/restcomm/connect/mscontrol/mms/MgcpMediaGroup.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,9 @@ protected boolean is(State state) {
358358

359359
protected void onEndpointStateChanged(EndpointStateChanged message, ActorRef self, ActorRef sender) throws Exception {
360360
if (is(deactivating)) {
361-
if (sender.equals(this.ivr) && EndpointState.DESTROYED.equals(message.getState())) {
361+
if (sender.equals(this.ivr) && (EndpointState.DESTROYED.equals(message.getState()) || EndpointState.FAILED.equals(message.getState()))) {
362+
if(EndpointState.FAILED.equals(message.getState()))
363+
logger.error("Could not destroy ivr endpoint on media server: " + this.ivrEndpointName + ". corresponding actor path is: " + this.ivr.path());
362364
this.ivr.tell(new StopObserving(self), self);
363365
this.fsm.transition(message, inactive);
364366
}

restcomm/restcomm.mscontrol.mms/src/main/java/org/restcomm/connect/mscontrol/mms/MmsBridgeController.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474

7575
/**
7676
* @author Henrique Rosa (henrique.rosa@telestax.com)
77+
* @author maria.farooq@telestax.com (Maria Farooq)
7778
*
7879
*/
7980
public class MmsBridgeController extends MediaServerController {
@@ -347,7 +348,9 @@ private void onMediaGroupStateChanged(MediaGroupStateChanged message, ActorRef s
347348

348349
private void onEndpointStateChanged(EndpointStateChanged message, ActorRef self, ActorRef sender) throws Exception {
349350
if (is(stopping)) {
350-
if (sender.equals(this.endpoint) && EndpointState.DESTROYED.equals(message.getState())) {
351+
if (sender.equals(this.endpoint) && (EndpointState.DESTROYED.equals(message.getState()) || EndpointState.FAILED.equals(message.getState()))) {
352+
if(EndpointState.FAILED.equals(message.getState()))
353+
logger.error("Could not destroy endpoint on media server. corresponding actor path is: " + this.endpoint.path());
351354
this.endpoint.tell(new StopObserving(self), self);
352355
context().stop(endpoint);
353356
endpoint = null;

restcomm/restcomm.mscontrol.mms/src/main/java/org/restcomm/connect/mscontrol/mms/MmsCallController.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@
102102

103103
/**
104104
* @author Henrique Rosa (henrique.rosa@telestax.com)
105+
* @author maria.farooq@telestax.com (Maria Farooq)
105106
*
106107
*/
107108
public class MmsCallController extends MediaServerController {
@@ -722,7 +723,9 @@ private void onCollect(Collect message, ActorRef self, ActorRef sender) {
722723

723724
private void onEndpointStateChanged(EndpointStateChanged message, ActorRef self, ActorRef sender) throws Exception {
724725
if (is(stopping)) {
725-
if (sender.equals(this.bridgeEndpoint) && EndpointState.DESTROYED.equals(message.getState())) {
726+
if (sender.equals(this.bridgeEndpoint) && (EndpointState.DESTROYED.equals(message.getState()) || EndpointState.FAILED.equals(message.getState()))) {
727+
if(EndpointState.FAILED.equals(message.getState()))
728+
logger.error("Could not destroy endpoint on media server. corresponding actor path is: " + this.bridgeEndpoint.path());
726729
this.bridgeEndpoint.tell(new StopObserving(self), self);
727730
context().stop(bridgeEndpoint);
728731
bridgeEndpoint = null;

restcomm/restcomm.mscontrol.mms/src/main/java/org/restcomm/connect/mscontrol/mms/MmsConferenceController.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,9 @@ private void onMediaGroupResponse(MediaGroupResponse<String> message, ActorRef s
437437

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

0 commit comments

Comments
 (0)