Users: OpenNMS
Asterisk Monitoring and Notification
OpenNMS is an open source network management platform developed on the Java platform. It offers monitoring for a wide range of network devices and services.
As Asterisk becomes an important part of today's network infrastructure it becomes more important to be able to monitor it for outages and resource usage. Jeff Gehlbach of The OpenNMS Group is the de facto maintainer of res_snmp and is working on improved monitoring for Asterisk with OpenNMS. His slides from a recent talk in Frankfurt provide a good overview of the effort.
In addition to monitoring Asterisk Jeff has also added support to send OpenNMS notifications through Asterisk. This allows staff to be notified by a phone call of any outages in the network. The notification module is based on Asterisk-Java and uses the originate feature of the Manager API along with a custom AGI script that reads the notice details.
Jeff has made a screencast that shows it in action. If you are interested in the details have a look at his strategy class for originating calls and the AGI script that reads some of the notice details. Along with a few properties for configuration this makes a good example on how to integrate Asterisk into your applications with Asterisk-Java.
References
- OpenNMS homepage
- Jeff's slides on OpenNMS and Asterisk
- Jeff's screencast on OpenNMS Asterisk Notifications
Free Implementation of IAX in Java
Mexuar has released the sources for Correlata SDK under GPLv3
Tim Panton recently announced that Mexuar has released their Correlata SDK under the terms of GPLv3. It is available for download at http://www.mexuar.com/files/corraleta_sdk.rar.
Correlata SDK is a pure Java implementation of the IAX2 protocol. It includes an applet that can be accessed via JavaScript which makes it useful as a softphone embedded into web pages. In contrast to SIP IAX2 is firewall and NAT friendly.
To use the code you have to compile the sources and create a jar file. Then you have to sign it to allow the applet to access the microphone. Finally you'll setup a web page with the applet and add some JavaScript. You can have a look at the source code of the Mexuar homepage to see an example.
Though Mexuar has published the source code under GPL the download only contains the plain Java sources. There is no documentation except for JavaDoc, no build script and no sample code. The link to the download is quite hidden on their website. While Mexuar offers paid support, licenses and manged hosting there doesn't seem to be an Open Source community around it yet. Tim suggested to set up a project on Sourceforge or Google Code to build one. However due to his former relationship with Mexuar he prefers not be the project lead.
I think the code is a great complement to Asterisk-Java and will be very useful for a lot of applications. If you are also interested in giving it a good home and add some polish feel free to comment on this posting or discuss it on our mailing list.
References
- Download Source Code
- Implementing IAX2 In Java, presentation at Astricon Dallas by Tim Panton in 2006
Asterisk-Java With Groovy Presentation
A presentation by Justin Grammens
Justin Grammens has published a great overview of using Asterisk and Groovy with Asterisk-Java showing some real-worl examples.
The presentation is also available from SlideShare.
You might also want to have a look at Justin's blog Localtone. You'll find lots of information on Asterisk, Ruby and Groovy including the Ruby framework Adhearsion and some screencasts. I recommend his screencast on how to setup Asterisk to any Java or Ruby developer who wants to get started with VoIP and Asterisk.
Users: Zimbra Integration
Asterisk PBX Integration Zimlet
Zimbra is an open source groupware product for messaging and collaboration. Its core is implemented in Java and provides extension points for custom plugins so called Zimlets.
Swiss company BNC has developed a Zimlet to connect Asterisk to Zimbra using Asterisk-Java. The Asterisk PBX Integration Zimlet is available from Sourceforge under the terms of the GPL.
Features include
- Dial on-click in Contacts and Emails
- Sending SMS trough Asterisk's SMS application
- Inbound call notification
References
Users: Asterisk-Java and Spring
Mapping AGI URLs to Spring Beans
Sajid Moinuddin has blogged about using Asterisk-Java with Spring. His article shows how to implement a BeanNameAwareAGIMappingStrategy that automatically maps AGI URLs to Spring beans without any additional configuration.
References:
AACC: An Asterisk-Java based solution for Call Centers
By: Fernando Borcel – AACC Project Manager
As far as I know, no one has yet succeeded to deliver a high quality open source package for the thousands of small and medium sized call centers around the globe that want to go Asterisk. But having to buy proprietary software for managing the call center, or having to build their own software, seemed up to now the only two available options.
AACC was conceived to fulfill the need of those call centers, and make an impact in call centers similar to the one Asterisk has made in telephony. Now, that’s setting a pretty high mark for ourselves, so, how will we do it?
First of all, we have tried very hard to understand what those small and medium sized call centers need and want. So we are designing a system which is feature rich, yet easy to manage, agile, and extensible. We didn’t set up to reinvent the wheel. So we try to take advantage of other open source projects out there that do what they do very well. One of those projects is Asterisk-Java, on which we rely to communicate back and forth with Asterisk.
Then we said to ourselves, "Let’s go visual!" But let’s not go exactly mainstream. So we ruled out resource-hungry web based solutions, AJAX, and other technologies, and chose to use industry proven Java technology, both for our clients as well as for our servers.
Agents will have a toolbar – a specialized CRM from which they will be able to see and update call information, see a script for the campaign, or have it do an automatic screen pop. Administrators will have a control panel from which they will manage all aspects of the call center with ease. And they can chose to go Linux, or to go Windows, or… Mac? Doesn’t matter, AACC is built with Java, so it’s OS independent.
The response from the developers’ community was overwhelming, surpassing all of our expectations. We even had the luxury of turning down candidates! We are working right now on several fronts.
AACC will be suitable both for inbound as well as for outbound call centers. So we’re designing a predictive dialer, which will be able to handle multiple campaigns for multiple customers, with customizable information such as products offered, and per-campaign custom data, sales scripts, and call disposition.
Reporting is key. We are creating additional reporting information to what Asterisk provides, both for realtime and historical statistics. We're also incorporating JasperReports for stunning on-screen reporting, as well as saving the reports in the most relevant file formats, like PDF, RTF, ODT, HTML, XLS, and others. Reporting will of course be extensible, meaning that you will be able to design your own reports – with a WYSIWYG tool, also open source – in addition to the reports you will get out-of-the-box.
Last, but not least, AACC will be fully localizable. We hope that once initial development stage is over, we can be joined by translators who will help us localize the application to many languages.
When, you would ask, will this be production ready? We believe an alpha (i.e. not yet ready for production) version will be available before Christmas 2008. A beta version should be ready not long after that. I’ll keep you posted! Make sure you join our users list and visit our site at http://hanashidialer.sourceforge.net for more information about this project.
Outbound Message Delivery using AGI and AMI in Scala
From my participation in the asterisk-users and asterisk-java-users mailing lists, and from the general questions I see, I think a common use case for the combination of the Gateway interface and the Manager interface is to deliver outbound recorded messages. I think that an example might help to show how the two interfaces (and the two parts of Asterisk-Java) can be leveraged to deliver outbound messages.
However, because I've recently wanted to write more complex applications in Scala (a language interoperable with Java), I'm going to show you how to perform outbound message delivery with Scala and Asterisk-Java and without modification of the dialplan. If you liked my example of Scala and want to see more, I'd recommend this series if you have a Java background.
Here's the plan for our simple application:
- Design an Agi script that plays back our message
- Create & start an AgiServer object to host our script
- Create a Manager connection to Asterisk
- Using the Manager connection, ask Asterisk to originate a call from some destination to our Agi script
- Create a callback handler to act if/when the originate fails, succeeds, or we get disconnected
First, here's some definitions and imports we'll need in order to use Console (the System.out analog) and the Asterisk-Java library:
package org.asteriskjava.blog.scala import actors.Actor import Console.println import org.asteriskjava.fastagi._ import org.asteriskjava.live._
Next, here's the simple Agi script singleton class that simply plays the hello-world sound file, and then counts to ten. This is what our users will hear as the message.
object OutgoingMessageScript extends BaseAgiScript
{
def service(request: AgiRequest, channel: AgiChannel): Unit = {
streamFile("hello-world")
for(i <- 0.until(10))
sayNumber((i+1)+"")
}
}
Skipping ahead of a few steps (because it doesn't depend on anything else), here's the class that implements the callback interface, providing instructions on what to do if the originate dials, fails, succeeds, it's busy or not answered, or we get disconnected. This handler simply prints out what happened, though in your own code, this would be a good place to queue up something that failed, or mark it as a preliminary success (I say preliminary because this only means the originate succeeded, but not the playback... yet).
object OutgoingMessageStatusReport extends OriginateCallback
{
def onDialing(channel: AsteriskChannel): Unit = println("Dialing-" + channel)
def onSuccess(channel: AsteriskChannel): Unit = println("Success-" + channel)
def onNoAnswer(channel: AsteriskChannel): Unit = println("No Answer-" + channel)
def onBusy(channel: AsteriskChannel): Unit = println("Busy-" + channel)
def onFailure(cause: LiveException): Unit = println("Failure-" + cause)
}
And finally, here's the start of the main class and method...
object OutgoingMessageDelivery {
def main(args : Array[String]) : Unit = {
We'll create an AGI server, and use Actor to get the startup method executed in a separate thread. We do this so that it will begin to accept connections without blocking our current thread.
// start an AGI server with the given script
val asteriskGatewayServer = new DefaultAgiServer(OutgoingMessageScript)
new Actor { def act = asteriskGatewayServer.startup }.start
Next, we'll connect to Asterisk through the Manager interface too (via the nice Live API that wraps it).
// start a connection to the manager interface
val asteriskManagerInterface = new DefaultAsteriskServer(
"192.168.1.15",
"root",
"secret")
Finally, we will ask through the Manager interface that Asterisk originate to "SIP/xlite1" (if you were doing massive outbound delivery with T1/E1 circuits, you'd probably put something like "Zap/r1/outbound number" here)
// connect some channel to the script, with a callback
asteriskManagerInterface.originateToApplicationAsync(
"SIP/xlite1", // **** could be "Zap/r1/1234567890"
"Agi", "agi://"+java.net.InetAddress.getLocalHost.getHostAddress,
10*1000,
OutgoingMessageStatusReport)
}
}
And that's it! Asterisk will try to originate that call, and inform us (via the callback) of the outcome of the attempted originate.
Here's what the log will look like:
2008-08-09 16:02:04,671 org.asteriskjava.fastagi.DefaultAgiServer INFO [Thread-1] - Listening on *:4573. 2008-08-09 16:02:04,718 org.asteriskjava.manager.internal.ManagerConnectionImpl INFO [main] - Connecting to 192.168.1.15:5038 2008-08-09 16:02:04,843 org.asteriskjava.manager.internal.ManagerConnectionImpl INFO [Asterisk-Java ManagerConnection-0-Reader-0] - Connected via Asterisk Call Manager/1.0 2008-08-09 16:02:04,859 org.asteriskjava.manager.internal.ManagerConnectionImpl INFO [main] - Successfully logged in 2008-08-09 16:02:04,875 org.asteriskjava.manager.internal.ManagerConnectionImpl INFO [main] - Determined Asterisk version: Asterisk 1.4 2008-08-09 16:02:04,890 org.asteriskjava.live.internal.AsteriskServerImpl INFO [main] - Initializing done 2008-08-09 16:02:04,937 org.asteriskjava.live.internal.ChannelManager INFO [Asterisk-Java DaemonPool-1-thread-1] - Adding channel SIP/xlite1-081da108(1218312125.13) Dialing-AsteriskChannel[id='1218312125.13',name='SIP/xlite1-081da108',callerId='',state='DOWN',account='null',dateOfCreation=Sat Aug 09 16:02:04 EDT 2008,dialedChannel=null,dialingChannel=null,linkedChannel=null] 2008-08-09 16:02:06,218 org.asteriskjava.fastagi.DefaultAgiServer INFO [Thread-1] - Received connection from /192.168.1.15 Success-AsteriskChannel[id='1218312125.13',name='SIP/xlite1-081da108',callerId='',state='UP',account='null',dateOfCreation=Sat Aug 09 16:02:04 EDT 2008,dialedChannel=null,dialingChannel=null,linkedChannel=null] 2008-08-09 16:02:06,218 org.asteriskjava.fastagi.DefaultAgiServer INFO [Thread-1] - Thread pool started. 2008-08-09 16:02:06,375 org.asteriskjava.fastagi.internal.FastAgiConnectionHandler INFO [Asterisk-Java DaemonPool-2-thread-1] - Begin AgiScript org.asteriskjava.blog.scala.OutgoingMessageScript$ on Asterisk-Java DaemonPool-2-thread-1
Questions? Post on our mailing list or reply to the post!
It's worth nothing, too, that there are certainly already ways of doing this that may only involve the dialplan. Also, this doesn't solve the problem of detecting answering machines.
The complete source:
package org.asteriskjava.blog.scala
import actors.Actor
import Console.println
import org.asteriskjava.fastagi._
import org.asteriskjava.live._
object OutgoingMessageDelivery {
def main(args : Array[String]) : Unit = {
// start an AGI server with the given script
val asteriskGatewayServer = new DefaultAgiServer(OutgoingMessageScript)
new Actor { def act = asteriskGatewayServer.startup }.start
// start a connection to the manager interface
val asteriskManagerInterface = new DefaultAsteriskServer(
"192.168.1.15",
"root",
"secret")
// connect some channel to the script, with a callback
asteriskManagerInterface.originateToApplicationAsync(
"SIP/xlite1", // **** could be "Zap/r1/1234567890"
"Agi", "agi://"+java.net.InetAddress.getLocalHost.getHostAddress,
10*1000,
OutgoingMessageStatusReport)
}
}
object OutgoingMessageScript extends BaseAgiScript
{
def service(request: AgiRequest, channel: AgiChannel): Unit = {
streamFile("hello-world")
for(i <- 0.until(10))
sayNumber((i+1)+"")
}
}
object OutgoingMessageStatusReport extends OriginateCallback
{
def onDialing(channel: AsteriskChannel): Unit = println("Dialing-" + channel)
def onSuccess(channel: AsteriskChannel): Unit = println("Success-" + channel)
def onNoAnswer(channel: AsteriskChannel): Unit = println("No Answer-" + channel)
def onBusy(channel: AsteriskChannel): Unit = println("Busy-" + channel)
def onFailure(cause: LiveException): Unit = println("Failure-" + cause)
}
Users: Integrating PeopleSoft and Asterisk
Telephony integration with PeopleSoft on the cheap
Chris Heller has published a series of two blog posts on how to integrate Oracle's PeopleSoft with Asterisk using Asterisk-Java.
In PeopleSoft IVR Integration the easy way he explains how to "initiate a phone call to the end user from PeopleSoft, prompt them for a PIN code, and take action in PeopleSoft depending on whether they were successful or not. This may be used as part of the initial signon process for two-factor authentication of your PeopleSoft users, or you might tie this in with some business logic (e.g. be really sure who is sending off a large wire transfer)."
Part 2 goes into more detail on how use the integration for
two factor authentication with user events.
References
OSCON 2008, Mark Spencer's session on Thursday
Every year, O'Reilly hosts an open-source conference in Portland, OR, USA, in July. If anyone interested is at the conference, I'll be at Mark Spencer's talk on Thursday at 1:45pm. Stop by and say hello -- I'll be wearing the conference badge with my name on it. I'm always delighted to meet other like-minded Asterisk and Asterisk-Java users.
Visualizing your dialplan with a graph
Asterisk-Java's Config packages and the JUNG framework
A few weeks ago, Matt Gibson posted on the asterisk-users discussion list that he was looking for a GraphViz script he had heard about a few years ago that could generate graphs of Asterisk's extensions.conf file that defines the dialplan. At the time, I had been working on a recently open-sourced application, EgoNet, for a researcher I work with. This application taught me much about social networks, particularly his specialty of egocentric networks, and it also helped me learn a ton about the Java Universal Network/Graph Framework (or JUNG). I immediately thought about combining my experience with JUNG and Asterisk, and wrote a rudimentary (read as: extremely ugly) parser for extensions.conf and generated a crude graph of the sample dialplan.