grails create-app siptesting
In your IDE load the project.
For example, in Intellij you would do a:
File | Import Project
Point it to the project you just created and accept the prompts it gives.
Once the project is loaded in the IDE, we'll create the domain class first. The domain class will set the data elements we care about, any validation rules on them and these values will be stored in the db.
Speaking of Db, we could use any db we want, but for this demo, we'll just the in memory db (h2) that Grails defaults to.
To create a domain class in Intellij, you right click the project name, then click the sub menu item: New | Grails Domain Class
Give it a name like: OutboundCall
In the project tree, you should see a structure like:
grails-app
> conf
> controllers
> domain
In domain there should be a class now, called OutboundCall, open that up.
It will probably look like this:
class OutboundCall {
static constraints = {
}
}
Under the class reference, we're going to define some values. These values will tell Grails what to store. The info in a domain class is also used to create scaffolding elements like controllers and views.
By that I mean, if you define something in the Domain, Grails will generate all the actions to capture this data for you. Which saves from writing a lot of structure from scratch.
So lets define some things we want to capture...
Under class OutboundCall {
Date dateCreated
String carrier
String results
String ipProxy
String phone
String pass
dateCreated is an internal function. It will add a timestamp to each save of data
carrier will be captured from user input
results will be a computed value
ipProxy will be captured from user input
phone will be captured from user input
pass will be a computed value
Below this, there is that closure called "static constraints" - we want to add some constraints to the above variables. For example, we are ok with date being nullable, and only be able to pick carriers from a defined list (dropdown...)
So in the static constraints closure, add the following:
dateCreated nullable: true
carrier inList: ['Sprint','Verizon','Tcast']
results maxSize: 50000, nullable: true, display: false
ipProxy blank: false
phone blank: false
pass nullable: true, display: false
What we're saying here is this:
dateCreated is nullable, but why? Because it's not a value on the user creation form. It's going to be calculated by Grails. I had to make this nullable because otherwise Grails expects a value.
carrier uses a inList. Everything in the square brackets is going to be a option in a dropdown in a form.
results - we are saying results will have a size limitation and it's also nullable, and it won't display. The reason is that this field is going to be the SIPP output. It can be large output and it's not user input. We don't want it to display, except when it's avail, so not until the results are shown.
ipProxy and phone - are user input fields and they can't be blank.
pass - will be a value based on some logic to determine if the call went through fine or not.
Basically the Domain Class should look like this:
class OutboundCall{
Date dateCreated
String carrier
String results
String ipProxy
String phone
String pass
static constraints = {
dateCreated nullable: true
carrier inList: ['Sprint','TCast','Verizon']
results maxSize: 5000000, nullable: true, display: false
ipProxy blank: false
phone blank: false
pass nullable: true, display: false
}
static mapping = {
results type: 'text'
}
}
Generating the Static Scaffolding
At this point, we've created the domain. Lets do our first generation of code. We want Grails to generate the Controllers (the part of the code that will route logic) and Views (the display portion of the code.)
In Intellij, you can do a control+alt+G (windows) or Mac equivalent to pull up a command line for grails. In the box you will send:
grails generate-all [packag name].[class name]
For example:
grails generate-all siptests.OutboundCall
This will generate a controller for you called OutboundCallController (under the controllers folder in the project tree) and a set of views in a folder called "outboundCall."
Run the App
Let's see how our application looks.... go ahead and start it.
In Intellij we can click the green "play" like triangle at the top of the screen.
It should load without issue. Once it loads, it will give you a url, like http://localhost:8080/... click that link.
Iniitally you will land on a page that Grails generates to show you all your plugins used in the project and has links to your controllers. Click on the controller link.
This UI is all pre-built for you. You can "create" and it will load a UI with the fields we set in the Domain class. Go ahead and put some data in there and save it.
You'll be back at the List, showing your data you just saved.
It's not doing anything yet, other then capturing user input. But we can see that the applicaiton is up and running and taking user input.
Let's add some logic!
Controller
Go ahead and open up the controller we generated.
You'll see a lot of code. There will be all your crud actions in there. You'll see things like
def create()
def save()
def show()
This is the basic functionality of creating, saving, showing your data....
Our goal here is to take a user's input, and pass it to SIPP and validate the results we get. So we want to
SIPP
Back in SIPP, lets create some test scenarios.... Grails is going to let users send the phone number, the proxy and the carrier for the test. So lets get SIPP scenarios set up to handle this.
on the command line do a:
sipp -sd uac > outbound_call.xml
The above command will export a base template from SIPP to the XML file specified.
Once we have that file, lets edit it. We need to specify the carriers. In our example, we are going to allow users to send calls using Sprint, Verizon and TCast. To make this simple, we'll create three XML scenario files - one for each carrier. In each one, we'll hard code the carrier into the SIP Invite header.
If setting the carrier is applicable to you, you can define the carrier in the XML scenario. If it isn't applicable to you, then just omit the carrier reference in Grails (in the domain class) and just capture the phone number and proxy.
Some people can hard code a carrier value like:
Carrier: SPRINT
which is mapped to rules in their Sip Server (Berkeke or OpenSIPS) to send the call to the appropriate carrier.
If that's of interest, then lets do it.... let's copy that template as three files:
sprint_outbound_call.xml, verizon_outbound_call.xml, tcast_outbound_call.xml
Edit each one and modify the carrier value you read in from your sip server to be hard coded to this value.
Now when you run the sipp call to use this scenario it will be set to use this carrier - testing the carrier itself in handling the call.
Run a sipp scenario here that we made and make sure the call will go through to a phone number you have defined on the sip server.
If it works... then continue to Part II (Part II will cover setting up a Service and updating the Controller as well as Validating the results.)