The beauty of the spring and asterisk-java library is that they were made for each other! Asterisk java library was written in wonderful object-oriented way with clear separation on dependencies. So it was very easy to define the AGIServer and all its dependencies as Spring Bean. So We can inject the MappingStrategy with our own implementation of "BeanNameAwareAGIMappingStrategy" which implements ApplicationContextAware looks like this
@Override
protected AgiScript createAgiScriptInstance(String beanName) {
Object bean = applicationContext.getBean(beanName)
if(bean == null)
{
throw new IllegalArgumentException("No bean with name: [" + beanName +"] found. Make sure that you have all beans defined which are there in your fastagi-mapping.properties");
}
if(!(bean instanceof AgiScript))
{ throw new IllegalArgumentException("spring bean : " + beanName + " must implement org.asteriskjava.fastagi.AgiScript interface");
}
return (AgiScript) bean;
}
So now, instead of defining fully qualified classnames in your "fastagi-mapping.properties", you only give the bean name and our mapping strategy looks it up from the application context. So your plain agi scripts can talk to your dao, services and do all sort of fancy things! Isn't that wonderful!
3 comments:
We've been using similar approach for almost two years, with beans defined in XML files. It proved itself very convenient. Anyway, we implemented it in a slightly different way.
A brief example:
<bean id="agiServer" class="org.asteriskjava.fastagi.DefaultAgiServer" >
<property name="port" value="${server.callManager.port}"/>
<property name="mappingStrategy" ref="mappingStrategy"/>
</bean>
<bean id="mappingStrategy" class="ua.cv.usl.ice.agimanager.BasicMappingStrategy">
<property name="mappings">
<map>
<entry key="extension" value="ua.cv.usl.ice.callmanager.entryPoint.InternalCallEntryPoint"/>
<entry key="e164_outgoing" value="ua.cv.usl.ice.callmanager.entryPoint.PstnEntryPoint"/>
</map>
</property>
</bean>
Here BasicMappingStrategy extends AbstractMappingStrategy, implementing determineScript(AgiRequest request) method of MappingStrategy interface, so that createAgiScriptInstance(String className) is not overridden. Instead, createAgiScriptInstance is used only once - on BasicMappingStrategy initialization, to create instances of all Agi scripts and put them in a map, which can be accessed fast later, while calling to determineScript()
We have using Asterisk-java for 3 years now. Now the number of call has increased. So, we have to manage the access to DB via connection pool.
Any clue are welcome.
Do you mean Asterisk's DB or your application's DB? If you mean application's DB you can simply implement DB access layer that uses a technology which allows connections pooling, like Hibernate or something.
Post a Comment