Skip to content

Commit

Permalink
Fixed #126. Added variable expansion support in both "one of" and "re…
Browse files Browse the repository at this point in the history
…gex" validation pattern fields.

Fixed #127. The variable state if preserved for module-scoped variables until flow leave module. Applications that relied on the buggy assumption that module-scoped variables still exist in chained modules will be affected.
RESTCOMM-626,RESTCOMM-627 #Resolve-Issue fixed
  • Loading branch information
otsakir committed Nov 27, 2014
1 parent 46a0965 commit 3b0fe7a
Show file tree
Hide file tree
Showing 11 changed files with 91 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public class RvdConfiguration {
private static final String RVD_PROJECT_VERSION = "1.1"; // version for rvd project syntax
private static final String PACKAGING_VERSION = "1.0";
public static final String STICKY_PREFIX = "sticky_"; // a prefix for rvd sticky variable names
public static final String MODULE_PREFIX = "module_"; // a prefix for rvd module-scoped variable names
public static final String CORE_VARIABLE_PREFIX = "core_"; // a prefix for rvd variables that come from Restcomm parameters
public static final String PACKAGING_DIRECTORY_NAME = "packaging";
public static final String TICKET_COOKIE_NAME = "rvdticket"; // the name of the cookie that is used to store ticket ids for authentication
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package org.mobicents.servlet.restcomm.rvd.interpreter;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
Expand Down Expand Up @@ -73,6 +73,8 @@
import org.mobicents.servlet.restcomm.rvd.storage.ProjectStorage;
import org.mobicents.servlet.restcomm.rvd.storage.WorkspaceStorage;
import org.mobicents.servlet.restcomm.rvd.storage.exceptions.StorageException;
import org.mobicents.servlet.restcomm.rvd.utils.RvdUtils;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
Expand Down Expand Up @@ -277,7 +279,7 @@ public String interpret() throws RvdException {
processRequestParameters();
//handleStickyParameters(); // create local copies of sticky_* parameters

response = interpret(targetParam, null, null);
response = interpret(targetParam, null, null, null);
return response;
}

Expand All @@ -300,19 +302,24 @@ public void setContextPath(String contextPath) {
}


public String interpret(String targetParam, RcmlResponse rcmlModel, Step prependStep ) throws InterpreterException, StorageException {
public String interpret(String targetParam, RcmlResponse rcmlModel, Step prependStep, Target originTarget ) throws InterpreterException, StorageException {

logger.debug("starting interpeter for " + targetParam);
if ( rvdContext.getProjectSettings().getLogging() )
projectLogger.log("Running target: " + targetParam).tag("app",appName).done();

target = Interpreter.parseTarget(targetParam);
// if we are switching modules, remove module-scoped variables
if ( originTarget != null && ! RvdUtils.safeEquals(target.getNodename(), originTarget.getNodename() ) ) {
clearModuleVariables();
}


// TODO make sure all the required components of the target are available here

if (target.action != null) {
// Event handling
loadStep(target.stepname).handleAction(this);
loadStep(target.stepname).handleAction(this, target);
} else {
// RCML Generation

Expand Down Expand Up @@ -343,7 +350,7 @@ public String interpret(String targetParam, RcmlResponse rcmlModel, Step prepend
String rerouteTo = step.process(this, httpRequest); // is meaningful only for some of the steps like ExternalService steps
// check if we have to break the currently rendered module
if ( rerouteTo != null )
return interpret(rerouteTo, rcmlModel, null);
return interpret(rerouteTo, rcmlModel, null, target);
// otherwise continue rendering the current module
RcmlStep rcmlStep = step.render(this);
if ( rcmlStep != null)
Expand Down Expand Up @@ -458,6 +465,12 @@ final class VariableInText {
String replaceValue = "";
if (variables.containsKey(v.variableName))
replaceValue = variables.get(v.variableName);
else
if (variables.containsKey(RvdConfiguration.MODULE_PREFIX + v.variableName) )
replaceValue = variables.get(RvdConfiguration.MODULE_PREFIX + v.variableName);
else
if (variables.containsKey(RvdConfiguration.STICKY_PREFIX + v.variableName) )
replaceValue = variables.get(RvdConfiguration.STICKY_PREFIX + v.variableName);

buffer.replace(v.position, v.position + v.variableName.length() + 1, replaceValue == null ? "" : replaceValue); // +1 is for the $ character
}
Expand Down Expand Up @@ -485,9 +498,9 @@ public String buildAction(Map<String, String> pairs) {
query += key + "=" + encodedValue;
}

// append sticky parameters
// append sticky parameters and module-scoped variables
for ( String variableName : variables.keySet() ) {
if( variableName.startsWith(RvdConfiguration.STICKY_PREFIX) ) {
if( variableName.startsWith(RvdConfiguration.STICKY_PREFIX) || variableName.startsWith(RvdConfiguration.MODULE_PREFIX) ) {
if ("".equals(query))
query += "?";
else
Expand Down Expand Up @@ -646,15 +659,15 @@ private void processRequestParameters() {
String variableValue = getRequestParams().getFirst(anyVariableName);
getVariables().put(RvdConfiguration.CORE_VARIABLE_PREFIX + anyVariableName, variableValue );
} else
if ( anyVariableName.startsWith(RvdConfiguration.STICKY_PREFIX) ) {
if ( anyVariableName.startsWith(RvdConfiguration.STICKY_PREFIX) || anyVariableName.startsWith(RvdConfiguration.MODULE_PREFIX) ) {
// set up sticky variables
String variableValue = getRequestParams().getFirst(anyVariableName);
getVariables().put(anyVariableName, variableValue );

// make local copies
// First, rip off the sticky_prefix
String localVariableName = anyVariableName.substring(RvdConfiguration.STICKY_PREFIX.length());
getVariables().put(localVariableName, variableValue);
//String localVariableName = anyVariableName.substring(RvdConfiguration.STICKY_PREFIX.length());
//getVariables().put(localVariableName, variableValue);
} else {
//for the rest of the parameters simply create a variable with the same name
String variableValue = getRequestParams().getFirst(anyVariableName);
Expand Down Expand Up @@ -694,23 +707,16 @@ private void processBootstrapParameters() throws StorageException {
}
}

/*
* JsonParser parser = new JsonParser();
try {
HttpEntity entity = response.getEntity();
if ( entity != null ) {
String entity_string = EntityUtils.toString(entity);
logger.info("ES: Received " + entity_string.length() + " bytes");
logger.debug("ES Response: " + entity_string);
JsonElement response_element = parser.parse(entity_string);
String nextModuleName = null;
//boolean dynamicRouting = false;
if ( esStep.getDoRouting() && "responseBased".equals(esStep.getNextType()) ) {
//dynamicRouting = true;
String moduleLabel = evaluateExtractorExpression(esStep.getNextValueExtractor(), response_element);
nextModuleNam
*/

/**
* When switching from one module to the next clears module-scoped variables.
*/
public void clearModuleVariables() {
Iterator<String> it = variables.keySet().iterator();
while (it.hasNext()) {
String variableName = it.next();
if( variableName.startsWith(RvdConfiguration.MODULE_PREFIX) ) {
it.remove();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import org.mobicents.servlet.restcomm.rvd.exceptions.InterpreterException;
import org.mobicents.servlet.restcomm.rvd.interpreter.Interpreter;
import org.mobicents.servlet.restcomm.rvd.interpreter.Target;
import org.mobicents.servlet.restcomm.rvd.interpreter.exceptions.RVDUnsupportedHandlerVerb;
import org.mobicents.servlet.restcomm.rvd.model.rcml.RcmlStep;
import org.mobicents.servlet.restcomm.rvd.storage.exceptions.StorageException;
Expand Down Expand Up @@ -47,7 +48,7 @@ public void setName(String name) {
this.name = name;
}
public abstract RcmlStep render(Interpreter interpreter) throws InterpreterException;
public void handleAction(Interpreter interpreter) throws InterpreterException, StorageException {
public void handleAction(Interpreter interpreter, Target originTarget) throws InterpreterException, StorageException {
throw new RVDUnsupportedHandlerVerb();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.mobicents.servlet.restcomm.rvd.utils.RvdUtils;
import org.mobicents.servlet.restcomm.rvd.exceptions.InterpreterException;
import org.mobicents.servlet.restcomm.rvd.interpreter.Interpreter;
import org.mobicents.servlet.restcomm.rvd.interpreter.Target;
import org.mobicents.servlet.restcomm.rvd.model.client.Step;
import org.mobicents.servlet.restcomm.rvd.storage.exceptions.StorageException;

Expand Down Expand Up @@ -49,7 +50,8 @@ public RcmlDialStep render(Interpreter interpreter) throws InterpreterException
return rcmlStep;
}

public void handleAction(Interpreter interpreter) throws InterpreterException, StorageException {
@Override
public void handleAction(Interpreter interpreter, Target originTarget) throws InterpreterException, StorageException {
logger.info("handling dial action");
if ( RvdUtils.isEmpty(nextModule) )
throw new InterpreterException( "'next' module is not defined for step " + getName() );
Expand Down Expand Up @@ -81,7 +83,7 @@ public void handleAction(Interpreter interpreter) throws InterpreterException, S
if ( DialCallDuration != null )
interpreter.getVariables().put(RvdConfiguration.CORE_VARIABLE_PREFIX + "DialCallDuration", DialCallDuration);

interpreter.interpret( nextModule, null, null );
interpreter.interpret( nextModule, null, null, originTarget );
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,10 @@ public String process(Interpreter interpreter, HttpServletRequest httpRequest )

if ( "application".equals(assignment.getScope()) )
interpreter.putStickyVariable(assignment.getDestVariable(), value);
interpreter.putVariable(assignment.getDestVariable(), value );
if ( "module".equals(assignment.getScope()) )
interpreter.putModuleVariable(assignment.getDestVariable(), value);

//interpreter.putVariable(assignment.getDestVariable(), value );
} else
logger.debug("skipped assignment to " + assignment.getDestVariable() );
}
Expand All @@ -307,8 +310,10 @@ public String process(Interpreter interpreter, HttpServletRequest httpRequest )

if ( "application".equals(assignment.getScope()) )
interpreter.putStickyVariable(assignment.getDestVariable(), value);
if ( "module".equals(assignment.getScope()) )
interpreter.putModuleVariable(assignment.getDestVariable(), value);

interpreter.putVariable(assignment.getDestVariable(), value );
//interpreter.putVariable(assignment.getDestVariable(), value );
}
}
logger.debug("variables after processing ExternalService step: " + interpreter.getVariables().toString() );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.mobicents.servlet.restcomm.rvd.utils.RvdUtils;
import org.mobicents.servlet.restcomm.rvd.exceptions.InterpreterException;
import org.mobicents.servlet.restcomm.rvd.interpreter.Interpreter;
import org.mobicents.servlet.restcomm.rvd.interpreter.Target;
import org.mobicents.servlet.restcomm.rvd.model.client.Step;
import org.mobicents.servlet.restcomm.rvd.storage.exceptions.StorageException;

Expand Down Expand Up @@ -78,7 +79,9 @@ public RcmlFaxStep render(Interpreter interpreter) {

return rcmlStep;
}
public void handleAction(Interpreter interpreter) throws InterpreterException, StorageException {

@Override
public void handleAction(Interpreter interpreter, Target originTarget) throws InterpreterException, StorageException {
logger.info("handling fax action");
if ( RvdUtils.isEmpty(getNext()) )
throw new InterpreterException( "'next' module is not defined for step " + getName() );
Expand All @@ -91,6 +94,6 @@ public void handleAction(Interpreter interpreter) throws InterpreterException, S
if (FaxStatus != null )
interpreter.getVariables().put(RvdConfiguration.CORE_VARIABLE_PREFIX + "FaxStatus", FaxStatus);

interpreter.interpret( getNext(), null, null );
interpreter.interpret( getNext(), null, null, originTarget );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.mobicents.servlet.restcomm.rvd.RvdConfiguration;
import org.mobicents.servlet.restcomm.rvd.exceptions.InterpreterException;
import org.mobicents.servlet.restcomm.rvd.interpreter.Interpreter;
import org.mobicents.servlet.restcomm.rvd.interpreter.Target;
import org.mobicents.servlet.restcomm.rvd.model.client.Step;
import org.mobicents.servlet.restcomm.rvd.storage.exceptions.StorageException;

Expand Down Expand Up @@ -66,7 +67,7 @@ public RcmlGatherStep render(Interpreter interpreter) throws InterpreterExceptio
return rcmlStep;
}

public void handleAction(Interpreter interpreter) throws InterpreterException, StorageException {
public void handleAction(Interpreter interpreter, Target originTarget) throws InterpreterException, StorageException {
logger.info("handling gather action");

String digitsString = interpreter.getRequestParams().getFirst("Digits");
Expand All @@ -84,7 +85,7 @@ public void handleAction(Interpreter interpreter) throws InterpreterException, S
if (mapping.digits != null && mapping.digits.equals(digits)) {
// seems we found out menu selection
logger.debug("seems we found out menu selection");
interpreter.interpret(mapping.next,null, null);
interpreter.interpret(mapping.next,null, null, originTarget);
handled = true;
}
}
Expand All @@ -105,11 +106,15 @@ public void handleAction(Interpreter interpreter) throws InterpreterException, S
if ( validation != null ) {
//if ( validation.pattern != null && !validation.pattern.trim().equals("")) {
String effectivePattern = null;
if ( validation.userPattern != null )
effectivePattern = "^[" + validation.userPattern + "]$";
if ( validation.userPattern != null ) {
String expandedUserPattern = interpreter.populateVariables(validation.userPattern);
effectivePattern = "^[" + expandedUserPattern + "]$";
}
else
if (validation.regexPattern != null )
effectivePattern = validation.regexPattern;
if (validation.regexPattern != null ) {
String expandedRegexPattern = interpreter.populateVariables(validation.regexPattern);
effectivePattern = expandedRegexPattern;
}
else
logger.warn("Invalid validation information in gather. Validation object exists while oth patterns are null");

Expand All @@ -128,17 +133,21 @@ public void handleAction(Interpreter interpreter) throws InterpreterException, S
if ( "application".equals(collectdigits.scope) ) {
logger.debug("'" + variableName + "' is application scoped");
interpreter.putStickyVariable(variableName, variableValue);
} else
if ( "module".equals(collectdigits.scope) ) {
logger.debug("'" + variableName + "' is module scoped");
interpreter.putModuleVariable(variableName, variableValue);
}

// in any case initialize the module-scoped variable
interpreter.getVariables().put(variableName, variableValue);

interpreter.interpret(collectdigits.next,null,null);
interpreter.interpret(collectdigits.next,null,null, originTarget);
}
}

if ( !valid ) { // this should always be true
interpreter.interpret(interpreter.getTarget().getNodename() + "." + interpreter.getTarget().getStepname(),null, ( invalidMessage != null ) ? invalidMessage : null);
interpreter.interpret(interpreter.getTarget().getNodename() + "." + interpreter.getTarget().getStepname(),null, ( invalidMessage != null ) ? invalidMessage : null, originTarget);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.mobicents.servlet.restcomm.rvd.utils.RvdUtils;
import org.mobicents.servlet.restcomm.rvd.exceptions.InterpreterException;
import org.mobicents.servlet.restcomm.rvd.interpreter.Interpreter;
import org.mobicents.servlet.restcomm.rvd.interpreter.Target;
import org.mobicents.servlet.restcomm.rvd.model.client.Step;
import org.mobicents.servlet.restcomm.rvd.storage.exceptions.StorageException;

Expand Down Expand Up @@ -93,7 +94,8 @@ public RcmlRecordStep render(Interpreter interpreter) {
return rcmlStep;
}

public void handleAction(Interpreter interpreter) throws InterpreterException, StorageException {
@Override
public void handleAction(Interpreter interpreter, Target originTarget) throws InterpreterException, StorageException {
logger.info("handling record action");
if ( RvdUtils.isEmpty(getNext()) )
throw new InterpreterException( "'next' module is not defined for step " + getName() );
Expand Down Expand Up @@ -121,6 +123,6 @@ public void handleAction(Interpreter interpreter) throws InterpreterException, S
if (Digits != null )
interpreter.getVariables().put(RvdConfiguration.CORE_VARIABLE_PREFIX + "Digits", Digits);

interpreter.interpret( getNext(), null, null );
interpreter.interpret( getNext(), null, null, originTarget );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.mobicents.servlet.restcomm.rvd.utils.RvdUtils;
import org.mobicents.servlet.restcomm.rvd.exceptions.InterpreterException;
import org.mobicents.servlet.restcomm.rvd.interpreter.Interpreter;
import org.mobicents.servlet.restcomm.rvd.interpreter.Target;
import org.mobicents.servlet.restcomm.rvd.model.client.Step;
import org.mobicents.servlet.restcomm.rvd.storage.exceptions.StorageException;

Expand Down Expand Up @@ -87,7 +88,9 @@ public RcmlSmsStep render(Interpreter interpreter) {

return rcmlStep;
}
public void handleAction(Interpreter interpreter) throws InterpreterException, StorageException {

@Override
public void handleAction(Interpreter interpreter, Target originTarget) throws InterpreterException, StorageException {
logger.info("handling sms action");
if ( RvdUtils.isEmpty(getNext()) )
throw new InterpreterException( "'next' module is not defined for step " + getName() );
Expand All @@ -100,6 +103,6 @@ public void handleAction(Interpreter interpreter) throws InterpreterException, S
if (SmsStatus != null )
interpreter.getVariables().put(RvdConfiguration.CORE_VARIABLE_PREFIX + "SmsStatus", SmsStatus);

interpreter.interpret( getNext(), null, null );
interpreter.interpret( getNext(), null, null, originTarget );
}
}

0 comments on commit 3b0fe7a

Please sign in to comment.