diff --git a/restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/SystemExtensionResponse.java b/restcomm/restcomm.commons/src/main/java/org/restcomm/connect/commons/telephony/CreateCallType.java old mode 100644 new mode 100755 similarity index 79% rename from restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/SystemExtensionResponse.java rename to restcomm/restcomm.commons/src/main/java/org/restcomm/connect/commons/telephony/CreateCallType.java index 4df9d6a039..31c9b996a7 --- a/restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/SystemExtensionResponse.java +++ b/restcomm/restcomm.commons/src/main/java/org/restcomm/connect/commons/telephony/CreateCallType.java @@ -18,10 +18,8 @@ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ -/** - * When an Extension returns a SystemReponse, RC will reconfigure itself systemwide - */ -package org.restcomm.connect.extension.api; -public class SystemExtensionResponse extends ExtensionResponse { - //TODO: needs discussion, definition +package org.restcomm.connect.commons.telephony; + +public enum CreateCallType { + CLIENT, PSTN, SIP, USSD } diff --git a/restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/CallRequest.java b/restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/CallRequest.java deleted file mode 100644 index 86db69ceee..0000000000 --- a/restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/CallRequest.java +++ /dev/null @@ -1,58 +0,0 @@ -package org.restcomm.connect.extension.api; - - -import org.restcomm.connect.commons.dao.Sid; - -/** - * Created by gvagenas on 27/09/16. - */ -public class CallRequest { - public enum Type { - CLIENT, PSTN, SIP, USSD - }; - - private final String from; - private final String to; - private final Type type; - private final Sid accountId; - private final boolean isFromApi; - private final boolean parentCallSidExists; - - public CallRequest(String from, String to, Type type, Sid accountId, boolean isFromApi, boolean parentCallSidExists) { - this.from = from; - this.to = to; - this.type = type; - this.accountId = accountId; - this.isFromApi = isFromApi; - this.parentCallSidExists = parentCallSidExists; - } - - public String getFrom() { - return from; - } - - public String getTo() { - return to; - } - - public Type getType() { - return type; - } - - public Sid getAccountId() { - return accountId; - } - - public boolean isFromApi() { - return isFromApi; - } - - public boolean isParentCallSidExists() { - return parentCallSidExists; - } - - @Override - public String toString() { - return "From: "+from+", To: "+to+", Type: "+type.name()+", AccountId: "+accountId+", isFromApi: "+isFromApi+", parentCallSidExists: "+parentCallSidExists; - } -} diff --git a/restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/ExtensionRequest.java b/restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/ExtensionRequest.java index 76231eba0d..fc79185add 100755 --- a/restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/ExtensionRequest.java +++ b/restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/ExtensionRequest.java @@ -19,28 +19,43 @@ * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.restcomm.connect.extension.api; -import org.apache.commons.configuration.Configuration; -public class ExtensionRequest { - private Object payload; - private Configuration configuration; - - public ExtensionRequest() {} - - public Object getObject() { - return payload; +public class ExtensionRequest implements IExtensionRequest{ + private boolean allowed = true; + private String accountSid; + public ExtensionRequest() { + this("", true); + } + public ExtensionRequest(String accountSid, boolean allowed) { + this.accountSid = accountSid; + this.allowed = allowed; } - public void setObject(Object object) { - this.payload = object; + /** + * IExtensionRequest + * @return get accountSid + */ + @Override + public String getAccountSid() { + return this.accountSid; } - public void setConfiguration(Configuration configuration) { - this.configuration = configuration; + /** + * IExtensionRequest + * @return is allowed + */ + @Override + public boolean isAllowed() { + return this.allowed; } - public Configuration getConfiguration() { - return this.configuration; + /** + * IExtensionRequest + * @param is allowed + */ + @Override + public void setAllowed(boolean allowed) { + this.allowed = allowed; } } diff --git a/restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/IExtensionCreateCallRequest.java b/restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/IExtensionCreateCallRequest.java new file mode 100755 index 0000000000..f88ea24199 --- /dev/null +++ b/restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/IExtensionCreateCallRequest.java @@ -0,0 +1,85 @@ +package org.restcomm.connect.extension.api; + +import java.util.ArrayList; +import java.util.Map; + +import org.restcomm.connect.commons.dao.Sid; +import org.restcomm.connect.commons.telephony.CreateCallType; + +public interface IExtensionCreateCallRequest extends IExtensionRequest { + + /** + * @return the from address + */ + String getFrom(); + + /** + * @return the to address + */ + String getTo(); + + /** + * @return the accountId + */ + Sid getAccountId(); + + /** + * @return boolean if is from EP + */ + boolean isFromApi(); + + /** + * @return boolean if this is a child call + */ + boolean isParentCallSidExists(); + + /** + * @return the CreateCallType + */ + CreateCallType getType(); + + /** + * @return the outboundProxy + */ + String getOutboundProxy(); + + /** + * @param outboundProxy the outboundProxy to set + */ + void setOutboundProxy(String outboundProxy); + + /** + * @return the outboundProxyUsername + */ + String getOutboundProxyUsername(); + + /** + * @param outboundProxyUsername the outboundProxyUsername to set + */ + void setOutboundProxyUsername(String outboundProxyUsername); + + /** + * @return the outboundProxyPassword + */ + String getOutboundProxyPassword(); + + /** + * @param outboundProxyPassword the outboundProxyPassword to set + */ + void setOutboundProxyPassword(String outboundProxyPassword); + + /** + * @return the outboundProxyHeaders + */ + Map> getOutboundProxyHeaders(); + + /** + * @param outboundProxyHeaders the outboundProxyHeaders to set + */ + void setOutboundProxyHeaders(Map> outboundProxyHeaders); + + /** + * @return the Request URI + */ + String getRequestURI(); +} diff --git a/restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/NodeExtensionResponse.java b/restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/IExtensionCreateSmsSessionRequest.java old mode 100644 new mode 100755 similarity index 62% rename from restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/NodeExtensionResponse.java rename to restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/IExtensionCreateSmsSessionRequest.java index ed3b2f4965..ad7dd73008 --- a/restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/NodeExtensionResponse.java +++ b/restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/IExtensionCreateSmsSessionRequest.java @@ -18,10 +18,22 @@ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ -/** - * When an Extension returns a NodeReponse, RC will reconfigure the specific RC node it is in - */ package org.restcomm.connect.extension.api; -public class NodeExtensionResponse extends ExtensionResponse { - //TODO: needs discussion, definition + +import org.apache.commons.configuration.Configuration; + +public interface IExtensionCreateSmsSessionRequest extends IExtensionRequest { + /** + * FIXME: potentially we will change this to be specific properties + * rather than a whole Config object + * @param set Configuration object + */ + void setConfiguration(Configuration configuration); + + /** + * FIXME: potentially we will change this to be specific properties + * rather than a whole Config object + * @return the Configuration object + */ + Configuration getConfiguration(); } diff --git a/restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/MessageExtensionResponse.java b/restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/IExtensionRequest.java old mode 100644 new mode 100755 similarity index 73% rename from restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/MessageExtensionResponse.java rename to restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/IExtensionRequest.java index de1b637ff5..0211de62d6 --- a/restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/MessageExtensionResponse.java +++ b/restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/IExtensionRequest.java @@ -18,10 +18,23 @@ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ -/** - * When an Extension returns a MessageReponse, RC will reconfigure the message it will send - */ package org.restcomm.connect.extension.api; -public class MessageExtensionResponse extends ExtensionResponse { - //TODO: needs discussion, definition + +public interface IExtensionRequest { + + /** + * @return the accountId as String + * FIXME: should this be at this level? + */ + String getAccountSid(); + + /** + * @return whether request should proceed + */ + boolean isAllowed(); + + /** + * @param set to allow/restrict request + */ + void setAllowed(boolean allowed); } diff --git a/restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/RestcommExtensionGeneric.java b/restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/RestcommExtensionGeneric.java index 96116be9c6..e2a8a162cd 100644 --- a/restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/RestcommExtensionGeneric.java +++ b/restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/RestcommExtensionGeneric.java @@ -57,14 +57,14 @@ public interface RestcommExtensionGeneric { * and either block/allow it or modify the session before Restcomm process it * @return ExtensionResponse see ExtensionResponse */ - ExtensionResponse preOutboundAction(ExtensionRequest extensionRequest); + ExtensionResponse preOutboundAction(IExtensionRequest extensionRequest); /** * Method that will be executed AFTER the process of an Outbound session * Implement this method so you will be able to check the Outgoing session * and either block or allow or modify the session after Restcomm process it * @return ExtensionResponse see ExtensionResponse */ - ExtensionResponse postOutboundAction(CallRequest callRequest); + ExtensionResponse postOutboundAction(IExtensionRequest extensionRequest); /** * Method that will be executed before the process of an API action, such as DID purchase (but after security checks) diff --git a/restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/SessionExtensionResponse.java b/restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/SessionExtensionResponse.java deleted file mode 100644 index 9d8013a87f..0000000000 --- a/restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/SessionExtensionResponse.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2013, Telestax Inc and individual contributors - * by the @authors tag. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ -/** - * When an Extension returns a SessionReponse, RC will reconfigure the session it is in - */ -package org.restcomm.connect.extension.api; -import org.apache.commons.configuration.Configuration; -public class SessionExtensionResponse extends ExtensionResponse { - //TODO: needs discussion, definition - /** - * The Extension is expected to populate the session specific - * Configuration - */ - public void setConfiguration(Configuration configuration){ - super.setObject(configuration); - } - - /** - * RC expects an Extension to populate Configuration when it returns - * this SessionResponse - * @return Configuration object - */ - public Configuration getConfiguration(){ - return (Configuration) super.getObject(); - } -} diff --git a/restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/TransactionExtensionResponse.java b/restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/TransactionExtensionResponse.java deleted file mode 100644 index c3ac493ab2..0000000000 --- a/restcomm/restcomm.extension.api/src/main/java/org/restcomm/connect/extension/api/TransactionExtensionResponse.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2013, Telestax Inc and individual contributors - * by the @authors tag. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ -/** - * When an Extension returns a TransactionReponse, RC will reconfigure the transaction it - * is in - */ -package org.restcomm.connect.extension.api; -public class TransactionExtensionResponse extends ExtensionResponse { - //TODO: needs discussion, definition -} \ No newline at end of file diff --git a/restcomm/restcomm.extension.controller/src/main/java/org/restcomm/connect/extension/controller/ExtensionController.java b/restcomm/restcomm.extension.controller/src/main/java/org/restcomm/connect/extension/controller/ExtensionController.java index 0668660738..0098482e1d 100644 --- a/restcomm/restcomm.extension.controller/src/main/java/org/restcomm/connect/extension/controller/ExtensionController.java +++ b/restcomm/restcomm.extension.controller/src/main/java/org/restcomm/connect/extension/controller/ExtensionController.java @@ -1,16 +1,10 @@ package org.restcomm.connect.extension.controller; -import org.restcomm.connect.extension.api.ExtensionRequest; import org.restcomm.connect.extension.api.ExtensionResponse; import org.restcomm.connect.extension.api.ExtensionType; -import org.restcomm.connect.extension.api.MessageExtensionResponse; -import org.restcomm.connect.extension.api.NodeExtensionResponse; +import org.restcomm.connect.extension.api.IExtensionRequest; import org.restcomm.connect.extension.api.RestcommExtension; import org.restcomm.connect.extension.api.RestcommExtensionGeneric; -import org.restcomm.connect.extension.api.SessionExtensionResponse; -import org.restcomm.connect.extension.api.SystemExtensionResponse; -import org.restcomm.connect.extension.api.TransactionExtensionResponse; -import org.apache.commons.configuration.Configuration; import org.apache.log4j.Logger; import java.util.List; @@ -89,7 +83,7 @@ public void registerExtension(final RestcommExtensionGeneric extension) { } } - public ExtensionResponse executePreOutboundAction(final ExtensionRequest er, List extensions) { + public ExtensionResponse executePreOutboundAction(final IExtensionRequest ier, List extensions) { //FIXME: if we have more than one extension in chain // and all of them are successful, we only receive the last // extensionResponse @@ -101,7 +95,7 @@ public ExtensionResponse executePreOutboundAction(final ExtensionRequest er, Lis logger.info( extension.getName()+" is enabled="+extension.isEnabled()); } if (extension.isEnabled()) { - response = extension.preOutboundAction(er); + response = extension.preOutboundAction(ier); //fail fast if (!response.isAllowed()){ break; @@ -112,38 +106,14 @@ public ExtensionResponse executePreOutboundAction(final ExtensionRequest er, Lis return response; } - public ExtensionResponse executePostOutboundAction(final Object er, List extensions) { + public ExtensionResponse executePostOutboundAction(Object er, List extensions) { ExtensionResponse response = new ExtensionResponse(); //TODO: implement actual calls return response; } - - //FIXME: there must be a fixed contract between the returned extensions object - // and how the system will reconfigure itself with the type of ExtensionResponse - // for now we will just map SessionExtensionResponse to Configuration object - //FIXME: method signature is too restrictive - public Object handleExtensionResponse(ExtensionResponse response, Configuration configuration){ - //check type of extension - //FIXME: hack to default - Object object = configuration; - if(response instanceof SystemExtensionResponse){ - //TODO:return systemwide level customization behaviour - } - if(response instanceof NodeExtensionResponse){ - //TODO:return node level customization behaviour - } - if(response instanceof SessionExtensionResponse){ - SessionExtensionResponse ser = (SessionExtensionResponse) response; - Configuration config = ser.getConfiguration(); - - object = config; - } - if(response instanceof TransactionExtensionResponse){ - //TODO:return transaction level customization behaviour - } - if(response instanceof MessageExtensionResponse){ - //TODO:return message level customization behaviour - } - return object; + public ExtensionResponse executePostOutboundAction(final IExtensionRequest er, List extensions) { + ExtensionResponse response = new ExtensionResponse(); + //TODO: implement actual calls + return response; } } diff --git a/restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/CallsEndpoint.java b/restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/CallsEndpoint.java index 5e532a61e1..052f4605bd 100644 --- a/restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/CallsEndpoint.java +++ b/restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/CallsEndpoint.java @@ -21,17 +21,20 @@ import akka.actor.ActorRef; import akka.util.Timeout; + import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.i18n.phonenumbers.NumberParseException; import com.google.i18n.phonenumbers.PhoneNumberUtil; import com.google.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberFormat; import com.thoughtworks.xstream.XStream; + import org.apache.commons.configuration.Configuration; import org.restcomm.connect.commons.amazonS3.RecordingSecurityLevel; import org.restcomm.connect.commons.annotations.concurrency.NotThreadSafe; import org.restcomm.connect.commons.configuration.RestcommConfiguration; import org.restcomm.connect.commons.dao.Sid; +import org.restcomm.connect.commons.telephony.CreateCallType; import org.restcomm.connect.dao.AccountsDao; import org.restcomm.connect.dao.CallDetailRecordsDao; import org.restcomm.connect.dao.DaoManager; @@ -59,6 +62,7 @@ import org.restcomm.connect.telephony.api.GetCallInfo; import org.restcomm.connect.telephony.api.Hangup; import org.restcomm.connect.telephony.api.UpdateCallScript; + import scala.concurrent.Await; import scala.concurrent.Future; import scala.concurrent.duration.Duration; @@ -71,6 +75,7 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; + import java.net.URI; import java.net.URL; import java.text.ParseException; @@ -379,13 +384,13 @@ protected Response putCall(final String accountSid, final MultivaluedMap future = (Future) ask(ussdCallManager, create, expires); diff --git a/restcomm/restcomm.interpreter/src/main/java/org/restcomm/connect/interpreter/SubVoiceInterpreter.java b/restcomm/restcomm.interpreter/src/main/java/org/restcomm/connect/interpreter/SubVoiceInterpreter.java index fda7e7d1d7..6625e2a238 100644 --- a/restcomm/restcomm.interpreter/src/main/java/org/restcomm/connect/interpreter/SubVoiceInterpreter.java +++ b/restcomm/restcomm.interpreter/src/main/java/org/restcomm/connect/interpreter/SubVoiceInterpreter.java @@ -25,6 +25,7 @@ import akka.actor.UntypedActorContext; import akka.event.Logging; import akka.event.LoggingAdapter; + import org.apache.commons.configuration.Configuration; import org.apache.http.HttpStatus; import org.apache.http.NameValuePair; @@ -37,6 +38,7 @@ import org.restcomm.connect.commons.fsm.FiniteStateMachine; import org.restcomm.connect.commons.fsm.State; import org.restcomm.connect.commons.fsm.Transition; +import org.restcomm.connect.commons.telephony.CreateCallType; import org.restcomm.connect.dao.CallDetailRecordsDao; import org.restcomm.connect.dao.DaoManager; import org.restcomm.connect.dao.NotificationsDao; @@ -57,12 +59,13 @@ import org.restcomm.connect.telephony.api.CallResponse; import org.restcomm.connect.telephony.api.CallStateChanged; import org.restcomm.connect.telephony.api.Cancel; -import org.restcomm.connect.telephony.api.CreateCall; + import org.restcomm.connect.telephony.api.DestroyCall; import org.restcomm.connect.telephony.api.Reject; import org.restcomm.connect.tts.api.SpeechSynthesizerResponse; import javax.servlet.sip.SipServletResponse; + import java.io.IOException; import java.net.URI; import java.util.ArrayList; @@ -434,7 +437,7 @@ List parameters() { parameters.add(new BasicNameValuePair("ForwardedFrom", forwardedFrom)); // Adding SIP OUT Headers and SipCallId for // https://bitbucket.org/telestax/telscale-restcomm/issue/132/implement-twilio-sip-out - if (CreateCall.Type.SIP == callInfo.type()) { + if (CreateCallType.SIP == callInfo.type()) { SipServletResponse lastResponse = callInfo.lastResponse(); if (lastResponse != null) { final int statusCode = lastResponse.getStatus(); diff --git a/restcomm/restcomm.interpreter/src/main/java/org/restcomm/connect/interpreter/VoiceInterpreter.java b/restcomm/restcomm.interpreter/src/main/java/org/restcomm/connect/interpreter/VoiceInterpreter.java index 520ea6109a..5bc71c75ba 100644 --- a/restcomm/restcomm.interpreter/src/main/java/org/restcomm/connect/interpreter/VoiceInterpreter.java +++ b/restcomm/restcomm.interpreter/src/main/java/org/restcomm/connect/interpreter/VoiceInterpreter.java @@ -26,6 +26,7 @@ import akka.event.LoggingAdapter; import akka.pattern.AskTimeoutException; import akka.util.Timeout; + import org.apache.commons.configuration.Configuration; import org.apache.http.HttpStatus; import org.apache.http.NameValuePair; @@ -46,6 +47,7 @@ import org.restcomm.connect.commons.fsm.TransitionRollbackException; import org.restcomm.connect.commons.patterns.Observe; import org.restcomm.connect.commons.patterns.StopObserving; +import org.restcomm.connect.commons.telephony.CreateCallType; import org.restcomm.connect.commons.util.UriUtils; import org.restcomm.connect.dao.CallDetailRecordsDao; import org.restcomm.connect.dao.DaoManager; @@ -106,6 +108,7 @@ import org.restcomm.connect.telephony.api.StopBridge; import org.restcomm.connect.telephony.api.StopConference; import org.restcomm.connect.tts.api.SpeechSynthesizerResponse; + import scala.concurrent.Await; import scala.concurrent.Future; import scala.concurrent.duration.Duration; @@ -114,6 +117,7 @@ import javax.servlet.sip.SipServletRequest; import javax.servlet.sip.SipServletResponse; import javax.servlet.sip.SipSession; + import java.io.IOException; import java.math.BigDecimal; import java.net.MalformedURLException; @@ -1472,7 +1476,7 @@ List parameters() { } // logger.info("Type " + callInfo.type()); SipServletResponse lastResponse = callInfo.lastResponse(); - if (CreateCall.Type.SIP == callInfo.type()) { + if (CreateCallType.SIP == callInfo.type()) { // Adding SIP OUT Headers and SipCallId for // https://bitbucket.org/telestax/telscale-restcomm/issue/132/implement-twilio-sip-out // logger.info("lastResponse " + lastResponse); @@ -2068,26 +2072,26 @@ else if (CallManagerResponse.class.equals(klass) && !((CallManagerResponse)messa if (Nouns.client.equals(child.name())) { if (call != null && callInfo != null) { create = new CreateCall(e164(callerId(verb)), e164(child.text()), null, null, callInfo.isFromApi(), timeout(verb), - CreateCall.Type.CLIENT, accountId, callInfo.sid(), statusCallback, statusCallbackMethod, statusCallbackEvent); + CreateCallType.CLIENT, accountId, callInfo.sid(), statusCallback, statusCallbackMethod, statusCallbackEvent); } else { create = new CreateCall(e164(callerId(verb)), e164(child.text()), null, null, false, timeout(verb), - CreateCall.Type.CLIENT, accountId, null, statusCallback, statusCallbackMethod, statusCallbackEvent); + CreateCallType.CLIENT, accountId, null, statusCallback, statusCallbackMethod, statusCallbackEvent); } } else if (Nouns.number.equals(child.name())) { if (call != null && callInfo != null) { create = new CreateCall(e164(callerId(verb)), e164(child.text()), null, null, callInfo.isFromApi(), timeout(verb), - CreateCall.Type.PSTN, accountId, callInfo.sid(), statusCallback, statusCallbackMethod, statusCallbackEvent); + CreateCallType.PSTN, accountId, callInfo.sid(), statusCallback, statusCallbackMethod, statusCallbackEvent); } else { create = new CreateCall(e164(callerId(verb)), e164(child.text()), null, null, false, timeout(verb), - CreateCall.Type.PSTN, accountId, null, statusCallback, statusCallbackMethod, statusCallbackEvent); + CreateCallType.PSTN, accountId, null, statusCallback, statusCallbackMethod, statusCallbackEvent); } } else if (Nouns.uri.equals(child.name())) { if (call != null && callInfo != null) { create = new CreateCall(e164(callerId(verb)), e164(child.text()), null, null, callInfo.isFromApi(), timeout(verb), - CreateCall.Type.SIP, accountId, callInfo.sid(), statusCallback, statusCallbackMethod, statusCallbackEvent); + CreateCallType.SIP, accountId, callInfo.sid(), statusCallback, statusCallbackMethod, statusCallbackEvent); } else { create = new CreateCall(e164(callerId(verb)), e164(child.text()), null, null, false, timeout(verb), - CreateCall.Type.SIP, accountId, null, statusCallback, statusCallbackMethod, statusCallbackEvent); + CreateCallType.SIP, accountId, null, statusCallback, statusCallbackMethod, statusCallbackEvent); } } else if (Nouns.SIP.equals(child.name())) { // https://bitbucket.org/telestax/telscale-restcomm/issue/132/implement-twilio-sip-out @@ -2112,10 +2116,10 @@ else if (CallManagerResponse.class.equals(klass) && !((CallManagerResponse)messa } if (call != null && callInfo != null) { create = new CreateCall(e164(callerId(verb)), e164(child.text()), username, password, false, timeout(verb), - CreateCall.Type.SIP, accountId, callInfo.sid(), statusCallback, statusCallbackMethod, statusCallbackEvent); + CreateCallType.SIP, accountId, callInfo.sid(), statusCallback, statusCallbackMethod, statusCallbackEvent); } else { create = new CreateCall(e164(callerId(verb)), e164(child.text()), username, password, false, timeout(verb), - CreateCall.Type.SIP, accountId, null, statusCallback, statusCallbackMethod, statusCallbackEvent); + CreateCallType.SIP, accountId, null, statusCallback, statusCallbackMethod, statusCallbackEvent); } } callManager.tell(create, source); diff --git a/restcomm/restcomm.sms.api/pom.xml b/restcomm/restcomm.sms.api/pom.xml index 10f1e11f94..bd8c60fded 100644 --- a/restcomm/restcomm.sms.api/pom.xml +++ b/restcomm/restcomm.sms.api/pom.xml @@ -17,6 +17,11 @@ restcomm-connect.commons ${project.version} - + + org.restcomm + restcomm-connect.extension.api + ${project.version} + provided + diff --git a/restcomm/restcomm.sms.api/src/main/java/org/restcomm/connect/sms/api/CreateSmsSession.java b/restcomm/restcomm.sms.api/src/main/java/org/restcomm/connect/sms/api/CreateSmsSession.java index e032c03c1f..726d5ed514 100644 --- a/restcomm/restcomm.sms.api/src/main/java/org/restcomm/connect/sms/api/CreateSmsSession.java +++ b/restcomm/restcomm.sms.api/src/main/java/org/restcomm/connect/sms/api/CreateSmsSession.java @@ -19,17 +19,20 @@ */ package org.restcomm.connect.sms.api; +import org.apache.commons.configuration.Configuration; import org.restcomm.connect.commons.annotations.concurrency.Immutable; - +import org.restcomm.connect.extension.api.IExtensionCreateSmsSessionRequest; /** * @author quintana.thomas@gmail.com (Thomas Quintana) */ @Immutable -public final class CreateSmsSession { +public final class CreateSmsSession implements IExtensionCreateSmsSessionRequest { private final String from; private final String to; private final String accountSid; private final boolean isFromApi; + private Configuration configuration; + private boolean allowed = true; //This will be used to create SmsSession from @@ -52,10 +55,6 @@ public String getTo() { return to; } - public String getAccountSid() { - return accountSid; - } - public boolean isFromApi() { return isFromApi; } @@ -64,4 +63,49 @@ public boolean isFromApi() { public String toString() { return "From: "+from+" , To: "+to+" , AccountSid: "+accountSid+" , isFromApi: "+isFromApi; } + + /** + * IExtensionRequest + * @return accountSid + */ + @Override + public String getAccountSid() { + return accountSid; + } + + /** + * IExtensionRequest + * @return if allowed + */ + @Override + public boolean isAllowed() { + return this.allowed; + } + + /** + * IExtensionRequest + * @param set allowed + */ + @Override + public void setAllowed(boolean allowed) { + this.allowed = allowed; + } + + /** + * IExtensionCreateSmsSessionRequest + * @param set Configuration object + */ + @Override + public void setConfiguration(Configuration configuration) { + this.configuration = configuration; + } + + /** + * IExtensionCreateSmsSessionRequest + * @return Configuration object + */ + @Override + public Configuration getConfiguration() { + return this.configuration; + } } diff --git a/restcomm/restcomm.sms/src/main/java/org/restcomm/connect/sms/SmsService.java b/restcomm/restcomm.sms/src/main/java/org/restcomm/connect/sms/SmsService.java index 86ff8949a9..49622b5027 100644 --- a/restcomm/restcomm.sms/src/main/java/org/restcomm/connect/sms/SmsService.java +++ b/restcomm/restcomm.sms/src/main/java/org/restcomm/connect/sms/SmsService.java @@ -27,8 +27,10 @@ import akka.actor.UntypedActorFactory; import akka.event.Logging; import akka.event.LoggingAdapter; + import com.google.i18n.phonenumbers.PhoneNumberUtil; import com.google.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberFormat; + import org.apache.commons.configuration.Configuration; import org.joda.time.DateTime; import org.restcomm.connect.commons.dao.Sid; @@ -47,9 +49,8 @@ import org.restcomm.connect.dao.entities.SmsMessage; import org.restcomm.connect.dao.entities.SmsMessage.Direction; import org.restcomm.connect.dao.entities.SmsMessage.Status; -import org.restcomm.connect.extension.api.ExtensionResponse; -import org.restcomm.connect.extension.api.ExtensionRequest; import org.restcomm.connect.extension.api.ExtensionType; +import org.restcomm.connect.extension.api.IExtensionCreateSmsSessionRequest; import org.restcomm.connect.extension.api.RestcommExtensionException; import org.restcomm.connect.extension.api.RestcommExtensionGeneric; import org.restcomm.connect.extension.controller.ExtensionController; @@ -61,11 +62,9 @@ import org.restcomm.connect.sms.api.SmsServiceResponse; import org.restcomm.connect.sms.api.SmsSessionAttribute; import org.restcomm.connect.sms.api.SmsSessionRequest; - import org.restcomm.connect.telephony.api.TextMessage; import org.restcomm.connect.telephony.api.util.B2BUAHelper; import org.restcomm.connect.telephony.api.util.CallControlHelper; - import org.restcomm.smpp.parameter.TlvSet; import javax.servlet.ServletConfig; @@ -340,19 +339,11 @@ public void onReceive(final Object message) throws Exception { final ActorRef sender = sender(); ExtensionController ec = ExtensionController.getInstance(); if (CreateSmsSession.class.equals(klass)) { - //retrieve extension object - //FIXME:we need a real interface here rather than amending a preexisting request interface - ExtensionRequest er = new ExtensionRequest(); - er.setObject(message); - er.setConfiguration(this.configuration); - - ExtensionResponse extensionResponse = ec.executePreOutboundAction(er, this.extensions); - if (extensionResponse.isAllowed()) { - //pass in response object to sms session - Object obj = ec.handleExtensionResponse(extensionResponse, this.configuration); - //FIXME:not all instances of extensions should modify - //a session configuration, we should do checks here - final ActorRef session = session((Configuration)obj); + IExtensionCreateSmsSessionRequest ier = (CreateSmsSession)message; + ier.setConfiguration(this.configuration); + ec.executePreOutboundAction(ier, this.extensions); + if (ier.isAllowed()) { + final ActorRef session = session(ier.getConfiguration()); final SmsServiceResponse response = new SmsServiceResponse(session); sender.tell(response, self); } else { diff --git a/restcomm/restcomm.sms/src/main/java/org/restcomm/connect/sms/smpp/SmppMessageHandler.java b/restcomm/restcomm.sms/src/main/java/org/restcomm/connect/sms/smpp/SmppMessageHandler.java index a434af6ad7..32f1a8d7ef 100644 --- a/restcomm/restcomm.sms/src/main/java/org/restcomm/connect/sms/smpp/SmppMessageHandler.java +++ b/restcomm/restcomm.sms/src/main/java/org/restcomm/connect/sms/smpp/SmppMessageHandler.java @@ -8,6 +8,7 @@ import akka.actor.UntypedActorFactory; import akka.event.Logging; import akka.event.LoggingAdapter; + import com.cloudhopper.commons.charset.CharsetUtil; import com.cloudhopper.smpp.pdu.SubmitSm; import com.cloudhopper.smpp.type.Address; @@ -18,6 +19,7 @@ import com.cloudhopper.smpp.type.UnrecoverablePduException; import com.cloudhopper.smpp.tlv.Tlv; import com.google.i18n.phonenumbers.PhoneNumberUtil; + import org.apache.commons.configuration.Configuration; import org.restcomm.connect.commons.dao.Sid; import org.restcomm.connect.commons.util.UriUtils; @@ -27,9 +29,10 @@ import org.restcomm.connect.dao.IncomingPhoneNumbersDao; import org.restcomm.connect.dao.entities.Application; import org.restcomm.connect.dao.entities.IncomingPhoneNumber; -import org.restcomm.connect.extension.api.ExtensionRequest; -import org.restcomm.connect.extension.api.ExtensionResponse; +//import org.restcomm.connect.extension.api.ExtensionRequest; +//import org.restcomm.connect.extension.api.ExtensionResponse; import org.restcomm.connect.extension.api.ExtensionType; +import org.restcomm.connect.extension.api.IExtensionCreateSmsSessionRequest; import org.restcomm.connect.extension.api.RestcommExtensionException; import org.restcomm.connect.extension.api.RestcommExtensionGeneric; import org.restcomm.connect.extension.controller.ExtensionController; @@ -45,6 +48,7 @@ import javax.servlet.sip.SipFactory; import javax.servlet.sip.SipServlet; import javax.servlet.sip.SipURI; + import java.io.IOException; import java.net.URI; import java.util.List; @@ -92,13 +96,11 @@ public void onReceive(Object message) throws Exception { } outbound((SmppOutboundMessageEntity) message); } else if (message instanceof CreateSmsSession) { - ExtensionRequest er = new ExtensionRequest(); - er.setObject(message); - er.setConfiguration(this.configuration); - ExtensionResponse extensionResponse = ec.executePreOutboundAction(er, this.extensions); - if (extensionResponse.isAllowed()) { - Object obj = ec.handleExtensionResponse(extensionResponse, this.configuration); - final ActorRef session = session((Configuration)obj); + IExtensionCreateSmsSessionRequest ier = (CreateSmsSession)message; + ier.setConfiguration(this.configuration); + ec.executePreOutboundAction(ier, this.extensions); + if (ier.isAllowed()) { + final ActorRef session = session(ier.getConfiguration()); final SmsServiceResponse response = new SmsServiceResponse(session); sender.tell(response, self); } else { diff --git a/restcomm/restcomm.telephony.api/pom.xml b/restcomm/restcomm.telephony.api/pom.xml index ca287f7f45..3a7c9e9987 100644 --- a/restcomm/restcomm.telephony.api/pom.xml +++ b/restcomm/restcomm.telephony.api/pom.xml @@ -35,7 +35,12 @@ ${project.version} provided - + + org.restcomm + restcomm-connect.extension.api + ${project.version} + provided + org.restcomm restcomm-connect.dao diff --git a/restcomm/restcomm.telephony.api/src/main/java/org/restcomm/connect/telephony/api/CallInfo.java b/restcomm/restcomm.telephony.api/src/main/java/org/restcomm/connect/telephony/api/CallInfo.java index 156c569984..ccf8fcf13f 100644 --- a/restcomm/restcomm.telephony.api/src/main/java/org/restcomm/connect/telephony/api/CallInfo.java +++ b/restcomm/restcomm.telephony.api/src/main/java/org/restcomm/connect/telephony/api/CallInfo.java @@ -25,6 +25,7 @@ import org.joda.time.DateTime; import org.restcomm.connect.commons.annotations.concurrency.Immutable; import org.restcomm.connect.commons.dao.Sid; +import org.restcomm.connect.commons.telephony.CreateCallType; /** * @author quintana.thomas@gmail.com (Thomas Quintana) @@ -34,7 +35,7 @@ public final class CallInfo { private final Sid sid; private CallStateChanged.State state; - private final CreateCall.Type type; + private final CreateCallType type; private final String direction; private final DateTime dateCreated; private final DateTime dateConUpdated; @@ -48,7 +49,7 @@ public final class CallInfo { private boolean muted; private boolean isFromApi; - public CallInfo(final Sid sid, final CallStateChanged.State state, final CreateCall.Type type, final String direction, + public CallInfo(final Sid sid, final CallStateChanged.State state, final CreateCallType type, final String direction, final DateTime dateCreated, final String forwardedFrom, final String fromName, final String from, final String to, final SipServletRequest invite, final SipServletResponse lastResponse, final boolean webrtc, final boolean muted, final boolean isFromApi, final DateTime dateConUpdated) { super(); @@ -81,7 +82,7 @@ public String direction() { return direction; } - public CreateCall.Type type() { + public CreateCallType type() { return type; } diff --git a/restcomm/restcomm.telephony.api/src/main/java/org/restcomm/connect/telephony/api/CreateCall.java b/restcomm/restcomm.telephony.api/src/main/java/org/restcomm/connect/telephony/api/CreateCall.java index 2219cbf5b8..4fb83228f7 100644 --- a/restcomm/restcomm.telephony.api/src/main/java/org/restcomm/connect/telephony/api/CreateCall.java +++ b/restcomm/restcomm.telephony.api/src/main/java/org/restcomm/connect/telephony/api/CreateCall.java @@ -21,9 +21,13 @@ import org.restcomm.connect.commons.annotations.concurrency.Immutable; import org.restcomm.connect.commons.dao.Sid; +import org.restcomm.connect.commons.telephony.CreateCallType; +import org.restcomm.connect.extension.api.IExtensionCreateCallRequest; import java.net.URI; +import java.util.ArrayList; import java.util.List; +import java.util.Map; /** * @author quintana.thomas@gmail.com (Thomas Quintana) @@ -31,28 +35,35 @@ * @author gvagenas@telestax.com */ @Immutable -public final class CreateCall { - public enum Type { - CLIENT, PSTN, SIP, USSD - }; +public final class CreateCall implements IExtensionCreateCallRequest{ private final String from; private final String to; - private final String username; - private final String password; + private String username; + private String password; private final boolean isFromApi; private final int timeout; - private final Type type; + private final CreateCallType callType; private final Sid accountId; private boolean createCDR = true; private final Sid parentCallSid; private final URI statusCallbackUrl; private final String statusCallbackMethod; private final List statusCallbackEvent; + private String outboundProxy; + private Map> outboundProxyHeaders; + private boolean allowed = true; public CreateCall(final String from, final String to, final String username, final String password, - final boolean isFromApi, final int timeout, final Type type, final Sid accountId, final Sid parentCallSid, - final URI statusCallbackUrl, final String statusCallbackMethod, final List statusCallbackEvent) { + final boolean isFromApi, final int timeout, final CreateCallType type, final Sid accountId, final Sid parentCallSid, + final URI statusCallbackUrl, final String statusCallbackMethod, final List statusCallbackEvent + ) { + this(from, to, username, password, isFromApi, timeout, type, accountId, parentCallSid, statusCallbackUrl, statusCallbackMethod, statusCallbackEvent, "", null); + } + public CreateCall(final String from, final String to, final String username, final String password, + final boolean isFromApi, final int timeout, final CreateCallType type, final Sid accountId, final Sid parentCallSid, + final URI statusCallbackUrl, final String statusCallbackMethod, final List statusCallbackEvent, + final String outboundProxy, final Map> outboundProxyHeaders) { super(); this.from = from; this.to = to; @@ -60,12 +71,14 @@ public CreateCall(final String from, final String to, final String username, fin this.password = password; this.isFromApi = isFromApi; this.timeout = timeout; - this.type = type; + this.callType = type; this.accountId = accountId; this.parentCallSid = parentCallSid; this.statusCallbackUrl = statusCallbackUrl; this.statusCallbackMethod = statusCallbackMethod; this.statusCallbackEvent = statusCallbackEvent; + this.outboundProxy = outboundProxy; + this.outboundProxyHeaders = outboundProxyHeaders; } public String from() { @@ -76,16 +89,12 @@ public String to() { return to; } - public boolean isFromApi() { - return isFromApi; - } - public int timeout() { return timeout; } - public Type type() { - return type; + public CreateCallType type() { + return callType; } public Sid accountId() { @@ -95,11 +104,18 @@ public Sid accountId() { public String username() { return username; } + public String setUsername() { + return username; + } public String password() { return password; } + public String setPassword() { + return password; + } + public boolean isCreateCDR() { return createCDR; } @@ -117,4 +133,164 @@ public Sid parentCallSid() { public String statusCallbackMethod() { return statusCallbackMethod; } public List statusCallbackEvent() { return statusCallbackEvent; } + + /** + * IExtensionCreateCallRequest + * @return the outboundProxy + */ + public String getOutboundProxy() { + return outboundProxy; + } + + /** + * IExtensionCreateCallRequest + * @param outboundProxy the outboundProxy to set + */ + public void setOutboundProxy(String outboundProxy) { + this.outboundProxy = outboundProxy; + } + + /** + * IExtensionCreateCallRequest + * the outboundProxyUsername is a facade to the username field + * @return the outboundProxyUsername + */ + public String getOutboundProxyUsername() { + return username; + } + + /** + * IExtensionCreateCallRequest + * the outboundProxyUsername is a facade to the username field + * @param outboundProxyUsername the outboundProxyUsername to set + */ + public void setOutboundProxyUsername(String outboundProxyUsername) { + this.username = outboundProxyUsername; + } + + /** + * IExtensionCreateCallRequest + * the outboundProxyPassword is a facade to the password field + * @return the outboundProxyPassword + */ + public String getOutboundProxyPassword() { + return password; + } + + /** + * IExtensionCreateCallRequest + * the outboundProxyPassword is a facade to the password field + * @param outboundProxyPassword the outboundProxyPassword to set + */ + public void setOutboundProxyPassword(String outboundProxyPassword) { + this.password = outboundProxyPassword; + } + + /** + * IExtensionCreateCallRequest + * @return the outboundProxyHeaders + */ + public Map> getOutboundProxyHeaders() { + return outboundProxyHeaders; + } + + /** + * IExtensionCreateCallRequest + * @param outboundProxyHeaders the outboundProxyHeaders to set + */ + public void setOutboundProxyHeaders(Map> outboundProxyHeaders) { + this.outboundProxyHeaders = outboundProxyHeaders; + } + + /** + * IExtensionCreateCallRequest + * @return from address + */ + public String getFrom() { + return from; + } + + /** + * IExtensionCreateCallRequest + * @return to address + */ + public String getTo() { + return to; + } + + /** + * IExtensionCreateCallRequest + * @return accountId + */ + public Sid getAccountId() { + return accountId; + } + + /** + * IExtensionCreateCallRequest + * @return boolean fromApi + */ + @Override + public boolean isFromApi() { + return isFromApi; + } + + /** + * IExtensionCreateCallRequest + * @return boolean is child call + */ + @Override + public boolean isParentCallSidExists() { + return parentCallSid != null; + } + + /** + * IExtensionCreateCallRequest + * @return the CreateCallType + */ + @Override + public CreateCallType getType() { + return callType; + } + + /** + * IExtensionCreateCallRequest + * @return the CreateCallType + */ + @Override + public String getRequestURI() { + return this.to; + } + + /** + * IExtensionRequest + * @return accountSid + */ + @Override + public String getAccountSid() { + return this.accountId.toString(); + } + + /** + * IExtensionRequest + * @return is allowed + */ + @Override + public boolean isAllowed() { + return this.allowed; + } + + /** + * IExtensionRequest + * @param set allowed + */ + @Override + public void setAllowed(boolean allowed) { + this.allowed = allowed; + } + + @Override + public String toString() { + return "From: "+from+", To: "+to+", Type: "+callType.name()+", AccountId: "+accountId+", isFromApi: "+isFromApi+", parentCallSidExists: "+isParentCallSidExists(); + } } diff --git a/restcomm/restcomm.telephony.api/src/main/java/org/restcomm/connect/telephony/api/InitializeOutbound.java b/restcomm/restcomm.telephony.api/src/main/java/org/restcomm/connect/telephony/api/InitializeOutbound.java index 8bb768e5c2..4a28a101b4 100644 --- a/restcomm/restcomm.telephony.api/src/main/java/org/restcomm/connect/telephony/api/InitializeOutbound.java +++ b/restcomm/restcomm.telephony.api/src/main/java/org/restcomm/connect/telephony/api/InitializeOutbound.java @@ -24,6 +24,7 @@ import org.restcomm.connect.commons.annotations.concurrency.Immutable; import org.restcomm.connect.dao.DaoManager; import org.restcomm.connect.commons.dao.Sid; +import org.restcomm.connect.commons.telephony.CreateCallType; /** * @author quintana.thomas@gmail.com (Thomas Quintana) @@ -43,7 +44,7 @@ public final class InitializeOutbound { private final boolean isFromApi; private final String apiVersion; private final Sid accountId; - private final CreateCall.Type type; + private final CreateCallType type; private final DaoManager daoManager; private Sid parentCallSid; private final boolean webrtc; @@ -55,7 +56,7 @@ public final class InitializeOutbound { public InitializeOutbound(final String name, final SipURI from, final SipURI to, final String username, final String password, final long timeout, final boolean isFromApi, final String apiVersion, - final Sid accountId, final CreateCall.Type type, final DaoManager daoManager, final boolean webrtc, + final Sid accountId, final CreateCallType type, final DaoManager daoManager, final boolean webrtc, final boolean outboundToIms, final String imsProxyAddress, final int imsProxyPort) { this(name, from, to, username, password, timeout, isFromApi, apiVersion, accountId, type, daoManager, webrtc); this.outboundToIms = outboundToIms; @@ -65,7 +66,7 @@ public InitializeOutbound(final String name, final SipURI from, final SipURI to, public InitializeOutbound(final String name, final SipURI from, final SipURI to, final String username, final String password, final long timeout, final boolean isFromApi, final String apiVersion, - final Sid accountId, final CreateCall.Type type, final DaoManager daoManager, final boolean webrtc) { + final Sid accountId, final CreateCallType type, final DaoManager daoManager, final boolean webrtc) { super(); this.name = name; this.from = from; @@ -118,7 +119,7 @@ public String password() { return password; } - public CreateCall.Type type() { + public CreateCallType type() { return type; } diff --git a/restcomm/restcomm.telephony/pom.xml b/restcomm/restcomm.telephony/pom.xml index 5f65a86159..fbed976910 100644 --- a/restcomm/restcomm.telephony/pom.xml +++ b/restcomm/restcomm.telephony/pom.xml @@ -80,7 +80,12 @@ ${project.version} provided - + + org.restcomm + restcomm-connect.extension.api + ${project.version} + provided + org.restcomm restcomm-connect.dao 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 7f19760557..678a557336 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 @@ -28,6 +28,7 @@ import akka.actor.UntypedActorFactory; import akka.event.Logging; import akka.event.LoggingAdapter; + import org.apache.commons.configuration.Configuration; import org.apache.http.NameValuePair; import org.apache.http.message.BasicNameValuePair; @@ -49,6 +50,7 @@ import org.restcomm.connect.commons.patterns.Observe; import org.restcomm.connect.commons.patterns.Observing; import org.restcomm.connect.commons.patterns.StopObserving; +import org.restcomm.connect.commons.telephony.CreateCallType; import org.restcomm.connect.commons.util.SdpUtils; import org.restcomm.connect.dao.CallDetailRecordsDao; import org.restcomm.connect.dao.DaoManager; @@ -86,7 +88,6 @@ import org.restcomm.connect.telephony.api.ChangeCallDirection; import org.restcomm.connect.telephony.api.ConferenceInfo; import org.restcomm.connect.telephony.api.ConferenceResponse; -import org.restcomm.connect.telephony.api.CreateCall; import org.restcomm.connect.telephony.api.Dial; import org.restcomm.connect.telephony.api.GetCallInfo; import org.restcomm.connect.telephony.api.GetCallObservers; @@ -94,6 +95,7 @@ import org.restcomm.connect.telephony.api.InitializeOutbound; import org.restcomm.connect.telephony.api.Reject; import org.restcomm.connect.telephony.api.RemoveParticipant; + import scala.concurrent.duration.Duration; import javax.sdp.SdpException; @@ -111,6 +113,7 @@ import javax.sip.header.RecordRouteHeader; import javax.sip.header.RouteHeader; import javax.sip.message.Response; + import java.io.IOException; import java.math.BigDecimal; import java.net.InetAddress; @@ -189,10 +192,13 @@ public final class Call extends UntypedActor { private SipURI from; private javax.servlet.sip.URI to; // custom headers for SIP Out https://bitbucket.org/telestax/telscale-restcomm/issue/132/implement-twilio-sip-out - private Map headers; + //headers defined in rcml + private Map rcmlHeaders; + //headers populated by extension to modify existing headers and add new headers + private Map> extensionHeaders; private String username; private String password; - private CreateCall.Type type; + private CreateCallType type; private long timeout; private SipServletRequest invite; private SipServletRequest inDialogInvite; @@ -281,7 +287,14 @@ public String toString() { }; public Call(final SipFactory factory, final ActorRef mediaSessionController, final Configuration configuration, - final URI statusCallback, final String statusCallbackMethod, final List statusCallbackEvent) { + final URI statusCallback, final String statusCallbackMethod, final List statusCallbackEvent) { + this(factory, mediaSessionController, configuration, statusCallback, statusCallbackMethod, + statusCallbackEvent, null); + } + + public Call(final SipFactory factory, final ActorRef mediaSessionController, final Configuration configuration, + final URI statusCallback, final String statusCallbackMethod, final List statusCallbackEvent, Map> headers) + { super(); final ActorRef source = self(); this.system = context().system(); @@ -291,6 +304,12 @@ public Call(final SipFactory factory, final ActorRef mediaSessionController, fin if (statusCallback != null) { downloader = downloader(); } + + this.extensionHeaders = new HashMap>(); + if(headers != null){ + this.extensionHeaders = headers; + } + // States for the FSM this.uninitialized = new State("uninitialized", null, null); this.initializing = new State("initializing", new Initializing(source), null); @@ -818,10 +837,11 @@ public void execute(Object message) throws Exception { imsProxyAddress = request.getImsProxyAddress(); imsProxyPort = request.getImsProxyPort(); String toHeaderString = to.toString(); + rcmlHeaders = new HashMap(); if (toHeaderString.indexOf('?') != -1) { // custom headers parsing for SIP Out // https://bitbucket.org/telestax/telscale-restcomm/issue/132/implement-twilio-sip-out - headers = new HashMap(); + // we keep only the to URI without the headers to = (SipURI) factory.createURI(toHeaderString.substring(0, toHeaderString.lastIndexOf('?'))); String headersString = toHeaderString.substring(toHeaderString.lastIndexOf('?') + 1); @@ -830,7 +850,7 @@ public void execute(Object message) throws Exception { String headerNameValue = tokenizer.nextToken(); String headerName = headerNameValue.substring(0, headerNameValue.lastIndexOf('=')); String headerValue = headerNameValue.substring(headerNameValue.lastIndexOf('=') + 1); - headers.put(headerName, headerValue); + rcmlHeaders.put(headerName, headerValue); } } timeout = request.timeout(); @@ -944,19 +964,14 @@ public void execute(Object message) throws Exception { if(userAgent!=null){ invite.setHeader("User-Agent", userAgent); } + addCustomHeadersToMap(rcmlHeaders); + // adding custom headers for SIP Out + // https://bitbucket.org/telestax/telscale-restcomm/issue/132/implement-twilio-sip-out + addHeadersToMessage(invite, rcmlHeaders, "X-"); + + //the extension headers will override any headers + addHeadersToMessage(invite, extensionHeaders); - if (headers != null) { - // adding custom headers for SIP Out - // https://bitbucket.org/telestax/telscale-restcomm/issue/132/implement-twilio-sip-out - Set> entrySet = headers.entrySet(); - for (Map.Entry entry : entrySet) { - invite.addHeader("X-" + entry.getKey(), entry.getValue()); - } - } - addCustomHeaders(invite); -// invite.addHeader("X-RestComm-ApiVersion", apiVersion); -// invite.addHeader("X-RestComm-AccountSid", accountId.toString()); -// invite.addHeader("X-RestComm-CallSid", id.toString()); final SipSession session = invite.getSession(); session.setHandler("CallManager"); // Issue: https://telestax.atlassian.net/browse/RESTCOMM-608 @@ -964,7 +979,7 @@ public void execute(Object message) throws Exception { if (logger.isInfoEnabled()) logger.info("bypassLoadBalancer is set to: "+RestcommConfiguration.getInstance().getMain().getBypassLbForClients()); if (RestcommConfiguration.getInstance().getMain().getBypassLbForClients()) { - if (type.equals(CreateCall.Type.CLIENT) || type.equals(CreateCall.Type.SIP)) { + if (type.equals(CreateCallType.CLIENT) || type.equals(CreateCallType.SIP)) { ((SipSessionExt) session).setBypassLoadBalancer(true); ((SipSessionExt) session).setBypassProxy(true); } @@ -986,6 +1001,95 @@ public void execute(Object message) throws Exception { context.setReceiveTimeout(Duration.create(timeout, TimeUnit.SECONDS)); executeStatusCallback(CallbackState.INITIATED); } + + /** + * addCustomHeadersToMap + */ + private void addCustomHeadersToMap(Map headers) { + if (apiVersion != null) + headers.put("RestComm-ApiVersion", apiVersion); + if (accountId != null) + headers.put("RestComm-AccountSid", accountId.toString()); + headers.put("RestComm-CallSid", instanceId+"-"+id.toString()); + } + + //TODO: put this in a central place + private void addHeadersToMessage(SipServletRequest message, Map headers, String keyPrepend) { + try { + for (Map.Entry entry : headers.entrySet()) { + String headerName = keyPrepend + entry.getKey(); + message.addHeader(headerName , entry.getValue()); + } + } catch (IllegalArgumentException iae) { + if(logger.isErrorEnabled()) { + logger.error("Exception while setting message header: "+iae.getMessage()); + } + } + } + + /** + * Replace headers + * @param SipServletRequest message + * @param Map > headers + */ + private void addHeadersToMessage(SipServletRequest message, Map > headers) { + + if(headers!=null) { + for (Map.Entry> entry : headers.entrySet()) { + //check if header exists + String headerName = entry.getKey(); + + StringBuilder sb = new StringBuilder(); + if(entry.getValue() instanceof ArrayList){ + for(String pair : entry.getValue()){ + sb.append(";").append(pair); + } + } + if(logger.isDebugEnabled()) { + logger.debug("headerName="+headerName+" headerVal="+message.getHeader(headerName)+" concatValue="+sb.toString()); + } + if(!headerName.equalsIgnoreCase("Request-URI")){ + try { + String headerVal = message.getHeader(headerName); + if(headerVal!=null && !headerVal.isEmpty()) { + message.setHeader(headerName , headerVal+sb.toString()); + }else{ + message.addHeader(headerName , sb.toString()); + } + } catch (IllegalArgumentException iae) { + if(logger.isErrorEnabled()) { + logger.error("Exception while setting message header: "+iae.getMessage()); + } + } + }else{ + //handle Request-URI + javax.servlet.sip.URI reqURI = message.getRequestURI(); + if(logger.isDebugEnabled()) { + logger.debug("ReqURI="+reqURI.toString()+" msgReqURI="+message.getRequestURI()); + } + for(String keyValPair :entry.getValue()){ + String parName = ""; + String parVal = ""; + int equalsPos = keyValPair.indexOf("="); + parName = keyValPair.substring(0, equalsPos); + parVal = keyValPair.substring(equalsPos+1); + reqURI.setParameter(parName, parVal); + if(logger.isDebugEnabled()) { + logger.debug("ReqURI pars ="+parName+"="+parVal+" equalsPos="+equalsPos+" keyValPair="+keyValPair); + } + } + + message.setRequestURI(reqURI); + if(logger.isDebugEnabled()) { + logger.debug("ReqURI="+reqURI.toString()+" msgReqURI="+message.getRequestURI()); + } + } + if(logger.isDebugEnabled()) { + logger.debug("headerName="+headerName+" headerVal="+message.getHeader(headerName)); + } + } + } + } } private final class Ringing extends AbstractAction { diff --git a/restcomm/restcomm.telephony/src/main/java/org/restcomm/connect/telephony/CallManager.java b/restcomm/restcomm.telephony/src/main/java/org/restcomm/connect/telephony/CallManager.java index 9eff90b358..256bb836cb 100644 --- a/restcomm/restcomm.telephony/src/main/java/org/restcomm/connect/telephony/CallManager.java +++ b/restcomm/restcomm.telephony/src/main/java/org/restcomm/connect/telephony/CallManager.java @@ -42,6 +42,7 @@ import org.restcomm.connect.commons.configuration.RestcommConfiguration; import org.restcomm.connect.commons.dao.Sid; import org.restcomm.connect.commons.patterns.StopObserving; +import org.restcomm.connect.commons.telephony.CreateCallType; import org.restcomm.connect.commons.util.SdpUtils; import org.restcomm.connect.commons.util.UriUtils; import org.restcomm.connect.dao.AccountsDao; @@ -59,10 +60,8 @@ import org.restcomm.connect.dao.entities.IncomingPhoneNumber; import org.restcomm.connect.dao.entities.Notification; import org.restcomm.connect.dao.entities.Registration; -import org.restcomm.connect.extension.api.CallRequest; -import org.restcomm.connect.extension.api.ExtensionRequest; -import org.restcomm.connect.extension.api.ExtensionResponse; import org.restcomm.connect.extension.api.ExtensionType; +import org.restcomm.connect.extension.api.IExtensionCreateCallRequest; import org.restcomm.connect.extension.api.RestcommExtensionException; import org.restcomm.connect.extension.api.RestcommExtensionGeneric; import org.restcomm.connect.extension.controller.ExtensionController; @@ -116,6 +115,7 @@ import java.net.URI; import java.net.URISyntaxException; import java.net.UnknownHostException; +import java.util.ArrayList; import java.util.List; import java.util.ListIterator; import java.util.Map; @@ -346,7 +346,7 @@ private ActorRef call(final CreateCall request) { @Override public UntypedActor create() throws Exception { return new Call(sipFactory, msControllerFactory.provideCallController(), configuration, - null, null, null); + null, null, null, null); } }); } else { @@ -356,7 +356,7 @@ public UntypedActor create() throws Exception { @Override public UntypedActor create() throws Exception { return new Call(sipFactory, msControllerFactory.provideCallController(), configuration, - request.statusCallback(), request.statusCallbackMethod(), request.statusCallbackEvent()); + request.statusCallback(), request.statusCallbackMethod(), request.statusCallbackEvent(), request.getOutboundProxyHeaders()); } }); } @@ -484,13 +484,11 @@ private void invite(final Object message) throws IOException, NumberParseExcepti logger.info("Client is not null: " + client.getLogin() + " will try to proxy to client: "+ toClient); } - CallRequest callRequest = new CallRequest(fromUser, toUser, CallRequest.Type.CLIENT, - client.getAccountSid(), false, false); ExtensionController ec = ExtensionController.getInstance(); - ExtensionRequest er = new ExtensionRequest(); - er.setObject(callRequest); - ExtensionResponse extensionResponse = ec.executePreOutboundAction(er, this.extensions); - if (extensionResponse.isAllowed()) { + IExtensionCreateCallRequest er = new CreateCall(fromUser, toUser, "", "", false, 0, CreateCallType.CLIENT, client.getAccountSid(), null,null, null, null); + ec.executePreOutboundAction(er, this.extensions); + + if (er.isAllowed()) { if (B2BUAHelper.redirectToB2BUA(request, client, toClient, storage, sipFactory, patchForNatB2BUASessions)) { if(logger.isInfoEnabled()) { logger.info("Call to CLIENT. myHostIp: " + myHostIp + " mediaExternalIp: " + mediaExternalIp + " toHost: " @@ -517,7 +515,7 @@ private void invite(final Object message) throws IOException, NumberParseExcepti final SipServletResponse resp = request.createResponse(SC_FORBIDDEN, "Call not allowed"); resp.send(); } - ec.executePostOutboundAction(callRequest, this.extensions); + ec.executePostOutboundAction(er, this.extensions); return; } else { // toClient is null or we couldn't make the b2bua call to another client. check if this call is for a registered @@ -526,47 +524,59 @@ private void invite(final Object message) throws IOException, NumberParseExcepti // This is a call to a registered DID (application) return; } + // This call is not a registered DID (application). Try to proxy out this call. // log to console and to notification engine String errMsg = "A Restcomm Client is trying to call a Number/DID that is not registered with Restcomm"; sendNotification(errMsg, 11002, "info", true); - if (isWebRTC(request)) { - //This is a WebRTC client that dials out - proxyThroughMediaServer(request, client, toUser); - return; - } + ExtensionController ec = ExtensionController.getInstance(); + IExtensionCreateCallRequest er = new CreateCall(fromUser, toUser, "", "", false, 0, CreateCallType.PSTN, client.getAccountSid(), null,null, null, null); + ec.executePreOutboundAction(er, this.extensions); + if (er.isAllowed()) { + if (isWebRTC(request)) { + //This is a WebRTC client that dials out + //TODO: should we inject headers for this case? + proxyThroughMediaServer(request, client, toUser); - // https://telestax.atlassian.net/browse/RESTCOMM-335 - final String proxyURI = activeProxy; - final String proxyUsername = activeProxyUsername; - final String proxyPassword = activeProxyPassword; - SipURI from = null; - SipURI to = null; - boolean callToSipUri = false; - // proxy DID or number if the outbound proxy fields are not empty in the restcomm.xml - if (proxyURI != null && !proxyURI.isEmpty()) { -// String destination = ((SipURI)request.getTo().getURI()).getUser(); - CallRequest callRequest = new CallRequest(fromUser,toUser, CallRequest.Type.PSTN, client.getAccountSid(), false, false); - ExtensionController ec = ExtensionController.getInstance(); - ExtensionRequest er = new ExtensionRequest(); - er.setObject(callRequest); - ExtensionResponse extensionResponse = ec.executePreOutboundAction(er, this.extensions); - if (extensionResponse.isAllowed()) { - proxyOut(request, client, toUser, toHost, toHostIpAddress, toPort, outboundIntf, proxyURI, proxyUsername, proxyPassword, from, to, callToSipUri); } else { - final SipServletResponse response = request.createResponse(SC_FORBIDDEN, "Call request not allowed"); - response.send(); - if (logger.isDebugEnabled()) { - logger.debug("Call request now allowed: "+callRequest.toString()); + // https://telestax.atlassian.net/browse/RESTCOMM-335 + String proxyURI = activeProxy; + String proxyUsername = activeProxyUsername; + String proxyPassword = activeProxyPassword; + SipURI from = null; + SipURI to = null; + boolean callToSipUri = false; + + if(er.getOutboundProxy()!=null && !er.getOutboundProxy().isEmpty()){ + proxyURI = er.getOutboundProxy(); + } + if(er.getOutboundProxyUsername()!=null && !er.getOutboundProxyUsername().isEmpty()){ + proxyUsername = er.getOutboundProxyUsername(); + } + if(er.getOutboundProxyPassword()!=null && !er.getOutboundProxyPassword().isEmpty()){ + proxyUsername = er.getOutboundProxyPassword(); + } + // proxy DID or number if the outbound proxy fields are not empty in the restcomm.xml + if (proxyURI != null && !proxyURI.isEmpty()) { + //FIXME: not so nice to just inject headers here + addHeadersToMessage(request, er.getOutboundProxyHeaders()); + proxyOut(request, client, toUser, toHost, toHostIpAddress, toPort, outboundIntf, proxyURI, proxyUsername, proxyPassword, from, to, callToSipUri); + } else { + errMsg = "Restcomm tried to proxy this call to an outbound party but it seems the outbound proxy is not configured."; + sendNotification(errMsg, 11004, "warning", true); } } - ec.executePostOutboundAction(callRequest, this.extensions); - return; } else { - String msg = "Restcomm tried to proxy this call to an outbound party but it seems the outbound proxy is not configured."; - sendNotification(errMsg, 11004, "warning", true); + //Extensions didn't allow this call + final SipServletResponse response = request.createResponse(SC_FORBIDDEN, "Call request not allowed"); + response.send(); + if (logger.isDebugEnabled()) { + logger.debug("Call request not allowed: "+er.toString()); + } } + ec.executePostOutboundAction(er, this.extensions); + return; } } else { // Client is null, check if this call is for a registered DID (application) @@ -589,6 +599,71 @@ private void invite(final Object message) throws IOException, NumberParseExcepti } + /** + * FIXME: duplicated code make into static function or something more optimized + * Replace headers + * @param SipServletRequest message + * @param Map > headers + */ + private void addHeadersToMessage(SipServletRequest message, Map > headers) { + + if(headers!=null) { + for (Map.Entry> entry : headers.entrySet()) { + //check if header exists + String headerName = entry.getKey(); + + StringBuilder sb = new StringBuilder(); + if(entry.getValue() instanceof ArrayList){ + for(String pair : entry.getValue()){ + sb.append(";").append(pair); + } + } + if(logger.isDebugEnabled()) { + logger.debug("headerName="+headerName+" headerVal="+message.getHeader(headerName)+" concatValue="+sb.toString()); + } + if(!headerName.equalsIgnoreCase("Request-URI")){ + try { + String headerVal = message.getHeader(headerName); + if(headerVal!=null && !headerVal.isEmpty()) { + message.setHeader(headerName , headerVal+sb.toString()); + }else{ + message.addHeader(headerName , sb.toString()); + } + } catch (IllegalArgumentException iae) { + if(logger.isErrorEnabled()) { + logger.error("Exception while setting message header: "+iae.getMessage()); + } + } + }else{ + //handle Request-URI + javax.servlet.sip.URI reqURI = message.getRequestURI(); + if(logger.isDebugEnabled()) { + logger.debug("ReqURI="+reqURI.toString()+" msgReqURI="+message.getRequestURI()); + } + for(String keyValPair :entry.getValue()){ + String parName = ""; + String parVal = ""; + int equalsPos = keyValPair.indexOf("="); + parName = keyValPair.substring(0, equalsPos); + parVal = keyValPair.substring(equalsPos+1); + reqURI.setParameter(parName, parVal); + if(logger.isDebugEnabled()) { + logger.debug("ReqURI pars ="+parName+"="+parVal+" equalsPos="+equalsPos+" keyValPair="+keyValPair); + } + } + + message.setRequestURI(reqURI); + if(logger.isDebugEnabled()) { + logger.debug("ReqURI="+reqURI.toString()+" msgReqURI="+message.getRequestURI()); + } + } + if(logger.isDebugEnabled()) { + logger.debug("headerName="+headerName+" headerVal="+message.getHeader(headerName)); + } + } + } + } + private boolean proxyOut(SipServletRequest request, Client client, String toUser, String toHost, String toHostIpAddress, String toPort, SipURI outboundIntf, String proxyURI, String proxyUsername, String proxyPassword, SipURI from, SipURI to, boolean callToSipUri) throws UnknownHostException { final Configuration runtime = configuration.subset("runtime-settings"); final boolean useLocalAddressAtFromHeader = runtime.getBoolean("use-local-address", false); @@ -1507,14 +1582,11 @@ private void update(final Object message) throws Exception { private void outbound(final Object message, final ActorRef sender) throws ServletParseException { final CreateCall request = (CreateCall) message; - CallRequest callRequest = new CallRequest(request.from(), request.to(), CallRequest.Type.valueOf(request.type().name()), request.accountId(), request.isFromApi(), request.parentCallSid() != null); ExtensionController ec = ExtensionController.getInstance(); - ExtensionRequest er = new ExtensionRequest(); - er.setObject(callRequest); - ExtensionResponse extensionResponse = ec.executePreOutboundAction(er, this.extensions); + ec.executePreOutboundAction(request, this.extensions); switch (request.type()) { case CLIENT: { - if (extensionResponse.isAllowed()) { + if (request.isAllowed()) { outboundToClient(request, sender); } else { //Extensions didn't allowed this call @@ -1522,11 +1594,11 @@ private void outbound(final Object message, final ActorRef sender) throws Servle logger.warning(errMsg); sender.tell(new CallManagerResponse(new RestcommExtensionException(errMsg), this.createCallRequest), self()); } - ec.executePostOutboundAction(callRequest, this.extensions); + ec.executePostOutboundAction(request, this.extensions); break; } case PSTN: { - if (extensionResponse.isAllowed()) { + if (request.isAllowed()) { outboundToPstn(request, sender); } else { //Extensions didn't allowed this call @@ -1534,14 +1606,14 @@ private void outbound(final Object message, final ActorRef sender) throws Servle logger.warning(errMsg); sender.tell(new CallManagerResponse(new RestcommExtensionException(errMsg), this.createCallRequest), self()); } - ec.executePostOutboundAction(callRequest, this.extensions); + ec.executePostOutboundAction(request, this.extensions); break; } case SIP: { if (actAsImsUa) { outboundToIms(request, sender); } - else if (extensionResponse.isAllowed()) { + else if (request.isAllowed()) { outboundToSip(request, sender); } else { //Extensions didn't allowed this call @@ -1549,7 +1621,7 @@ else if (extensionResponse.isAllowed()) { logger.warning(errMsg); sender.tell(new CallManagerResponse(new RestcommExtensionException(errMsg), this.createCallRequest), self()); } - ec.executePostOutboundAction(callRequest, this.extensions); + ec.executePostOutboundAction(request, this.extensions); break; } } @@ -1667,7 +1739,7 @@ private void outboundToClient(final CreateCall request, final ActorRef sender) t } private void outboundToPstn(final CreateCall request, final ActorRef sender) throws ServletParseException { - final String uri = activeProxy; + final String uri = (request.getOutboundProxy()!= null && (!request.getOutboundProxy().isEmpty())) ? request.getOutboundProxy() : activeProxy; SipURI outboundIntf = null; SipURI from = null; SipURI to = null; @@ -1727,11 +1799,15 @@ private void outboundToPstn(final CreateCall request, final ActorRef sender) thr private void outboundToSip(final CreateCall request, final ActorRef sender) throws ServletParseException { + final String uri = (request.getOutboundProxy()!= null && (!request.getOutboundProxy().isEmpty())) ? request.getOutboundProxy() : ""; SipURI outboundIntf = null; SipURI from = null; - SipURI to = null; + SipURI to = (SipURI) sipFactory.createURI(request.to()); + + if(!uri.isEmpty()){ + to.setHost(uri); + } - to = (SipURI) sipFactory.createURI(request.to()); String transport = (to.getTransportParam() != null) ? to.getTransportParam() : "udp"; outboundIntf = outboundInterface(transport); if (request.from() == null) { diff --git a/restcomm/restcomm.ussd/src/main/java/org/restcomm/connect/ussd/interpreter/UssdInterpreter.java b/restcomm/restcomm.ussd/src/main/java/org/restcomm/connect/ussd/interpreter/UssdInterpreter.java index 8cb32742db..ed4a074577 100644 --- a/restcomm/restcomm.ussd/src/main/java/org/restcomm/connect/ussd/interpreter/UssdInterpreter.java +++ b/restcomm/restcomm.ussd/src/main/java/org/restcomm/connect/ussd/interpreter/UssdInterpreter.java @@ -29,6 +29,7 @@ import akka.actor.UntypedActorFactory; import akka.event.Logging; import akka.event.LoggingAdapter; + import org.apache.commons.configuration.Configuration; import org.apache.http.HttpStatus; import org.apache.http.NameValuePair; @@ -42,6 +43,7 @@ import org.restcomm.connect.commons.fsm.State; import org.restcomm.connect.commons.fsm.Transition; import org.restcomm.connect.commons.patterns.Observe; +import org.restcomm.connect.commons.telephony.CreateCallType; import org.restcomm.connect.commons.util.UriUtils; import org.restcomm.connect.dao.CallDetailRecordsDao; import org.restcomm.connect.dao.DaoManager; @@ -67,7 +69,7 @@ import org.restcomm.connect.telephony.api.CallInfo; import org.restcomm.connect.telephony.api.CallResponse; import org.restcomm.connect.telephony.api.CallStateChanged; -import org.restcomm.connect.telephony.api.CreateCall; + import org.restcomm.connect.telephony.api.GetCallInfo; import org.restcomm.connect.ussd.commons.UssdInfoRequest; import org.restcomm.connect.ussd.commons.UssdMessageType; @@ -75,6 +77,7 @@ import javax.servlet.sip.SipServletRequest; import javax.servlet.sip.SipServletResponse; + import java.io.IOException; import java.math.BigDecimal; import java.net.URI; @@ -359,7 +362,7 @@ List parameters() { final String forwardedFrom = info.forwardedFrom(); parameters.add(new BasicNameValuePair("ForwardedFrom", forwardedFrom)); // logger.info("Type " + callInfo.type()); - if (CreateCall.Type.SIP == info.type()) { + if (CreateCallType.SIP == info.type()) { // Adding SIP OUT Headers and SipCallId for // https://bitbucket.org/telestax/telscale-restcomm/issue/132/implement-twilio-sip-out SipServletResponse lastResponse = info.lastResponse(); diff --git a/restcomm/restcomm.ussd/src/main/java/org/restcomm/connect/ussd/telephony/UssdCall.java b/restcomm/restcomm.ussd/src/main/java/org/restcomm/connect/ussd/telephony/UssdCall.java index 9cecbbe359..c6a5db6460 100644 --- a/restcomm/restcomm.ussd/src/main/java/org/restcomm/connect/ussd/telephony/UssdCall.java +++ b/restcomm/restcomm.ussd/src/main/java/org/restcomm/connect/ussd/telephony/UssdCall.java @@ -57,11 +57,12 @@ import org.restcomm.connect.commons.patterns.Observe; import org.restcomm.connect.commons.patterns.Observing; import org.restcomm.connect.commons.patterns.StopObserving; +import org.restcomm.connect.commons.telephony.CreateCallType; import org.restcomm.connect.telephony.api.Answer; import org.restcomm.connect.telephony.api.CallInfo; import org.restcomm.connect.telephony.api.CallResponse; import org.restcomm.connect.telephony.api.CallStateChanged; -import org.restcomm.connect.telephony.api.CreateCall; + import org.restcomm.connect.telephony.api.GetCallInfo; import org.restcomm.connect.telephony.api.GetCallObservers; import org.restcomm.connect.telephony.api.InitializeOutbound; @@ -111,7 +112,7 @@ public class UssdCall extends UntypedActor { private String transport; private String username; private String password; - private CreateCall.Type type; + private CreateCallType type; private long timeout; private SipServletRequest invite; private SipServletRequest outgoingInvite;