diff --git a/restcomm/restcomm.application/src/main/java/org/restcomm/connect/application/Bootstrapper.java b/restcomm/restcomm.application/src/main/java/org/restcomm/connect/application/Bootstrapper.java index 9a533dcdb0..f632bb3d8f 100644 --- a/restcomm/restcomm.application/src/main/java/org/restcomm/connect/application/Bootstrapper.java +++ b/restcomm/restcomm.application/src/main/java/org/restcomm/connect/application/Bootstrapper.java @@ -79,7 +79,7 @@ public void destroy() { system.awaitTermination(); } - private MediaServerControllerFactory mediaServerControllerFactory(final Configuration configuration, ClassLoader loader, DaoManager storage) + private MediaServerControllerFactory mediaServerControllerFactory(final Configuration configuration, ClassLoader loader, DaoManager storage, ActorRef monitoring) throws ServletException { Configuration settings ; String compatibility = configuration.subset("mscontrol").getString("compatibility", "rms"); @@ -89,7 +89,7 @@ private MediaServerControllerFactory mediaServerControllerFactory(final Configur case "rms": try { settings = configuration.subset("media-server-manager"); - ActorRef mrb = mediaResourceBroker(settings, storage, loader); + ActorRef mrb = mediaResourceBroker(settings, storage, loader, monitoring); factory = new MmsControllerFactory(mrb); } catch (UnknownHostException e) { throw new ServletException(e); @@ -200,7 +200,7 @@ private SipURI outboundInterface(ServletContext context, String transport) { return result; } - private ActorRef mediaResourceBroker(final Configuration configuration, final DaoManager storage, final ClassLoader loader) throws UnknownHostException{ + private ActorRef mediaResourceBroker(final Configuration configuration, final DaoManager storage, final ClassLoader loader, final ActorRef monitoring) throws UnknownHostException{ final Props props = new Props(new UntypedActorFactory() { private static final long serialVersionUID = 1L; @@ -211,7 +211,7 @@ public UntypedActor create() throws Exception { } }); ActorRef mrb = system.actorOf(props); - mrb.tell(new StartMediaResourceBroker(configuration, storage, loader), null); + mrb.tell(new StartMediaResourceBroker(configuration, storage, loader, monitoring), null); return mrb; } @@ -387,7 +387,7 @@ public void servletInitialized(SipServletContextEvent event) { // Create the media server controller factory MediaServerControllerFactory mscontrollerFactory = null; try { - mscontrollerFactory = mediaServerControllerFactory(xml, loader, storage); + mscontrollerFactory = mediaServerControllerFactory(xml, loader, storage, monitoring); } catch (ServletException exception) { logger.error("ServletException during initialization: ", exception); } diff --git a/restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/SupervisorEndpoint.java b/restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/SupervisorEndpoint.java index af32fe768d..080a74504f 100644 --- a/restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/SupervisorEndpoint.java +++ b/restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/SupervisorEndpoint.java @@ -134,14 +134,19 @@ protected Response getMetrics(final String accountSid, final UriInfo info, final checkAuthenticatedAccount(); allowOnlySuperAdmin(); boolean withLiveCallDetails = false; + boolean withMgcpStats = false; if (info != null && info.getQueryParameters().containsKey("LiveCallDetails") ) { withLiveCallDetails = Boolean.parseBoolean(info.getQueryParameters().getFirst("LiveCallDetails")); } + + if (info != null && info.getQueryParameters().containsKey("MgcpStats") ) { + withMgcpStats = Boolean.parseBoolean(info.getQueryParameters().getFirst("MgcpStats")); + } //Get the list of live calls from Monitoring Service MonitoringServiceResponse monitoringServiceResponse; try { final Timeout expires = new Timeout(Duration.create(5, TimeUnit.SECONDS)); - GetStatistics getStatistics = new GetStatistics(withLiveCallDetails, accountSid); + GetStatistics getStatistics = new GetStatistics(withLiveCallDetails, withMgcpStats, accountSid); Future future = (Future) ask(monitoringService, getStatistics, expires); monitoringServiceResponse = (MonitoringServiceResponse) Await.result(future, Duration.create(5, TimeUnit.SECONDS)); } catch (Exception exception) { @@ -202,14 +207,19 @@ protected Response registerForUpdates(final String accountSid, final UriInfo inf checkAuthenticatedAccount(); allowOnlySuperAdmin(); boolean withLiveCallDetails = false; + boolean withMgcpStats = false; if (info != null && info.getQueryParameters().containsKey("LiveCallDetails") ) { withLiveCallDetails = Boolean.parseBoolean(info.getQueryParameters().getFirst("LiveCallDetails")); } + + if (info != null && info.getQueryParameters().containsKey("MgcpStats") ) { + withMgcpStats = Boolean.parseBoolean(info.getQueryParameters().getFirst("MgcpStats")); + } //Get the list of live calls from Monitoring Service MonitoringServiceResponse monitoringServiceResponse; try { final Timeout expires = new Timeout(Duration.create(60, TimeUnit.SECONDS)); - GetStatistics getStatistics = new GetStatistics(withLiveCallDetails, accountSid); + GetStatistics getStatistics = new GetStatistics(withLiveCallDetails, withMgcpStats, accountSid); Future future = (Future) ask(monitoringService, getStatistics, expires); monitoringServiceResponse = (MonitoringServiceResponse) Await.result(future, Duration.create(10, TimeUnit.SECONDS)); } catch (Exception exception) { @@ -238,14 +248,19 @@ protected Response registerForCallUpdates(final String accountSid, final String final String url = data.getFirst("Url"); final String refresh = data.getFirst("Refresh"); boolean withLiveCallDetails = false; + boolean withMgcpStats = false; if (data != null && data.containsKey("LiveCallDetails")) { withLiveCallDetails = Boolean.parseBoolean(data.getFirst("LiveCallDetails")); } + + if (data != null && data.containsKey("MgcpStats") ) { + withMgcpStats = Boolean.parseBoolean(data.getFirst("MgcpStats")); + } //Get the list of live calls from Monitoring Service MonitoringServiceResponse monitoringServiceResponse; try { final Timeout expires = new Timeout(Duration.create(60, TimeUnit.SECONDS)); - GetStatistics getStatistics = new GetStatistics(withLiveCallDetails, accountSid); + GetStatistics getStatistics = new GetStatistics(withLiveCallDetails, withMgcpStats, accountSid); Future future = (Future) ask(monitoringService, getStatistics, expires); monitoringServiceResponse = (MonitoringServiceResponse) Await.result(future, Duration.create(10, TimeUnit.SECONDS)); } catch (Exception exception) { diff --git a/restcomm/restcomm.mgcp/src/main/java/org/restcomm/connect/mgcp/MockMediaGateway.java b/restcomm/restcomm.mgcp/src/main/java/org/restcomm/connect/mgcp/MockMediaGateway.java index f6b3985261..3d57cdea63 100644 --- a/restcomm/restcomm.mgcp/src/main/java/org/restcomm/connect/mgcp/MockMediaGateway.java +++ b/restcomm/restcomm.mgcp/src/main/java/org/restcomm/connect/mgcp/MockMediaGateway.java @@ -49,11 +49,16 @@ import org.mobicents.protocols.mgcp.jain.pkg.AUPackage; import org.restcomm.connect.commons.faulttolerance.RestcommUntypedActor; import org.restcomm.connect.commons.util.RevolvingCounter; +import org.restcomm.connect.mgcp.stats.MgcpConnectionAdded; +import org.restcomm.connect.mgcp.stats.MgcpConnectionDeleted; +import org.restcomm.connect.mgcp.stats.MgcpEndpointAdded; +import org.restcomm.connect.mgcp.stats.MgcpEndpointDeleted; import javax.sdp.SdpFactory; import javax.sdp.SdpParseException; import javax.sdp.SessionDescription; import java.net.InetAddress; +import java.util.Collections; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -89,30 +94,16 @@ public class MockMediaGateway extends RestcommUntypedActor { private RevolvingCounter connectionIdPool; private RevolvingCounter endpointIdPool; - private static Map endpoints; - private static Map links; - private static Map connections; + private Map connEndpointMap; + + private ActorRef monitoringService; private ActorSystem system; public MockMediaGateway() { super(); - endpoints = new ConcurrentHashMap(); - links = new ConcurrentHashMap(); - connections = new ConcurrentHashMap(); system = context().system(); - } - - public static Map getEndpointsMap() { - return endpoints; - } - - public static Map getConnections() { - return connections; - } - - public static Map getLinks() { - return links; + connEndpointMap = new ConcurrentHashMap(); } private ActorRef getConnection(final Object message) { @@ -127,7 +118,10 @@ public UntypedActor create() throws Exception { } }); ActorRef connection = system.actorOf(props); - connections.put(session, connection); + if (logger.isInfoEnabled()) { + String msg = String.format("MockMediaGateway, Added new Connection, path: %s",connection.path()); + logger.info(msg); + } return connection; } @@ -144,7 +138,10 @@ public Actor create() throws Exception { } }); ActorRef bridgeEndpoint = system.actorOf(props); - endpoints.put(session, bridgeEndpoint); + if (logger.isInfoEnabled()) { + String msg = String.format("MockMediaGateway, Added Bridge endpoint, path: %s",bridgeEndpoint.path()); + logger.info(msg); + } return bridgeEndpoint; } @@ -165,7 +162,10 @@ public UntypedActor create() throws Exception { } }); ActorRef conferenceEndpoint = system.actorOf(props); - endpoints.put(session, conferenceEndpoint); + if (logger.isInfoEnabled()) { + String msg = String.format("MockMediaGateway, Added Conference endpoint, path: %s", conferenceEndpoint.path()); + logger.info(msg); + } return conferenceEndpoint; } @@ -188,7 +188,10 @@ public UntypedActor create() throws Exception { } }); ActorRef ivrEndpoint = system.actorOf(props); - endpoints.put(session, ivrEndpoint); + if (logger.isInfoEnabled()) { + String msg = String.format("MockMediaGateway, Added Ivr endpoint, path: %s",ivrEndpoint.path()); + logger.info(msg); + } return ivrEndpoint; } @@ -205,7 +208,10 @@ public UntypedActor create() throws Exception { } }); ActorRef link = system.actorOf(props); - links.put(session, link); + if (logger.isInfoEnabled()) { + String msg = String.format("MockMediaGateway, Added new Link, path: %s",link.path()); + logger.info(msg); + } return link; } @@ -222,7 +228,10 @@ public UntypedActor create() throws Exception { } }); ActorRef packetRelayEndpoint = system.actorOf(props); - endpoints.put(session, packetRelayEndpoint); + if (logger.isInfoEnabled()) { + String msg = String.format("MockMediaGateway, Added PacketRelay endpoint, path: %s",packetRelayEndpoint.path()); + logger.info(msg); + } return packetRelayEndpoint; } @@ -264,6 +273,7 @@ private void powerOn(final Object message) { requestIdPool = new RevolvingCounter(1, Integer.MAX_VALUE); sessionIdPool = new RevolvingCounter(1, Integer.MAX_VALUE); transactionIdPool = new RevolvingCounter(1, Integer.MAX_VALUE); + monitoringService = request.getMonitoringService(); } @Override @@ -298,15 +308,24 @@ public void onReceive(final Object message) throws Exception { sender.tell(new MediaGatewayResponse(endpoint), self); } else if (DestroyConnection.class.equals(klass)) { final DestroyConnection request = (DestroyConnection) message; - connections.values().remove(request.connection()); + if (logger.isInfoEnabled()) { + String msg = String.format("MockMediaGateway, Connection destroyed, path %s",request.connection().path()); + logger.info(msg); + } context.stop(request.connection()); } else if (DestroyLink.class.equals(klass)) { final DestroyLink request = (DestroyLink) message; - links.values().remove(request.link()); + if (logger.isInfoEnabled()) { + String msg = String.format("MockMediaGateway, Link destroyed, path %s",request.link().path()); + logger.info(msg); + } context.stop(request.link()); } else if (DestroyEndpoint.class.equals(klass)) { final DestroyEndpoint request = (DestroyEndpoint) message; - endpoints.values().remove(request.endpoint()); + if (logger.isInfoEnabled()) { + String msg = String.format("MockMediaGateway, Endpoint destroyed, path %s",request.endpoint().path()); + logger.info(msg); + } context.stop(request.endpoint()); } else if (message instanceof JainMgcpCommandEvent) { send(message, sender); @@ -336,14 +355,21 @@ private void createConnection(final Object message, final ActorRef sender) { buffer.append(endpointIdPool.get()); endpointId = new EndpointIdentifier(buffer.toString(), domain); } + connEndpointMap.put(connId.toString(), endpointId.getLocalEndpointName()); + if (logger.isInfoEnabled()) { + String msg = String.format("About to add connId %s for endpoint %s", connId.toString(), endpointId.getLocalEndpointName()); + logger.info(msg); + } + monitoringService.tell(new MgcpEndpointAdded(connId.toString(), endpointId.getLocalEndpointName()), self()); + monitoringService.tell(new MgcpConnectionAdded(connId.toString(), endpointId.getLocalEndpointName()), self()); response.setSpecificEndpointIdentifier(endpointId); // Create a new secondary end point id if necessary. EndpointIdentifier secondaryEndpointId = crcx.getSecondEndpointIdentifier(); if (secondaryEndpointId != null) { buffer = new StringBuilder(); buffer.append(connectionIdPool.get()); - connId = new ConnectionIdentifier(buffer.toString()); - response.setSecondConnectionIdentifier(connId); + ConnectionIdentifier secondayConnId = new ConnectionIdentifier(buffer.toString()); + response.setSecondConnectionIdentifier(secondayConnId); endpointName = secondaryEndpointId.getLocalEndpointName(); if (endpointName.endsWith("$")) { final String[] tokens = endpointName.split("/"); @@ -353,6 +379,13 @@ private void createConnection(final Object message, final ActorRef sender) { buffer.append(endpointIdPool.get()); secondaryEndpointId = new EndpointIdentifier(buffer.toString(), domain); } + connEndpointMap.put(secondayConnId.toString(), secondaryEndpointId.getLocalEndpointName()); + if (logger.isInfoEnabled()) { + String msg = String.format("About to add connId %s for secondary endpoint %s associated with endpont %s", secondayConnId.toString(), secondaryEndpointId.getLocalEndpointName(), endpointId.getLocalEndpointName()); + logger.info(msg); + } + monitoringService.tell(new MgcpEndpointAdded(connId.toString(), secondaryEndpointId.getLocalEndpointName()), self()); + monitoringService.tell(new MgcpConnectionAdded(secondayConnId.toString(), secondaryEndpointId.getLocalEndpointName())); response.setSecondEndpointIdentifier(secondaryEndpointId); } final ConnectionDescriptor descriptor = new ConnectionDescriptor(sdp); @@ -366,7 +399,11 @@ private void createConnection(final Object message, final ActorRef sender) { private void modifyConnection(final Object message, final ActorRef sender) { final ActorRef self = self(); final ModifyConnection mdcx = (ModifyConnection) message; - System.out.println(mdcx.toString()); + System.out.println("MDCX: \n" +mdcx.toString()); + if (logger.isInfoEnabled()) { + String msg = String.format("Got MDCX for endpoint %s connId %s, mdcx: \n%s", mdcx.getEndpointIdentifier().getLocalEndpointName(), mdcx.getConnectionIdentifier(), mdcx); + logger.info(msg); + } ReturnCode code; SessionDescription sessionDescription = null; boolean isNonValidSdp = false; @@ -400,6 +437,28 @@ private void modifyConnection(final Object message, final ActorRef sender) { private void deleteConnection(final Object message, final ActorRef sender) { final ActorRef self = self(); final DeleteConnection dlcx = (DeleteConnection) message; + if (dlcx.getConnectionIdentifier() == null) { + connEndpointMap.values().removeAll(Collections.singleton(dlcx.getEndpointIdentifier().getLocalEndpointName())); + monitoringService.tell(new MgcpConnectionDeleted(null, dlcx.getEndpointIdentifier().getLocalEndpointName()), self()); + monitoringService.tell(new MgcpEndpointDeleted(dlcx.getEndpointIdentifier().getLocalEndpointName()), self()); + if (logger.isInfoEnabled()) { + String msg = String.format("Endpoint deleted %s", dlcx.getEndpointIdentifier().getLocalEndpointName()); + logger.info(msg); + } + } else { + connEndpointMap.remove(dlcx.getConnectionIdentifier().toString()); + monitoringService.tell(new MgcpConnectionDeleted(dlcx.getConnectionIdentifier().toString(), null), self()); + //If all connections have been removed for a given Endpoint, we can consider that the endpoint is stopped (this is the RMS behavior) + //Here check if we have Endpoint ID on the map, and if not, tell MonitoringService that the endpoint stopped. + if (!connEndpointMap.values().contains(dlcx.getEndpointIdentifier().getLocalEndpointName())) { + monitoringService.tell(new MgcpEndpointDeleted(dlcx.getEndpointIdentifier().getLocalEndpointName()), self()); + if (logger.isInfoEnabled()) { + String msg = String.format("Endpoint deleted %s since because there are no more connections related to this endpoint", dlcx.getEndpointIdentifier().getLocalEndpointName()); + logger.info(msg); + } + } + } + System.out.println(dlcx.toString()); final ReturnCode code = ReturnCode.Transaction_Executed_Normally; final DeleteConnectionResponse response = new DeleteConnectionResponse(self, code); diff --git a/restcomm/restcomm.mgcp/src/main/java/org/restcomm/connect/mgcp/PowerOnMediaGateway.java b/restcomm/restcomm.mgcp/src/main/java/org/restcomm/connect/mgcp/PowerOnMediaGateway.java index e2d3b64d37..7863a8f365 100644 --- a/restcomm/restcomm.mgcp/src/main/java/org/restcomm/connect/mgcp/PowerOnMediaGateway.java +++ b/restcomm/restcomm.mgcp/src/main/java/org/restcomm/connect/mgcp/PowerOnMediaGateway.java @@ -19,6 +19,7 @@ */ package org.restcomm.connect.mgcp; +import akka.actor.ActorRef; import jain.protocol.ip.mgcp.JainMgcpProvider; import jain.protocol.ip.mgcp.JainMgcpStack; import org.restcomm.connect.commons.annotations.concurrency.Immutable; @@ -43,10 +44,11 @@ public final class PowerOnMediaGateway { private final long timeout; private final JainMgcpStack stack; private final JainMgcpProvider provider; + private final ActorRef monitoringService; public PowerOnMediaGateway(final String name, final InetAddress localIp, final int localPort, final InetAddress remoteIp, final int remotePort, final boolean useNat, final InetAddress externalIp, final long timeout, final JainMgcpStack stack, - final JainMgcpProvider provider) { + final JainMgcpProvider provider, final ActorRef monitoringService) { super(); this.name = name; this.localIp = localIp; @@ -58,6 +60,7 @@ public PowerOnMediaGateway(final String name, final InetAddress localIp, final i this.timeout = timeout; this.stack = stack; this.provider = provider; + this.monitoringService = monitoringService; } public static Builder builder() { @@ -104,6 +107,10 @@ public JainMgcpProvider getProvider() { return provider; } + public ActorRef getMonitoringService () { + return monitoringService; + } + public static final class Builder { private String name; private InetAddress localIp; @@ -115,13 +122,14 @@ public static final class Builder { private long timeout; private JainMgcpStack stack; private JainMgcpProvider provider; + private ActorRef monitoringService; private Builder() { super(); } public PowerOnMediaGateway build() { - return new PowerOnMediaGateway(name, localIp, localPort, remoteIp, remotePort, useNat, externalIp, timeout, stack, provider); + return new PowerOnMediaGateway(name, localIp, localPort, remoteIp, remotePort, useNat, externalIp, timeout, stack, provider, monitoringService); } public void setName(final String name) { @@ -163,5 +171,9 @@ public void setStack(JainMgcpStack stack) { public void setProvider(JainMgcpProvider provider) { this.provider = provider; } + + public void setMonitoringService (ActorRef monitoringService) { + this.monitoringService = monitoringService; + } } } diff --git a/restcomm/restcomm.mgcp/src/main/java/org/restcomm/connect/mgcp/stats/MgcpConnectionAdded.java b/restcomm/restcomm.mgcp/src/main/java/org/restcomm/connect/mgcp/stats/MgcpConnectionAdded.java new file mode 100644 index 0000000000..3922bac477 --- /dev/null +++ b/restcomm/restcomm.mgcp/src/main/java/org/restcomm/connect/mgcp/stats/MgcpConnectionAdded.java @@ -0,0 +1,19 @@ +package org.restcomm.connect.mgcp.stats; + +public class MgcpConnectionAdded { + private final String connId; + private final String endpointId; + + public MgcpConnectionAdded (String connId, String endpointId) { + this.connId = connId; + this.endpointId = endpointId; + } + + public String getConnId () { + return connId; + } + + public String getEndpointId () { + return endpointId; + } +} diff --git a/restcomm/restcomm.mgcp/src/main/java/org/restcomm/connect/mgcp/stats/MgcpConnectionDeleted.java b/restcomm/restcomm.mgcp/src/main/java/org/restcomm/connect/mgcp/stats/MgcpConnectionDeleted.java new file mode 100644 index 0000000000..099de39e5c --- /dev/null +++ b/restcomm/restcomm.mgcp/src/main/java/org/restcomm/connect/mgcp/stats/MgcpConnectionDeleted.java @@ -0,0 +1,19 @@ +package org.restcomm.connect.mgcp.stats; + +public class MgcpConnectionDeleted { + private final String connId; + private final String endpoint; + + public MgcpConnectionDeleted (String connId, String endpoint) { + this.connId = connId; + this.endpoint = endpoint; + } + + public String getConnId () { + return connId; + } + + public String getEndpoint () { + return endpoint; + } +} diff --git a/restcomm/restcomm.mgcp/src/main/java/org/restcomm/connect/mgcp/stats/MgcpEndpointAdded.java b/restcomm/restcomm.mgcp/src/main/java/org/restcomm/connect/mgcp/stats/MgcpEndpointAdded.java new file mode 100644 index 0000000000..6116051faf --- /dev/null +++ b/restcomm/restcomm.mgcp/src/main/java/org/restcomm/connect/mgcp/stats/MgcpEndpointAdded.java @@ -0,0 +1,19 @@ +package org.restcomm.connect.mgcp.stats; + +public class MgcpEndpointAdded { + private final String connId; + private final String endpoint; + + public MgcpEndpointAdded (String connId, String endpoint) { + this.connId = connId; + this.endpoint = endpoint; + } + + public String getConnId () { + return connId; + } + + public String getEndpoint () { + return endpoint; + } +} diff --git a/restcomm/restcomm.mgcp/src/main/java/org/restcomm/connect/mgcp/stats/MgcpEndpointDeleted.java b/restcomm/restcomm.mgcp/src/main/java/org/restcomm/connect/mgcp/stats/MgcpEndpointDeleted.java new file mode 100644 index 0000000000..fe1ad9da47 --- /dev/null +++ b/restcomm/restcomm.mgcp/src/main/java/org/restcomm/connect/mgcp/stats/MgcpEndpointDeleted.java @@ -0,0 +1,13 @@ +package org.restcomm.connect.mgcp.stats; + +public class MgcpEndpointDeleted { + private final String endpoint; + + public MgcpEndpointDeleted (String endpoint) { + this.endpoint = endpoint; + } + + public String getEndpoint () { + return endpoint; + } +} diff --git a/restcomm/restcomm.monitoring.service/pom.xml b/restcomm/restcomm.monitoring.service/pom.xml index 4a9e42c48d..9811ea06e7 100644 --- a/restcomm/restcomm.monitoring.service/pom.xml +++ b/restcomm/restcomm.monitoring.service/pom.xml @@ -80,5 +80,11 @@ ${jain-sip-api.version} provided + + + org.restcomm + restcomm-connect.mgcp + ${project.version} + diff --git a/restcomm/restcomm.monitoring.service/src/main/java/org/restcomm/connect/monitoringservice/MonitoringMetrics.java b/restcomm/restcomm.monitoring.service/src/main/java/org/restcomm/connect/monitoringservice/MonitoringMetrics.java index a7f0fdf1a9..a214a035c6 100644 --- a/restcomm/restcomm.monitoring.service/src/main/java/org/restcomm/connect/monitoringservice/MonitoringMetrics.java +++ b/restcomm/restcomm.monitoring.service/src/main/java/org/restcomm/connect/monitoringservice/MonitoringMetrics.java @@ -27,4 +27,11 @@ public class MonitoringMetrics { public static String COUNTERS_MAP_TEXT_MESSAGE_INBOUND_TO_PROXY_OUT="TextMessageInboundToProxyOut"; public static String COUNTERS_MAP_TEXT_MESSAGE_NOT_FOUND="TextMessageNotFound"; public static String COUNTERS_MAP_TEXT_MESSAGE_OUTBOUND="TextMessageOutbound"; + public static String COUNTERS_MAP_MGCP_CONNECTIONS="MgcpConnections"; + public static String COUNTERS_MAP_MGCP_LINKS="MgcpLinks"; + public static String COUNTERS_MAP_MGCP_ENDPOINTS="MgcpEndpoints"; + public static String COUNTERS_MAP_MGCP_ENDPOINTS_BRIDGE="MgcpEndpointsBridge"; + public static String COUNTERS_MAP_MGCP_ENDPOINTS_IVR="MgcpEndpointsIvr"; + public static String COUNTERS_MAP_MGCP_ENDPOINTS_PACKETRELAY="MgcpEndpointsPacketRelay"; + public static String COUNTERS_MAP_MGCP_ENDPOINTS_CONFERENCE="MgcpEndpointsConference"; } diff --git a/restcomm/restcomm.monitoring.service/src/main/java/org/restcomm/connect/monitoringservice/MonitoringService.java b/restcomm/restcomm.monitoring.service/src/main/java/org/restcomm/connect/monitoringservice/MonitoringService.java index 5003bcf1ce..f8814434ce 100644 --- a/restcomm/restcomm.monitoring.service/src/main/java/org/restcomm/connect/monitoringservice/MonitoringService.java +++ b/restcomm/restcomm.monitoring.service/src/main/java/org/restcomm/connect/monitoringservice/MonitoringService.java @@ -29,6 +29,10 @@ import org.restcomm.connect.commons.patterns.StopObserving; import org.restcomm.connect.dao.DaoManager; import org.restcomm.connect.dao.entities.InstanceId; +import org.restcomm.connect.mgcp.stats.MgcpConnectionAdded; +import org.restcomm.connect.mgcp.stats.MgcpConnectionDeleted; +import org.restcomm.connect.mgcp.stats.MgcpEndpointAdded; +import org.restcomm.connect.mgcp.stats.MgcpEndpointDeleted; import org.restcomm.connect.telephony.api.CallInfo; import org.restcomm.connect.telephony.api.CallResponse; import org.restcomm.connect.telephony.api.CallStateChanged; @@ -46,6 +50,7 @@ import java.net.URISyntaxException; import java.text.ParseException; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -84,6 +89,16 @@ public class MonitoringService extends RestcommUntypedActor { private final AtomicInteger maxConcurrentCalls; private final AtomicInteger maxConcurrentIncomingCalls; private final AtomicInteger maxConcurrentOutgoingCalls; + + private final AtomicInteger mgcpEndpointsBridge; + private final AtomicInteger mgcpEndpointsIvr; + private final AtomicInteger mgcpEndpointsConference; + private final AtomicInteger mgcpEndpointsPacketRelay; + private final Map mgcpEndpointMap; + private final Map mgcpConnectionMap; + + + private InstanceId instanceId; @@ -113,6 +128,15 @@ public MonitoringService(final DaoManager daoManager) { maxConcurrentCalls = new AtomicInteger(0); maxConcurrentIncomingCalls = new AtomicInteger(0); maxConcurrentOutgoingCalls = new AtomicInteger(0); + + mgcpEndpointsBridge = new AtomicInteger(0); + mgcpEndpointsIvr = new AtomicInteger(0); + mgcpEndpointsConference = new AtomicInteger(0); + mgcpEndpointsPacketRelay = new AtomicInteger(0); + + mgcpEndpointMap = new ConcurrentHashMap(); + mgcpConnectionMap = new ConcurrentHashMap(); + if(logger.isInfoEnabled()){ logger.info("Monitoring Service started"); } @@ -156,6 +180,43 @@ public void onReceive(Object message) throws Exception { logger.debug("MonitoringService onGetCall, message is null, sender: "+sender.path()); } } + } else if (MgcpConnectionAdded.class.equals(klass)) { + MgcpConnectionAdded mgcpConnectionAdded = (MgcpConnectionAdded)message; + mgcpConnectionMap.put(mgcpConnectionAdded.getConnId(), mgcpConnectionAdded.getEndpointId()); + } else if (MgcpConnectionDeleted.class.equals(klass)) { + MgcpConnectionDeleted mgcpConnectionDeleted = (MgcpConnectionDeleted)message; + if (mgcpConnectionDeleted.getConnId() != null) { + mgcpConnectionMap.remove(mgcpConnectionDeleted.getConnId()); + } else { + mgcpConnectionMap.values().removeAll(Collections.singleton(mgcpConnectionDeleted.getEndpoint())); + } + } else if (MgcpEndpointAdded.class.equals(klass)) { + MgcpEndpointAdded mgcpEndpointAdded = (MgcpEndpointAdded)message; + mgcpEndpointMap.put(mgcpEndpointAdded.getConnId(), mgcpEndpointAdded.getEndpoint()); + logger.info("MonitoringService: Added endpoint: "+mgcpEndpointAdded.getEndpoint()); + String endpoint = mgcpEndpointAdded.getEndpoint(); + if (endpoint.contains("ivr")) { + mgcpEndpointsIvr.incrementAndGet(); + } else if (endpoint.contains("conf")) { + mgcpEndpointsConference.incrementAndGet(); + } else if (endpoint.contains("bridge")) { + mgcpEndpointsBridge.incrementAndGet(); + } else if (endpoint.contains("relay")) { + mgcpEndpointsPacketRelay.incrementAndGet(); + } + } else if (MgcpEndpointDeleted.class.equals(klass)) { + MgcpEndpointDeleted mgcpEndpointDeleted = (MgcpEndpointDeleted)message; + mgcpEndpointMap.values().removeAll(Collections.singleton(mgcpEndpointDeleted.getEndpoint())); + String endpoint = mgcpEndpointDeleted.getEndpoint(); + if (endpoint.contains("ivr")) { + mgcpEndpointsIvr.decrementAndGet(); + } else if (endpoint.contains("conf")) { + mgcpEndpointsConference.decrementAndGet(); + } else if (endpoint.contains("bridge")) { + mgcpEndpointsBridge.decrementAndGet(); + } else if (endpoint.contains("relay")) { + mgcpEndpointsPacketRelay.decrementAndGet(); + } } } @@ -428,6 +489,17 @@ private void onGetStatistics (GetStatistics message, ActorRef self, ActorRef sen countersMap.put(MonitoringMetrics.COUNTERS_MAP_TEXT_MESSAGE_NOT_FOUND, textNotFound.get()); countersMap.put(MonitoringMetrics.COUNTERS_MAP_TEXT_MESSAGE_OUTBOUND, textOutbound.get()); + if (message.isWithMgcpStats()) { + countersMap.put(MonitoringMetrics.COUNTERS_MAP_MGCP_CONNECTIONS, mgcpConnectionMap.size()); + countersMap.put(MonitoringMetrics.COUNTERS_MAP_MGCP_ENDPOINTS, mgcpEndpointMap.size()); + if (mgcpEndpointMap.size()>0) { + countersMap.put(MonitoringMetrics.COUNTERS_MAP_MGCP_ENDPOINTS_BRIDGE, mgcpEndpointsBridge.get()); + countersMap.put(MonitoringMetrics.COUNTERS_MAP_MGCP_ENDPOINTS_IVR, mgcpEndpointsIvr.get()); + countersMap.put(MonitoringMetrics.COUNTERS_MAP_MGCP_ENDPOINTS_CONFERENCE, mgcpEndpointsConference.get()); + countersMap.put(MonitoringMetrics.COUNTERS_MAP_MGCP_ENDPOINTS_PACKETRELAY, mgcpEndpointsPacketRelay.get()); + } + } + MonitoringServiceResponse callInfoList = null; if (message.isWithLiveCallDetails()) { callInfoList = new MonitoringServiceResponse(instanceId, callDetailsList, countersMap, durationMap, true, null); diff --git a/restcomm/restcomm.mrb.api/src/main/java/org/restcomm/connect/mrb/api/StartMediaResourceBroker.java b/restcomm/restcomm.mrb.api/src/main/java/org/restcomm/connect/mrb/api/StartMediaResourceBroker.java index 7821c1018e..bd02c8c941 100644 --- a/restcomm/restcomm.mrb.api/src/main/java/org/restcomm/connect/mrb/api/StartMediaResourceBroker.java +++ b/restcomm/restcomm.mrb.api/src/main/java/org/restcomm/connect/mrb/api/StartMediaResourceBroker.java @@ -19,6 +19,7 @@ */ package org.restcomm.connect.mrb.api; +import akka.actor.ActorRef; import org.apache.commons.configuration.Configuration; import org.restcomm.connect.commons.annotations.concurrency.Immutable; import org.restcomm.connect.dao.DaoManager; @@ -31,12 +32,14 @@ public final class StartMediaResourceBroker { private final Configuration configuration; private final DaoManager storage; private final ClassLoader loader; + private final ActorRef monitoringService; - public StartMediaResourceBroker(final Configuration configuration, final DaoManager storage, final ClassLoader loader) { + public StartMediaResourceBroker(final Configuration configuration, final DaoManager storage, final ClassLoader loader, final ActorRef monitoringService) { super(); this.configuration = configuration; this.storage = storage; this.loader = loader; + this.monitoringService = monitoringService; } public Configuration configuration(){ @@ -50,4 +53,8 @@ public DaoManager storage(){ public ClassLoader loader(){ return this.loader; } + + public ActorRef getMonitoringService () { + return monitoringService; + } } diff --git a/restcomm/restcomm.mrb/src/main/java/org/restcomm/connect/mrb/MediaResourceBrokerGeneric.java b/restcomm/restcomm.mrb/src/main/java/org/restcomm/connect/mrb/MediaResourceBrokerGeneric.java index 70eecd086d..9b5c3488f4 100644 --- a/restcomm/restcomm.mrb/src/main/java/org/restcomm/connect/mrb/MediaResourceBrokerGeneric.java +++ b/restcomm/restcomm.mrb/src/main/java/org/restcomm/connect/mrb/MediaResourceBrokerGeneric.java @@ -69,6 +69,7 @@ public class MediaResourceBrokerGeneric extends RestcommUntypedActor { protected Configuration configuration; protected DaoManager storage; protected ClassLoader loader; + protected ActorRef monitoringService; protected ActorRef localMediaGateway; protected String localMsId; protected Map mediaGatewayMap; @@ -113,6 +114,7 @@ protected void onStartMediaResourceBroker(StartMediaResourceBroker message, Acto this.configuration = message.configuration(); this.storage = message.storage(); this.loader = message.loader(); + this.monitoringService = message.getMonitoringService(); localMediaServerEntity = uploadLocalMediaServersInDataBase(); bindMGCPStack(localMediaServerEntity.getLocalIpAddress(), localMediaServerEntity.getLocalPort()); @@ -184,6 +186,7 @@ protected ActorRef turnOnMediaGateway(MediaServerEntity mediaServerEntity) throw builder.setTimeout(Long.parseLong(mediaServerEntity.getResponseTimeout())); builder.setStack(mgcpStack); builder.setProvider(mgcpProvider); + builder.setMonitoringService(monitoringService); final PowerOnMediaGateway powerOn = builder.build(); gateway.tell(powerOn, null); diff --git a/restcomm/restcomm.mscontrol.mms/src/main/java/org/restcomm/connect/mscontrol/mms/MmsCallController.java b/restcomm/restcomm.mscontrol.mms/src/main/java/org/restcomm/connect/mscontrol/mms/MmsCallController.java index 9a662107fe..f2a4093260 100644 --- a/restcomm/restcomm.mscontrol.mms/src/main/java/org/restcomm/connect/mscontrol/mms/MmsCallController.java +++ b/restcomm/restcomm.mscontrol.mms/src/main/java/org/restcomm/connect/mscontrol/mms/MmsCallController.java @@ -1109,6 +1109,15 @@ public FinalState(ActorRef source, final MediaServerControllerState state) { public void execute(Object message) throws Exception { // Notify observers the controller has stopped broadcast(new MediaServerControllerStateChanged(state)); + if (mediaGroup != null) { + // Stop the media group + mediaGroup.tell(new StopMediaGroup(), super.source); + } + + if (bridgeEndpoint != null) { + // Stop bridge endpoint + bridgeEndpoint.tell(new DestroyEndpoint(), super.source); + } } } @@ -1161,7 +1170,7 @@ public Inactive(final ActorRef source) { private final class Failed extends FinalState { - public Failed(final ActorRef source) { + public Failed(final ActorRef source){ super(source, MediaServerControllerState.FAILED); } diff --git a/restcomm/restcomm.sms/src/main/java/org/restcomm/connect/sms/SmsSession.java b/restcomm/restcomm.sms/src/main/java/org/restcomm/connect/sms/SmsSession.java index 19d386f5b0..7e74bb1513 100644 --- a/restcomm/restcomm.sms/src/main/java/org/restcomm/connect/sms/SmsSession.java +++ b/restcomm/restcomm.sms/src/main/java/org/restcomm/connect/sms/SmsSession.java @@ -300,7 +300,7 @@ private void outbound(final Object message) { // 2, SMPP is activated if (toClient == null && smppActivated) { if(logger.isInfoEnabled()) { - logger.info("Destination is not a local registered client, therefore, sending through SMPP to: " + last.to() ); + logger.info("Destination is not a local registered client, therefore, sending through SMPP to: {} " + last.to() ); } if (sendUsingSmpp(last.from(), last.to(), last.body(), tlvSet, charset)) return; diff --git a/restcomm/restcomm.telephony.api/src/main/java/org/restcomm/connect/telephony/api/GetStatistics.java b/restcomm/restcomm.telephony.api/src/main/java/org/restcomm/connect/telephony/api/GetStatistics.java index e0660c5589..ad0fa8f2e9 100644 --- a/restcomm/restcomm.telephony.api/src/main/java/org/restcomm/connect/telephony/api/GetStatistics.java +++ b/restcomm/restcomm.telephony.api/src/main/java/org/restcomm/connect/telephony/api/GetStatistics.java @@ -5,15 +5,21 @@ */ public class GetStatistics { private final boolean withLiveCallDetails; + private final boolean withMgcpStats; private final String accountSid; - public GetStatistics (final boolean withLiveCallDetails, final String accountSid) { + public GetStatistics (final boolean withLiveCallDetails, final boolean withMgcpStats, final String accountSid) { this.withLiveCallDetails = withLiveCallDetails; + this.withMgcpStats = withMgcpStats; this.accountSid = accountSid; } public boolean isWithLiveCallDetails () { return withLiveCallDetails; } + public boolean isWithMgcpStats () { + return withMgcpStats; + } + public String getAccountSid () { return accountSid; } diff --git a/restcomm/restcomm.telephony/src/main/java/org/restcomm/connect/telephony/Call.java b/restcomm/restcomm.telephony/src/main/java/org/restcomm/connect/telephony/Call.java index 34f5982e5b..6f3f31a8fe 100644 --- a/restcomm/restcomm.telephony/src/main/java/org/restcomm/connect/telephony/Call.java +++ b/restcomm/restcomm.telephony/src/main/java/org/restcomm/connect/telephony/Call.java @@ -1748,17 +1748,8 @@ public void execute(Object message) throws Exception { } msController.tell(new CloseMediaSession(), source); - if (fail) { - if (logger.isDebugEnabled()) { - logger.debug("At Call Stopping state, moving to Failed state"); - } - fsm.transition(message, failed); - } else { - if (logger.isDebugEnabled()) { - logger.debug("At Call Stopping state, moving to Completed state"); - } - fsm.transition(message, completed); - } + //Don't wait for ever for the CallController response + context().setReceiveTimeout(Duration.create(2000, TimeUnit.SECONDS)); } } @@ -1979,11 +1970,22 @@ private void onReceiveTimeout(ReceiveTimeout message, ActorRef self, ActorRef se for (final ActorRef observer : observers) { observer.tell(infoResponse, self()); } - + } else if (is(stopping)) { + if (fail) { + if (logger.isDebugEnabled()) { + logger.debug("At Call Stopping state, moving to Failed state"); + } + fsm.transition(message, failed); + } else { + if (logger.isDebugEnabled()) { + logger.debug("At Call Stopping state, moving to Completed state"); + } + fsm.transition(message, completed); + } } else if(logger.isInfoEnabled()) { - logger.info("Timeout received for Call : "+self().path()+" isTerminated(): "+self().isTerminated()+". Sender: " + sender.path().toString() + " State: " + this.fsm.state() - + " Direction: " + direction + " From: " + from + " To: " + to); - } + logger.info("Timeout received for Call : "+self().path()+" isTerminated(): "+self().isTerminated()+". Sender: " + sender.path().toString() + " State: " + this.fsm.state() + + " Direction: " + direction + " From: " + from + " To: " + to); + } } private void onSipServletRequest(SipServletRequest message, ActorRef self, ActorRef sender) throws Exception { @@ -2512,6 +2514,19 @@ private void onMediaServerControllerStateChanged(MediaServerControllerStateChang String msg = String.format("On MediaServerContollerStateChanged, message: INACTIVE, Call state: %s, Fail: %s", fsm.state(), fail); logger.debug(msg); } + + if (fail) { + if (logger.isDebugEnabled()) { + logger.debug("At Call Stopping state, moving to Failed state"); + } + fsm.transition(message, failed); + } else { + if (logger.isDebugEnabled()) { + logger.debug("At Call Stopping state, moving to Completed state"); + } + fsm.transition(message, completed); + } + // if (fail) { // fsm.transition(message, failed); // } else { @@ -2604,7 +2619,7 @@ private void onLeft(Left message, ActorRef self, ActorRef sender) throws Excepti if (!liveCallModification) { // After leaving let the Interpreter know the Call is ready. - fsm.transition(message, completed); + fsm.transition(message, stopping); } else { if (muted) { // Forward to media server controller diff --git a/restcomm/restcomm.testsuite/pom.xml b/restcomm/restcomm.testsuite/pom.xml index 0726bc4109..a60d745dbb 100644 --- a/restcomm/restcomm.testsuite/pom.xml +++ b/restcomm/restcomm.testsuite/pom.xml @@ -278,7 +278,7 @@ mockito-all 1.8.5 test - + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/restcomm/restcomm.testsuite/src/test/resources/log4j.xml.cloud b/restcomm/restcomm.testsuite/src/test/resources/log4j.xml.cloud new file mode 100644 index 0000000000..18393d7f38 --- /dev/null +++ b/restcomm/restcomm.testsuite/src/test/resources/log4j.xml.cloud @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/restcomm/restcomm.testsuite/src/test/resources/restcomm.script_mgcpoperations b/restcomm/restcomm.testsuite/src/test/resources/restcomm.script_mgcpoperations new file mode 100644 index 0000000000..5035c16551 --- /dev/null +++ b/restcomm/restcomm.testsuite/src/test/resources/restcomm.script_mgcpoperations @@ -0,0 +1,33 @@ +CREATE SCHEMA PUBLIC AUTHORIZATION DBA +CREATE MEMORY TABLE "restcomm_instance_id"("instance_id" VARCHAR(34) NOT NULL PRIMARY KEY,"date_created" DATETIME NOT NULL,"date_updated" DATETIME NOT NULL, "host" VARCHAR(255) NOT NULL) +CREATE MEMORY TABLE "restcomm_organizations"("sid" VARCHAR(34) NOT NULL PRIMARY KEY, "domain_name" VARCHAR(255) NOT NULL UNIQUE, "date_created" DATETIME NOT NULL, "date_updated" DATETIME NOT NULL, "status" VARCHAR(16)) +CREATE MEMORY TABLE "restcomm_accounts"("sid" VARCHAR(34) NOT NULL PRIMARY KEY,"date_created" DATETIME NOT NULL,"date_updated" DATETIME NOT NULL,"email_address" LONGVARCHAR NOT NULL,"friendly_name" VARCHAR(64) NOT NULL,"parent_sid" VARCHAR(34),"type" VARCHAR(8) NOT NULL,"status" VARCHAR(16) NOT NULL,"auth_token" VARCHAR(32) NOT NULL,"role" VARCHAR(64) NOT NULL,"uri" LONGVARCHAR NOT NULL, "organization_sid" VARCHAR(34) DEFAULT 'ORafbe225ad37541eba518a74248f0ac4c') +CREATE MEMORY TABLE "restcomm_announcements"("sid" VARCHAR(34) NOT NULL PRIMARY KEY,"date_created" DATETIME NOT NULL,"account_sid" VARCHAR(34),"gender" VARCHAR(8) NOT NULL,"language" VARCHAR(16) NOT NULL,"text" VARCHAR(32) NOT NULL,"uri" LONGVARCHAR NOT NULL) +CREATE MEMORY TABLE "restcomm_available_phone_numbers"("friendly_name" VARCHAR(64) NOT NULL,"phone_number" VARCHAR(15) NOT NULL PRIMARY KEY,"lata" SMALLINT,"rate_center" VARCHAR(32),"latitude" DOUBLE,"longitude" DOUBLE,"region" VARCHAR(2),"postal_code" INTEGER,"iso_country" VARCHAR(2) NOT NULL,"voice_capable" BOOLEAN, "sms_capable" BOOLEAN, "mms_capable" BOOLEAN, "fax_capable" BOOLEAN,"cost" VARCHAR(10)) +CREATE MEMORY TABLE "restcomm_outgoing_caller_ids"("sid" VARCHAR(34) NOT NULL PRIMARY KEY,"date_created" DATETIME NOT NULL,"date_updated" DATETIME NOT NULL,"friendly_name" VARCHAR(64) NOT NULL,"account_sid" VARCHAR(34) NOT NULL,"phone_number" VARCHAR(15) NOT NULL,"uri" LONGVARCHAR NOT NULL) +CREATE MEMORY TABLE "restcomm_http_cookies"("sid" VARCHAR(34) NOT NULL PRIMARY KEY,"comment" LONGVARCHAR,"domain" LONGVARCHAR,"expiration_date" DATETIME,"name" LONGVARCHAR NOT NULL,"path" LONGVARCHAR,"value" LONGVARCHAR,"version" INT) +CREATE MEMORY TABLE "restcomm_incoming_phone_numbers"("sid" VARCHAR(34) NOT NULL PRIMARY KEY,"date_created" DATETIME NOT NULL,"date_updated" DATETIME NOT NULL,"friendly_name" VARCHAR(64) NOT NULL,"account_sid" VARCHAR(34) NOT NULL,"phone_number" VARCHAR(30) NOT NULL,"api_version" VARCHAR(10) NOT NULL,"voice_caller_id_lookup" BOOLEAN NOT NULL,"voice_url" LONGVARCHAR,"voice_method" VARCHAR(4),"voice_fallback_url" LONGVARCHAR,"voice_fallback_method" VARCHAR(4),"status_callback" LONGVARCHAR,"status_callback_method" VARCHAR(4),"voice_application_sid" VARCHAR(34),"sms_url" LONGVARCHAR,"sms_method" VARCHAR(4),"sms_fallback_url" LONGVARCHAR,"sms_fallback_method" VARCHAR(4),"sms_application_sid" VARCHAR(34),"uri" LONGVARCHAR NOT NULL, "voice_capable" BOOLEAN, "sms_capable" BOOLEAN, "mms_capable" BOOLEAN, "fax_capable" BOOLEAN, "pure_sip" BOOLEAN,"cost" VARCHAR(10), "ussd_url" LONGVARCHAR, "ussd_method" VARCHAR(4), "ussd_fallback_url" LONGVARCHAR, "ussd_fallback_method" VARCHAR(4), "ussd_application_sid" VARCHAR(34), "refer_url" LONGVARCHAR, "refer_method" VARCHAR(4), "refer_application_sid" VARCHAR(34), "organization_sid" VARCHAR(34) NOT NULL) +CREATE MEMORY TABLE "restcomm_applications"("sid" VARCHAR(34) NOT NULL PRIMARY KEY,"date_created" DATETIME NOT NULL,"date_updated" DATETIME NOT NULL,"friendly_name" VARCHAR(64) NOT NULL,"account_sid" VARCHAR(34) NOT NULL,"api_version" VARCHAR(10) NOT NULL,"voice_caller_id_lookup" BOOLEAN NOT NULL,"uri" LONGVARCHAR NOT NULL,"rcml_url" LONGVARCHAR, "kind" VARCHAR(5)) +CREATE MEMORY TABLE "restcomm_call_detail_records"("sid" VARCHAR(1000) NOT NULL PRIMARY KEY,"parent_call_sid" VARCHAR(1000),"date_created" DATETIME NOT NULL,"date_updated" DATETIME NOT NULL,"account_sid" VARCHAR(34) NOT NULL,"sender" VARCHAR(30) NOT NULL,"recipient" VARCHAR(64) NOT NULL,"phone_number_sid" VARCHAR(34),"status" VARCHAR(20) NOT NULL,"start_time" DATETIME,"end_time" DATETIME,"duration" INTEGER,"price" VARCHAR(8),"direction" VARCHAR(20) NOT NULL,"answered_by" VARCHAR(64),"api_version" VARCHAR(10) NOT NULL,"forwarded_from" VARCHAR(30),"caller_name" VARCHAR(50),"uri" LONGVARCHAR NOT NULL, "call_path" VARCHAR(255),"ring_duration" INTEGER, "instanceid" VARCHAR(255) NOT NULL, "conference_sid" VARCHAR(34),"muted" BOOLEAN, "start_conference_on_enter" BOOLEAN, "end_conference_on_exit" BOOLEAN, "on_hold" BOOLEAN, "ms_id" VARCHAR(34)) +CREATE MEMORY TABLE "restcomm_conference_detail_records" ( "sid" VARCHAR(34) NOT NULL PRIMARY KEY, "date_created" DATETIME NOT NULL, "date_updated" DATETIME NOT NULL, "account_sid" VARCHAR(34) NOT NULL, "status" VARCHAR(100) NOT NULL, "friendly_name" VARCHAR(60), "api_version" VARCHAR(10) NOT NULL, "uri" LONGVARCHAR NOT NULL, "master_ms_id" VARCHAR(34),"master_conference_endpoint_id" VARCHAR(20),"master_present" BOOLEAN DEFAULT TRUE, "master_ivr_endpoint_id" VARCHAR(20),"master_ivr_endpoint_session_id" VARCHAR(200),"master_bridge_endpoint_id" VARCHAR(20),"master_bridge_endpoint_session_id" VARCHAR(200),"master_bridge_conn_id" VARCHAR(200),"master_ivr_conn_id" VARCHAR(200)) +CREATE MEMORY TABLE "restcomm_clients"("sid" VARCHAR(34) NOT NULL PRIMARY KEY,"date_created" DATETIME NOT NULL,"date_updated" DATETIME NOT NULL,"account_sid" VARCHAR(34) NOT NULL,"api_version" VARCHAR(10) NOT NULL,"friendly_name" VARCHAR(64) NOT NULL,"login" VARCHAR(64) NOT NULL,"password" VARCHAR(64) NOT NULL,"status" INTEGER NOT NULL,"voice_url" LONGVARCHAR,"voice_method" VARCHAR(4),"voice_fallback_url" LONGVARCHAR,"voice_fallback_method" VARCHAR(4),"voice_application_sid" VARCHAR(34),"uri" LONGVARCHAR NOT NULL, "push_client_identity" VARCHAR(34)) +CREATE MEMORY TABLE "restcomm_registrations"("sid" VARCHAR(34) NOT NULL PRIMARY KEY,"date_created" DATETIME NOT NULL,"date_updated" DATETIME NOT NULL,"date_expires" DATETIME NOT NULL,"address_of_record" LONGVARCHAR NOT NULL,"display_name" VARCHAR(255),"user_name" VARCHAR(64) NOT NULL,"user_agent" LONGVARCHAR,"ttl" INTEGER NOT NULL,"location" LONGVARCHAR NOT NULL, "webrtc" BOOLEAN DEFAULT FALSE, "instanceid" VARCHAR(255), "isLBPresent" BOOLEAN DEFAULT FALSE, "organization_sid" VARCHAR(34)) +CREATE MEMORY TABLE "restcomm_short_codes"("sid" VARCHAR(34) NOT NULL PRIMARY KEY,"date_created" DATETIME NOT NULL,"date_updated" DATETIME NOT NULL,"friendly_name" VARCHAR(64) NOT NULL,"account_sid" VARCHAR(34) NOT NULL,"short_code" INTEGER NOT NULL,"api_version" VARCHAR(10) NOT NULL,"sms_url" LONGVARCHAR,"sms_method" VARCHAR(4),"sms_fallback_url" LONGVARCHAR,"sms_fallback_method" VARCHAR(4),"uri" LONGVARCHAR NOT NULL) +CREATE MEMORY TABLE "restcomm_sms_messages"("sid" VARCHAR(34) NOT NULL PRIMARY KEY,"date_created" DATETIME NOT NULL,"date_updated" DATETIME NOT NULL,"date_sent" DATETIME,"account_sid" VARCHAR(34) NOT NULL,"sender" VARCHAR(15) NOT NULL,"recipient" VARCHAR(64) NOT NULL,"body" VARCHAR(999) NOT NULL,"status" VARCHAR(20) NOT NULL,"direction" VARCHAR(14) NOT NULL,"price" VARCHAR(8) NOT NULL,"api_version" VARCHAR(10) NOT NULL,"uri" LONGVARCHAR NOT NULL) +CREATE MEMORY TABLE "restcomm_recordings"("sid" VARCHAR(34) NOT NULL PRIMARY KEY,"date_created" DATETIME NOT NULL,"date_updated" DATETIME NOT NULL,"account_sid" VARCHAR(34) NOT NULL,"call_sid" VARCHAR(1000) NOT NULL,"duration" DOUBLE NOT NULL,"api_version" VARCHAR(10) NOT NULL,"uri" LONGVARCHAR NOT NULL, "file_uri" LONGVARCHAR) +CREATE MEMORY TABLE "restcomm_transcriptions"("sid" VARCHAR(34) NOT NULL PRIMARY KEY,"date_created" DATETIME NOT NULL,"date_updated" DATETIME NOT NULL,"account_sid" VARCHAR(34) NOT NULL,"status" VARCHAR(11) NOT NULL,"recording_sid" VARCHAR(34) NOT NULL,"duration" DOUBLE NOT NULL,"transcription_text" LONGVARCHAR,"price" VARCHAR(8) NOT NULL,"uri" LONGVARCHAR NOT NULL) +CREATE MEMORY TABLE "restcomm_notifications"("sid" VARCHAR(34) NOT NULL PRIMARY KEY,"date_created" DATETIME NOT NULL,"date_updated" DATETIME NOT NULL,"account_sid" VARCHAR(34) NOT NULL,"call_sid" VARCHAR(1000),"api_version" VARCHAR(10) NOT NULL,"log" TINYINT NOT NULL,"error_code" SMALLINT NOT NULL,"more_info" LONGVARCHAR NOT NULL,"message_text" LONGVARCHAR NOT NULL,"message_date" DATETIME NOT NULL,"request_url" LONGVARCHAR NOT NULL,"request_method" VARCHAR(4) NOT NULL,"request_variables" LONGVARCHAR NOT NULL,"response_headers" LONGVARCHAR,"response_body" LONGVARCHAR,"uri" LONGVARCHAR NOT NULL) +CREATE MEMORY TABLE "restcomm_sand_boxes"("date_created" DATETIME NOT NULL,"date_updated" DATETIME NOT NULL,"pin" VARCHAR(8) NOT NULL,"account_sid" VARCHAR(34) NOT NULL PRIMARY KEY,"phone_number" VARCHAR(15) NOT NULL,"application_sid" VARCHAR(34) NOT NULL,"api_version" VARCHAR(10) NOT NULL,"voice_url" LONGVARCHAR,"voice_method" VARCHAR(4),"sms_url" LONGVARCHAR,"sms_method" VARCHAR(4),"status_callback" LONGVARCHAR,"status_callback_method" VARCHAR(4),"uri" LONGVARCHAR NOT NULL) +CREATE MEMORY TABLE "restcomm_gateways"("sid" VARCHAR(34) NOT NULL PRIMARY KEY,"date_created" DATETIME NOT NULL,"date_updated" DATETIME NOT NULL,"friendly_name" VARCHAR(255),"user_name" VARCHAR(255),"password" VARCHAR(255),"proxy" LONGVARCHAR NOT NULL,"register" BOOLEAN NOT NULL,"ttl" INT NOT NULL,"uri" LONGVARCHAR NOT NULL) +CREATE MEMORY TABLE "restcomm_media_servers" ( "ms_id" INT GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1) NOT NULL, "local_ip" VARCHAR(34) NOT NULL, "local_port" INT NOT NULL, "remote_ip" VARCHAR(34) NOT NULL UNIQUE, "remote_port" INT NOT NULL, "compatibility" VARCHAR(34) DEFAULT 'rms', "response_timeout" VARCHAR(34), "external_address" VARCHAR(34)) +CREATE MEMORY TABLE "restcomm_media_resource_broker_entity" ("conference_sid" VARCHAR(34) NOT NULL, "slave_ms_id" VARCHAR(34) NOT NULL, "slave_ms_bridge_ep_id" VARCHAR(34),"slave_ms_cnf_ep_id" VARCHAR(34),"is_bridged_together" BOOLEAN DEFAULT FALSE,PRIMARY KEY ("conference_sid" , "slave_ms_id")) +CREATE MEMORY TABLE PUBLIC."restcomm_extensions_configuration"("sid" VARCHAR(34) NOT NULL PRIMARY KEY,"extension" VARCHAR(255) NOT NULL,"configuration_data" VARCHAR(16777216),"configuration_type" VARCHAR(255) NOT NULL,"date_created" TIMESTAMP NOT NULL,"date_updated" TIMESTAMP, "enabled" BOOLEAN DEFAULT TRUE NOT NULL) +CREATE MEMORY TABLE "restcomm_geolocation"("sid" VARCHAR(34) NOT NULL PRIMARY KEY, "date_created" DATETIME NOT NULL, "date_updated" DATETIME NOT NULL, "date_executed" DATETIME NOT NULL, "account_sid" VARCHAR(34) NOT NULL, "source" VARCHAR(30), "device_identifier" VARCHAR(30) NOT NULL, "geolocation_type" VARCHAR(15) NOT NULL, "response_status" VARCHAR(30), "cell_id" VARCHAR(10), "location_area_code" VARCHAR(10), "mobile_country_code" INTEGER, "mobile_network_code" VARCHAR(3), "network_entity_address" BIGINT, "age_of_location_info" INTEGER, "device_latitude" VARCHAR(15), "device_longitude" VARCHAR(15), "accuracy" BIGINT, "physical_address" VARCHAR(50), "internet_address" VARCHAR(50), "formatted_address" VARCHAR(200), "location_timestamp" DATETIME, "event_geofence_latitude" VARCHAR(15), "event_geofence_longitude" VARCHAR(15), "radius" BIGINT, "geolocation_positioning_type" VARCHAR(15), "last_geolocation_response" VARCHAR(10), "cause" VARCHAR(150), "api_version" VARCHAR(10) NOT NULL, "uri" LONGVARCHAR NOT NULL) +CREATE USER SA PASSWORD "" +GRANT DBA TO SA +SET WRITE_DELAY 10 +SET SCHEMA PUBLIC +INSERT INTO "restcomm_organizations" VALUES('ORafbe225ad37541eba518a74248f0ac4c', 'default.restcomm.com', '2017-04-19 00:00:00.000000000','2017-04-19 00:00:00.000000000', 'active') +INSERT INTO "restcomm_accounts" VALUES('ACae6e420f425248d6a26948c17a9e2acf','2012-04-24 22:51:29.372000000','2012-04-24 22:51:29.372000000','administrator@company.com','Default Administrator Account',NULL,'Full','active','77f8c12cc7b8f8423e5c38b035249166','Administrator','/2012-04-24/Accounts/ACae6e420f425248d6a26948c17a9e2acf','ORafbe225ad37541eba518a74248f0ac4c') +INSERT INTO "restcomm_incoming_phone_numbers" VALUES('PNdd7a0a0248244615978bd5781598e5eb','2013-10-04 17:42:02.500000000','2013-10-04 17:42:02.500000000','This app plays pre-recorded audio file','ACae6e420f425248d6a26948c17a9e2acf','+1234','2012-04-24',FALSE,'/restcomm/demos/hello-play.xml','POST',NULL,'POST',NULL,'POST',NULL,NULL,'POST',NULL,'POST',NULL,'/2012-04-24/Accounts/ACae6e420f425248d6a26948c17a9e2acf/IncomingPhoneNumbers/PNdd7a0a0248244615978bd5781598e5eb',NULL,NULL,NULL,NULL, TRUE,'0.0',NULL,NULL,NULL,NULL,NULL, NULL, NULL, NULL, 'ORafbe225ad37541eba518a74248f0ac4c') +INSERT INTO "restcomm_clients" VALUES('CL3003328d0de04ba68f38de85b732ed56','2013-11-04 16:33:39.248000000','2013-11-04 16:33:39.248000000','ACae6e420f425248d6a26948c17a9e2acf','2012-04-24','bob','bob','1234',1,NULL,'POST',NULL,'POST',NULL,'/2012-04-24/Accounts/ACae6e420f425248d6a26948c17a9e2acf/Clients/CL3003328d0de04ba68f38de85b732ed56',NULL)