Posts Tagged ‘regular expression’

[quicky] Asterisk and incoming cli manipulation

Thursday, January 15th, 2009

It is very common in professional VoIP that service providers put through CLIs transparently. If you are just a traffic routing party you usually don’t care about it, but for premium services however it can cause major issues. For example you have an application that matches the calling party’s CLI to an entry in a database. If you have built that application yourself it’s very easy to do some internal mangling, however some people buy products which are not suited to do the job properly.

So this article is about manipulating the calling party’s CLI, rather than the called number. Let’s take a look at the following call example. Person A (00123456789) calls service B(1223235325). Service B has a number in E.164 format, however person A does not. In this example person A is the calling party. However the service requires the calling number to be in E.164 format.

So what would we do in asterisk to fix that? Well, let’s say for example also the B-number has to zeros at the beginning of the number:

001223235325

In the asterisk configuration we could have the following example dial plan to strip the two zeros:

[example]
; match incoming 00xxxxxxx numbers and reformat
exten => 00X.,1,Goto(${EXTEN:2}, 1)
 
; normal dialplan
exten => _X.,1,Answer()
[...]

By using the ‘:2′ on the ‘EXTEN’ variable we get rid of the first ‘2′ digits, this is a substring operation.

So that was easy! However, when doing it for the incoming CLI it’s a totally different story. The incoming CLI is exposed by the CALLERID function. There is some regular expression support in Asterisk, so we can get going. Unfortunately it only supports matching. So no support for getting matched groups, which would be a lot easier. However after some twiddling I came up with the following:

[example]
; print cli as it came in
exten => _X.,1,Verbose(${CALLERID(num)})
 
; test if it matches 00XXX
exten => _X.,n,Set(STRIPCLI=${REGEX("^[0]\{2\}[1-9][0-9]+$" ${CALLERID(num)})})
 
; Depending if it is set to 0 or 1 goto continue or continue and format the cli
exten => _X.,n,GotoIf($["${STRIPCLI}" = "0"]?continue)
exten => _X.,n,Verbose(Formatting outbound CLI)
 
; format the CLI
exten => _X.,n,Set(CALLERID(num)=${CALLERID(num):2)})
 
; continue normal operation
exten => _X.,n(continue),Verbose(${CALLERID(num)})
exten => _X.,n,Dial(SIP/SOMESERVER/${EXTEN})
[..]

Let’s go back to our example now and how the dial plan handles it:

Verbose(00123456789)
Match on regular expression and put it a variable
if(STRIPCLI == false)
  continue normal dialplan
else
  format cli
 
normal dialplan:
 
Verbose(123456789)
Forward call to some service

As you can see the ‘00′ has been stripped of and the A number is now in E.164 format. I hope this will become useful for someone else as well :-)

[ztemplates] Form validation with regular expressions

Sunday, November 16th, 2008

Today I tried form validation with ZTemplates. For validating something I had to use a regular expression. In my view I created a pattern matching property like this:

private final ZStringProperty name = new ZStringProperty() {
@Override
  public ZError validate() {
 
  try {
 
    ZError error = super.validate();
 
    if (error != null) {				
      return error;
    }
 
    final Matcher matcher = Pattern.compile("[A-Z]+").matcher(getValue());
 
    if (matcher.matches() == false) {
      return new ZError("You didn't supply a valid identifier");
    }
 
    return null;
 
    }
    catch (Exception e) {
      return new ZError(e.getMessage());
    }
  }
};

I then had to do 10 more, which annoyed me a bit. I decided to look at the in-built ZIntProperty type and then I built my own ‘ZPatternProperty’:

ZPatternProperty.java:

package org.ztemplates.property;
 
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
 
import org.ztemplates.property.ZProperty;
import org.ztemplates.web.ZTemplates;
 
public class ZPatternProperty extends ZProperty<String> {
 
  String pattern;
 
  public ZPatternProperty(String pattern, ZProperty<?>... dependsOn) {
 
    super(dependsOn);
    this.pattern = pattern;
  }
 
  public ZPatternProperty(String value, String pattern, ZProperty<?>... dependsOn) {
 
    super(dependsOn);
    this.pattern = pattern;
    setValue(value);
  }
 
  @Override
  public String parse(String formattedValue) throws Exception {
 
    if(formattedValue == null) {
      return null;
    }
 
    Pattern propertyPattern;
 
    try {
      propertyPattern = Pattern.compile(pattern);
    }
    catch(PatternSyntaxException e) {
 
    throw new Exception(ZTemplates.getMessageService().getMessage(ZPatternProperty.class.getName(), "PatternSyntaxException"));
    }
 
    // check if the value matches the pattern
    if(propertyPattern.matcher(formattedValue).matches() == false) {
      throw new Exception(ZTemplates.getMessageService().getMessage(ZPatternProperty.class.getName(), "NoMatchException"));
    }
 
    return formattedValue;
  }
 
  @Override
  public String format(String obj) {
    return obj;
  }
}

My first code example now becomes:

 
  private final ZPatternProperty name = new ZPatternProperty("[A-Z]+");

Isn’t that much more robust?!

I also had to supply a ZPatternProperties.properties file for getting the exception message:

ZPatternProperty.properties:

PatternSyntaxException=Invalid pattern
NoMatchException=Value does not match the pattern

It needs some better exception messages in the future, but for me it’s fine.

I’ve also sent an email to the creator of the ztemplates framework including the code. I hope that in a new version of ztemplates there will be support for pattern validation.