diff --git a/designer/src/main/java/org/restcomm/connect/rvd/http/resources/RvdController.java b/designer/src/main/java/org/restcomm/connect/rvd/http/resources/RvdController.java index c82d7ad..72f6615 100644 --- a/designer/src/main/java/org/restcomm/connect/rvd/http/resources/RvdController.java +++ b/designer/src/main/java/org/restcomm/connect/rvd/http/resources/RvdController.java @@ -46,6 +46,7 @@ import org.restcomm.connect.rvd.interpreter.exceptions.BadExternalServiceResponse; import org.restcomm.connect.rvd.interpreter.exceptions.ESProcessFailed; import org.restcomm.connect.rvd.interpreter.exceptions.RemoteServiceError; +import org.restcomm.connect.rvd.interpreter.serialization.RcmlSerializer; import org.restcomm.connect.rvd.logging.system.LoggingContext; import org.restcomm.connect.rvd.logging.system.LoggingHelper; import org.restcomm.connect.rvd.logging.system.RvdLoggers; @@ -56,6 +57,7 @@ import org.restcomm.connect.rvd.model.callcontrol.CallControlAction; import org.restcomm.connect.rvd.model.callcontrol.CallControlStatus; import org.restcomm.connect.rvd.model.project.StateHeader; +import org.restcomm.connect.rvd.model.rcml.RcmlResponse; import org.restcomm.connect.rvd.restcomm.RestcommAccountInfo; import org.restcomm.connect.rvd.restcomm.RestcommClient; import org.restcomm.connect.rvd.restcomm.RestcommCallArray; @@ -112,6 +114,7 @@ public RvdController() {} // handle both GET and POST request in a single place private Response runInterpreter(String appname, HttpServletRequest httpRequest, MultivaluedMap requestParams) { + RcmlSerializer serializer = new RcmlSerializer(); String rcmlResponse; try { if (!FsProjectStorage.projectExists(appname, workspaceStorage)) @@ -119,7 +122,8 @@ private Response runInterpreter(String appname, HttpServletRequest httpRequest, Interpreter interpreter = new Interpreter(appname, httpRequest, requestParams, workspaceStorage,applicationContext, logging, rvdContext.getProjectLogger(), rvdContext.getProjectSettings() ); - rcmlResponse = interpreter.interpret(); + RcmlResponse steplist = interpreter.interpret(); + rcmlResponse = serializer.serialize(steplist); // logging rcml response, if configured // make sure logging is enabled before allowing access to sensitive log information @@ -132,12 +136,12 @@ private Response runInterpreter(String appname, HttpServletRequest httpRequest, RvdLoggers.local.log(Level.WARN, LoggingHelper.buildMessage(getClass(),"runInterpreter","{0}{1}{2}", new Object[] {logging.getPrefix(),"[app-error] ", e.getMessage()})); if (rvdContext.getProjectSettings().getLogging()) rvdContext.getProjectLogger().log(e.getMessage()).tag("app", appname).tag("EXCEPTION").done(); - rcmlResponse = Interpreter.rcmlOnException(); + rcmlResponse = serializer.serialize(Interpreter.rcmlOnException()); } catch (Exception e) { RvdLoggers.local.log(Level.ERROR, logging.getPrefix(), e); if (rvdContext.getProjectSettings().getLogging()) rvdContext.getProjectLogger().log(e.getMessage()).tag("app", appname).tag("EXCEPTION").done(); - rcmlResponse = Interpreter.rcmlOnException(); + rcmlResponse = serializer.serialize(Interpreter.rcmlOnException()); } if (RvdLoggers.local.isDebugEnabled()) RvdLoggers.local.log(Level.DEBUG, LoggingHelper.buildMessage(getClass(),"runInterpreter", logging.getPrefix() + "[RCML]", rcmlResponse)); diff --git a/designer/src/main/java/org/restcomm/connect/rvd/interpreter/Interpreter.java b/designer/src/main/java/org/restcomm/connect/rvd/interpreter/Interpreter.java index 331711d..e39c652 100644 --- a/designer/src/main/java/org/restcomm/connect/rvd/interpreter/Interpreter.java +++ b/designer/src/main/java/org/restcomm/connect/rvd/interpreter/Interpreter.java @@ -37,40 +37,10 @@ import org.restcomm.connect.rvd.model.rcml.RcmlStep; import org.restcomm.connect.rvd.model.server.NodeName; import org.restcomm.connect.rvd.model.server.ProjectOptions; -import org.restcomm.connect.rvd.model.steps.dial.ClientNounConverter; -import org.restcomm.connect.rvd.model.steps.dial.ConferenceNounConverter; -import org.restcomm.connect.rvd.model.steps.dial.NumberNounConverter; -import org.restcomm.connect.rvd.model.steps.dial.RcmlClientNoun; -import org.restcomm.connect.rvd.model.steps.dial.RcmlConferenceNoun; -import org.restcomm.connect.rvd.model.steps.dial.RcmlDialStep; -import org.restcomm.connect.rvd.model.steps.dial.RcmlNumberNoun; -import org.restcomm.connect.rvd.model.steps.dial.RcmlSipuriNoun; -import org.restcomm.connect.rvd.model.steps.dial.SipuriNounConverter; -import org.restcomm.connect.rvd.model.steps.email.RcmlEmailStep; import org.restcomm.connect.rvd.model.steps.es.AccessOperation; import org.restcomm.connect.rvd.model.steps.es.ExternalServiceStep; import org.restcomm.connect.rvd.model.steps.es.ValueExtractor; -import org.restcomm.connect.rvd.model.steps.fax.FaxStepConverter; -import org.restcomm.connect.rvd.model.steps.fax.RcmlFaxStep; -import org.restcomm.connect.rvd.model.steps.email.EmailStepConverter; -import org.restcomm.connect.rvd.model.steps.gather.RcmlGatherStep; import org.restcomm.connect.rvd.model.steps.hangup.RcmlHungupStep; -import org.restcomm.connect.rvd.model.steps.pause.RcmlPauseStep; -import org.restcomm.connect.rvd.model.steps.play.PlayStepConverter; -import org.restcomm.connect.rvd.model.steps.play.RcmlPlayStep; -import org.restcomm.connect.rvd.model.steps.record.RcmlRecordStep; -import org.restcomm.connect.rvd.model.steps.redirect.RcmlRedirectStep; -import org.restcomm.connect.rvd.model.steps.redirect.RedirectStepConverter; -import org.restcomm.connect.rvd.model.steps.reject.RcmlRejectStep; -import org.restcomm.connect.rvd.model.steps.say.RcmlSayStep; -import org.restcomm.connect.rvd.model.steps.say.SayStepConverter; -import org.restcomm.connect.rvd.model.steps.sms.RcmlSmsStep; -import org.restcomm.connect.rvd.model.steps.sms.SmsStepConverter; -import org.restcomm.connect.rvd.model.steps.ussdcollect.UssdCollectRcml; -import org.restcomm.connect.rvd.model.steps.ussdlanguage.UssdLanguageConverter; -import org.restcomm.connect.rvd.model.steps.ussdlanguage.UssdLanguageRcml; -import org.restcomm.connect.rvd.model.steps.ussdsay.UssdSayRcml; -import org.restcomm.connect.rvd.model.steps.ussdsay.UssdSayStepConverter; import org.restcomm.connect.rvd.storage.FsProjectStorage; import org.restcomm.connect.rvd.storage.WorkspaceStorage; import org.restcomm.connect.rvd.storage.exceptions.StorageException; @@ -81,7 +51,6 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; -import com.thoughtworks.xstream.XStream; public class Interpreter { @@ -93,7 +62,6 @@ public class Interpreter { private ProjectSettings projectSettings; private WorkspaceStorage workspaceStorage; - private XStream xstream; private Gson gson; private String targetParam; private Target target; @@ -102,12 +70,13 @@ public class Interpreter { private String contextPath; - private String rcmlResult; private Map variables = new HashMap(); private List nodeNames; - public static String rcmlOnException() { - return ""; + public static RcmlResponse rcmlOnException() { + RcmlResponse response = new RcmlResponse(); + response.steps.add(new RcmlHungupStep()); + return response; } @@ -127,76 +96,6 @@ public Interpreter(String appName, HttpServletRequest httpRequest, MultivaluedMa } private void init() { - xstream = new XStream(); - xstream.registerConverter(new SayStepConverter()); - xstream.registerConverter(new PlayStepConverter()); - xstream.registerConverter(new RedirectStepConverter()); - xstream.registerConverter(new SmsStepConverter()); - xstream.registerConverter(new FaxStepConverter()); - xstream.registerConverter(new EmailStepConverter()); - xstream.registerConverter(new NumberNounConverter()); - xstream.registerConverter(new ClientNounConverter()); - xstream.registerConverter(new ConferenceNounConverter()); - xstream.registerConverter(new SipuriNounConverter()); - xstream.registerConverter(new UssdSayStepConverter()); - xstream.registerConverter(new UssdLanguageConverter()); - xstream.addImplicitCollection(RcmlDialStep.class, "nouns"); - xstream.alias("Response", RcmlResponse.class); - xstream.addImplicitCollection(RcmlResponse.class, "steps"); - xstream.alias("Say", RcmlSayStep.class); - xstream.alias("Play", RcmlPlayStep.class); - xstream.alias("Gather", RcmlGatherStep.class); - xstream.alias("Dial", RcmlDialStep.class); - xstream.alias("Hangup", RcmlHungupStep.class); - xstream.alias("Redirect", RcmlRedirectStep.class); - xstream.alias("Reject", RcmlRejectStep.class); - xstream.alias("Pause", RcmlPauseStep.class); - xstream.alias("Sms", RcmlSmsStep.class); - xstream.alias("Email", RcmlEmailStep.class); - xstream.alias("Record", RcmlRecordStep.class); - xstream.alias("Fax", RcmlFaxStep.class); - xstream.alias("Number", RcmlNumberNoun.class); - xstream.alias("Client", RcmlClientNoun.class); - xstream.alias("Conference", RcmlConferenceNoun.class); - xstream.alias("Sip", RcmlSipuriNoun.class); - xstream.alias("UssdMessage", UssdSayRcml.class); - xstream.alias("UssdCollect", UssdCollectRcml.class); - xstream.alias("Language", UssdLanguageRcml.class); - xstream.addImplicitCollection(RcmlGatherStep.class, "steps"); - xstream.addImplicitCollection(UssdCollectRcml.class, "messages"); - xstream.useAttributeFor(UssdCollectRcml.class, "action"); - xstream.useAttributeFor(RcmlGatherStep.class, "action"); - xstream.useAttributeFor(RcmlGatherStep.class, "timeout"); - xstream.useAttributeFor(RcmlGatherStep.class, "finishOnKey"); - xstream.useAttributeFor(RcmlGatherStep.class, "method"); - xstream.useAttributeFor(RcmlGatherStep.class, "numDigits"); - xstream.useAttributeFor(RcmlSayStep.class, "voice"); - xstream.useAttributeFor(RcmlSayStep.class, "language"); - xstream.useAttributeFor(RcmlSayStep.class, "loop"); - xstream.useAttributeFor(RcmlPlayStep.class, "loop"); - xstream.useAttributeFor(RcmlRejectStep.class, "reason"); - xstream.useAttributeFor(RcmlPauseStep.class, "length"); - xstream.useAttributeFor(RcmlRecordStep.class, "action"); - xstream.useAttributeFor(RcmlRecordStep.class, "method"); - xstream.useAttributeFor(RcmlRecordStep.class, "timeout"); - xstream.useAttributeFor(RcmlRecordStep.class, "finishOnKey"); - xstream.useAttributeFor(RcmlRecordStep.class, "maxLength"); - xstream.useAttributeFor(RcmlRecordStep.class, "transcribe"); - xstream.useAttributeFor(RcmlRecordStep.class, "transcribeCallback"); - xstream.useAttributeFor(RcmlRecordStep.class, "playBeep"); - xstream.useAttributeFor(RcmlRecordStep.class, "media"); - xstream.useAttributeFor(RcmlDialStep.class, "action"); - xstream.useAttributeFor(RcmlDialStep.class, "method"); - xstream.useAttributeFor(RcmlDialStep.class, "timeout"); - xstream.useAttributeFor(RcmlDialStep.class, "timeLimit"); - xstream.useAttributeFor(RcmlDialStep.class, "callerId"); - xstream.useAttributeFor(RcmlDialStep.class, "record"); - xstream.aliasField("Number", RcmlDialStep.class, "number"); - xstream.aliasField("Client", RcmlDialStep.class, "client"); - xstream.aliasField("Conference", RcmlDialStep.class, "conference"); - xstream.aliasField("Uri", RcmlDialStep.class, "sipuri"); - - // xstream.aliasField(alias, definedIn, fieldName); gson = new GsonBuilder().registerTypeAdapter(Step.class, new StepJsonDeserializer()).create(); } @@ -244,8 +143,8 @@ public void setTarget(Target target) { } - public String interpret() throws RvdException { - String response = null; + public RcmlResponse interpret() throws RvdException { + RcmlResponse response = null; ProjectOptions projectOptions = FsProjectStorage.loadProjectOptions(appName, workspaceStorage); //rvdContext.getRuntimeProjectOptions(); nodeNames = projectOptions.getNodeNames(); @@ -269,10 +168,6 @@ public String interpret() throws RvdException { } - - - - public MultivaluedMap getRequestParams() { return requestParams; } @@ -281,7 +176,7 @@ public String getContextPath() { return contextPath; } - public String interpret(String targetParam, RcmlResponse rcmlModel, Step prependStep, Target originTarget ) throws InterpreterException, StorageException { + public RcmlResponse interpret(String targetParam, RcmlResponse rcmlModel, Step prependStep, Target originTarget ) throws InterpreterException, StorageException { if (RvdLoggers.local.isTraceEnabled()) RvdLoggers.local.log(Level.TRACE, LoggingHelper.buildMessage(getClass(),"interpret", loggingContext.getPrefix(), "starting interpeter for " + targetParam)); if ( projectSettings.getLogging() ) @@ -338,10 +233,11 @@ public String interpret(String targetParam, RcmlResponse rcmlModel, Step prepend } } - rcmlResult = xstream.toXML(rcmlModel); + //rcmlResult = xstream.toXML(rcmlModel); } - return rcmlResult; // this is in case of an error + //return rcmlResult; // this is in case of an error + return rcmlModel; } private Step loadStep(String stepname) throws StorageException { diff --git a/designer/src/main/java/org/restcomm/connect/rvd/interpreter/serialization/RcmlSerializer.java b/designer/src/main/java/org/restcomm/connect/rvd/interpreter/serialization/RcmlSerializer.java new file mode 100644 index 0000000..08136c3 --- /dev/null +++ b/designer/src/main/java/org/restcomm/connect/rvd/interpreter/serialization/RcmlSerializer.java @@ -0,0 +1,120 @@ +package org.restcomm.connect.rvd.interpreter.serialization; + +import com.thoughtworks.xstream.XStream; +import org.restcomm.connect.rvd.model.rcml.RcmlResponse; +import org.restcomm.connect.rvd.model.steps.dial.ClientNounConverter; +import org.restcomm.connect.rvd.model.steps.dial.ConferenceNounConverter; +import org.restcomm.connect.rvd.model.steps.dial.NumberNounConverter; +import org.restcomm.connect.rvd.model.steps.dial.RcmlClientNoun; +import org.restcomm.connect.rvd.model.steps.dial.RcmlConferenceNoun; +import org.restcomm.connect.rvd.model.steps.dial.RcmlDialStep; +import org.restcomm.connect.rvd.model.steps.dial.RcmlNumberNoun; +import org.restcomm.connect.rvd.model.steps.dial.RcmlSipuriNoun; +import org.restcomm.connect.rvd.model.steps.dial.SipuriNounConverter; +import org.restcomm.connect.rvd.model.steps.email.EmailStepConverter; +import org.restcomm.connect.rvd.model.steps.email.RcmlEmailStep; +import org.restcomm.connect.rvd.model.steps.fax.FaxStepConverter; +import org.restcomm.connect.rvd.model.steps.fax.RcmlFaxStep; +import org.restcomm.connect.rvd.model.steps.gather.RcmlGatherStep; +import org.restcomm.connect.rvd.model.steps.hangup.RcmlHungupStep; +import org.restcomm.connect.rvd.model.steps.pause.RcmlPauseStep; +import org.restcomm.connect.rvd.model.steps.play.PlayStepConverter; +import org.restcomm.connect.rvd.model.steps.play.RcmlPlayStep; +import org.restcomm.connect.rvd.model.steps.record.RcmlRecordStep; +import org.restcomm.connect.rvd.model.steps.redirect.RcmlRedirectStep; +import org.restcomm.connect.rvd.model.steps.redirect.RedirectStepConverter; +import org.restcomm.connect.rvd.model.steps.reject.RcmlRejectStep; +import org.restcomm.connect.rvd.model.steps.say.RcmlSayStep; +import org.restcomm.connect.rvd.model.steps.say.SayStepConverter; +import org.restcomm.connect.rvd.model.steps.sms.RcmlSmsStep; +import org.restcomm.connect.rvd.model.steps.sms.SmsStepConverter; +import org.restcomm.connect.rvd.model.steps.ussdcollect.UssdCollectRcml; +import org.restcomm.connect.rvd.model.steps.ussdlanguage.UssdLanguageConverter; +import org.restcomm.connect.rvd.model.steps.ussdlanguage.UssdLanguageRcml; +import org.restcomm.connect.rvd.model.steps.ussdsay.UssdSayRcml; +import org.restcomm.connect.rvd.model.steps.ussdsay.UssdSayStepConverter; + +/** + * Serializes Rcml*Step to RCML code + * + * @author otsakir@gmail.com - Orestis Tsakiridis + */ +public class RcmlSerializer { + + private XStream xstream; + + public RcmlSerializer() { + xstream = new XStream(); + xstream.registerConverter(new SayStepConverter()); + xstream.registerConverter(new PlayStepConverter()); + xstream.registerConverter(new RedirectStepConverter()); + xstream.registerConverter(new SmsStepConverter()); + xstream.registerConverter(new FaxStepConverter()); + xstream.registerConverter(new EmailStepConverter()); + xstream.registerConverter(new NumberNounConverter()); + xstream.registerConverter(new ClientNounConverter()); + xstream.registerConverter(new ConferenceNounConverter()); + xstream.registerConverter(new SipuriNounConverter()); + xstream.registerConverter(new UssdSayStepConverter()); + xstream.registerConverter(new UssdLanguageConverter()); + xstream.addImplicitCollection(RcmlDialStep.class, "nouns"); + xstream.alias("Response", RcmlResponse.class); + xstream.addImplicitCollection(RcmlResponse.class, "steps"); + xstream.alias("Say", RcmlSayStep.class); + xstream.alias("Play", RcmlPlayStep.class); + xstream.alias("Gather", RcmlGatherStep.class); + xstream.alias("Dial", RcmlDialStep.class); + xstream.alias("Hangup", RcmlHungupStep.class); + xstream.alias("Redirect", RcmlRedirectStep.class); + xstream.alias("Reject", RcmlRejectStep.class); + xstream.alias("Pause", RcmlPauseStep.class); + xstream.alias("Sms", RcmlSmsStep.class); + xstream.alias("Email", RcmlEmailStep.class); + xstream.alias("Record", RcmlRecordStep.class); + xstream.alias("Fax", RcmlFaxStep.class); + xstream.alias("Number", RcmlNumberNoun.class); + xstream.alias("Client", RcmlClientNoun.class); + xstream.alias("Conference", RcmlConferenceNoun.class); + xstream.alias("Sip", RcmlSipuriNoun.class); + xstream.alias("UssdMessage", UssdSayRcml.class); + xstream.alias("UssdCollect", UssdCollectRcml.class); + xstream.alias("Language", UssdLanguageRcml.class); + xstream.addImplicitCollection(RcmlGatherStep.class, "steps"); + xstream.addImplicitCollection(UssdCollectRcml.class, "messages"); + xstream.useAttributeFor(UssdCollectRcml.class, "action"); + xstream.useAttributeFor(RcmlGatherStep.class, "action"); + xstream.useAttributeFor(RcmlGatherStep.class, "timeout"); + xstream.useAttributeFor(RcmlGatherStep.class, "finishOnKey"); + xstream.useAttributeFor(RcmlGatherStep.class, "method"); + xstream.useAttributeFor(RcmlGatherStep.class, "numDigits"); + xstream.useAttributeFor(RcmlSayStep.class, "voice"); + xstream.useAttributeFor(RcmlSayStep.class, "language"); + xstream.useAttributeFor(RcmlSayStep.class, "loop"); + xstream.useAttributeFor(RcmlPlayStep.class, "loop"); + xstream.useAttributeFor(RcmlRejectStep.class, "reason"); + xstream.useAttributeFor(RcmlPauseStep.class, "length"); + xstream.useAttributeFor(RcmlRecordStep.class, "action"); + xstream.useAttributeFor(RcmlRecordStep.class, "method"); + xstream.useAttributeFor(RcmlRecordStep.class, "timeout"); + xstream.useAttributeFor(RcmlRecordStep.class, "finishOnKey"); + xstream.useAttributeFor(RcmlRecordStep.class, "maxLength"); + xstream.useAttributeFor(RcmlRecordStep.class, "transcribe"); + xstream.useAttributeFor(RcmlRecordStep.class, "transcribeCallback"); + xstream.useAttributeFor(RcmlRecordStep.class, "playBeep"); + xstream.useAttributeFor(RcmlRecordStep.class, "media"); + xstream.useAttributeFor(RcmlDialStep.class, "action"); + xstream.useAttributeFor(RcmlDialStep.class, "method"); + xstream.useAttributeFor(RcmlDialStep.class, "timeout"); + xstream.useAttributeFor(RcmlDialStep.class, "timeLimit"); + xstream.useAttributeFor(RcmlDialStep.class, "callerId"); + xstream.useAttributeFor(RcmlDialStep.class, "record"); + xstream.aliasField("Number", RcmlDialStep.class, "number"); + xstream.aliasField("Client", RcmlDialStep.class, "client"); + xstream.aliasField("Conference", RcmlDialStep.class, "conference"); + xstream.aliasField("Uri", RcmlDialStep.class, "sipuri"); + } + + public String serialize(RcmlResponse rcmlResponse) { + return xstream.toXML(rcmlResponse); + } +}