JBoss.orgCommunity Documentation
To obtain the application's complete source code please refer to Section 2.2, “Mobicents JAIN SLEE USSD Gateway Application Source Code”.
This chapter explains how
components perform their tasks. For more
detailed explanation of
JSLEE
related source code
and xml descriptors,
please refer to
simple
examples, like
sip-wakeup
. Also for detailed description of rules
source code please refer to Drools
documentation
USSD Gateway
Application makes use of
Drools
as rules engine.
Engine is configured with DRL
files. DRL
file contains set of rules which perform operations on facts passed into engine.
USSD Gateway Application DRL
file defines rules to match initial USSD string to set of values identifying protocol and address of peer to which messages should be forwarded.
Rule file name is USSDGateway.drl
. File content looks as follows:
package org.mobicents.ussdgateway.rules![]()
import org.mobicents.ussdgateway.rules.Call;![]()
rule "USSDGateway1"
![]()
when
$c : Call( ussdString == "*123#" )
then![]()
$c.setSip( true );
$c.setSipProxy( "192.168.0.101" );
$c.setSipTo("123");
$c.setSipPort(5060);![]()
end
import of fact POJO | |
definition of rule | |
condition to enter rule clause. It accesses fact property | |
rule part which sets defined SIP peer as destination for messages | |
end of |
Rules are fed with facts on which engine performs matching operations(in general). Facts are simple POJO classes. This applications fact looks as follows:
package org.mobicents.ussdgateway.rules;
import java.io.Serializable;
/**
* Acts as Fact for Rules
* @author amit bhayani
*
*/
public class Call implements Serializable {
//Initial string, its like #123*
private String ussdString;
private boolean isSip;
private boolean isHttp;
private boolean isSmpp;
private String sipProxy;
private String sipTo;
private int sipPort;
//to be used with other protocols
private String genericUrl;
public Call(String ussdString){
this.ussdString = ussdString;
}
public String getUssdString() {
return ussdString;
}
public boolean isSip() {
return isSip;
}
public void setSip(boolean isSip) {
this.isSip = isSip;
}
public boolean isHttp() {
return isHttp;
}
public void setHttp(boolean isHttp) {
this.isHttp = isHttp;
}
public boolean isSmpp() {
return isSmpp;
}
public void setSmpp(boolean isSmpp) {
this.isSmpp = isSmpp;
}
public String getSipProxy() {
return sipProxy;
}
public void setSipProxy(String sipProxy) {
this.sipProxy = sipProxy;
}
public String getSipTo() {
return sipTo;
}
public void setSipTo(String sipTo) {
this.sipTo = sipTo;
}
public int getSipPort() {
return sipPort;
}
public void setSipPort(int sipPort) {
this.sipPort = sipPort;
}
/**
* @return the genericUrl
*/
public String getGenericUrl() {
return genericUrl;
}
/**
* @param genericUrl the genericUrl to set
*/
public void setGenericUrl(String genericUrl) {
this.genericUrl = genericUrl;
}
}
JMX part of USSD Gateway Application is responsible for initiating rules engine and exposing management methods.
Single JMX bean is defined with XML descriptor file jboss-beans.xml
. Descriptor content looks as follows:
<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:jboss:bean-deployer:2.0 bean-deployer_2_0.xsd"
xmlns="urn:jboss:bean-deployer:2.0">
<bean name="RulesService" class="org.mobicents.ussdgateway.rules.RulesService">
<annotation>@org.jboss.aop.microcontainer.aspects.jmx.JMX(
name="org.mobicents.ussdgateway:service=RulesService"
,exposedInterface=org.mobicents.ussdgateway.rules.RulesServiceMBean.class
,registerDirectly=true)
</annotation>
</bean>
</deployment>
JMX interface is defined as follows:
package org.mobicents.ussdgateway.rules;
import javax.naming.NamingException;
/**
*
* @author amit bhayani
*
*/
public interface RulesServiceMBean extends org.jboss.system.ServiceMBean {
![]()
String getJndiName();
void setJndiName(String jndiName) throws NamingException;
![]()
void startService() throws Exception;
void stopService() throws Exception;
}
It defines following:
management method. This method controls JNDI name under which rule engine is made available to SLEE Service | |
regular lifecycle methods |
Implementation of above interface fulfills defined contracts in following way:
public void startService() throws Exception {![]()
setupRule();![]()
rebind();
this.logger.info("Started Rules Service");
}
private void setupRule() {![]()
Resource resource = ResourceFactory.newUrlResource(CHANGESET_FILE_PATH);![]()
kagent = KnowledgeAgentFactory.newKnowledgeAgent("UssdGatewayAgent");
kagent.applyChangeSet(resource);
ResourceFactory.getResourceChangeNotifierService().start();
ResourceFactory.getResourceChangeScannerService().start();
}
private void rebind() throws NamingException {
InitialContext rootCtx = new InitialContext();
// Get the parent context into which we are to bind
Name fullName = rootCtx.getNameParser("").parse(jndiName);
System.out.println("fullName=" + fullName);
Name parentName = fullName;
if (fullName.size() > 1)
parentName = fullName.getPrefix(fullName.size() - 1);
else
parentName = new CompositeName();
Context parentCtx = createContext(rootCtx, parentName);
Name atomName = fullName.getSuffix(fullName.size() - 1);
String atom = atomName.get(0);
NonSerializableFactory.rebind(parentCtx, atom, kagent);
}
private static Context createContext(Context rootContext, Name name)
throws NamingException {
Context subctx = rootContext;
for (int n = 0; n < name.size(); n++) {
String atom = name.get(n);
try {
Object obj = subctx.lookup(atom);
subctx = (Context) obj;
} catch (NamingException e) { // No binding exists, create a
// subcontext
subctx = subctx.createSubcontext(atom);
}
}
return subctx;
}
void stopService() throws Exception
public void stopService() throws Exception {
![]()
unbind(jndiName);
}
void setJndiName(String jndiName) throws NamingException
public void setJndiName(String jndiName) throws NamingException {
![]()
String oldName = this.jndiName;
this.jndiName = jndiName;
![]()
if (getState() == STARTED) {
unbind(oldName);
try {
rebind();
} catch (Exception e) {
NamingException ne = new NamingException(
"Failed to update jndiName");
ne.setRootCause(e);
throw ne;
}
}
}
JMX bean loads change set file USSDGatewayChangeSet.xml
. This file controls how rules set is loaded and maintained by rule engine.
Please refer to Section 2.4, “Rule engine configuration” for details.
Mobicents USSD Gateway
Application is build with single
SLEE
service. Service is defined with single
XML
descriptor. Descriptor file name is
callsbb-service.xml
. It contains following information:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE service-xml PUBLIC "-//Sun Microsystems, Inc.//DTD JAIN SLEE Service 1.1//EN"
"http://java.sun.com/dtd/slee-service-xml_1_1.dtd">
<service-xml>
<service>
![]()
<service-name>mobicents-ussdgateway</service-name>
<service-vendor>org.mobicents</service-vendor>
<service-version>1.0</service-version>
<root-sbb>
![]()
<sbb-name>ParentSbb</sbb-name>
<sbb-vendor>org.mobicents</sbb-vendor>
<sbb-version>1.0</sbb-version>
</root-sbb>
![]()
<default-priority>50</default-priority>
</service>
</service-xml>
Since there is no standard defined for communication between USSD gateway and service providing peers, Mobicents USSD Gateway Application defines its own standard for encoding.
This SLEE library contains all classes required to properly encode and decode messages exchanged between Mobicents USSD Gateway and service providing peers. Library itself is built on top of JAXB framework.
Library is SLEE component, in other environments it is possible that it wont work properly.
Standard is defined with single XSD file ussd.xsd
. This file defines three types of encoded data:
This structure is base for all messages exchanged between Gateway and application server. It conveys parameter which help to identify dialog and resources it addresses.
USSD Dialog Message
This structure is base for all USSD messages exchanged between Gateway and application server. It adds USSD specific data.
USSD Message
This structure conveys data sent from between peers, for instance: #123*
or just simply 3
as subsequent request.
It has fields to indicate relevant metadata to conveyed string.
USSD Request
This structure indicates last message exchanged in dialog. It is standard USSD Message, however semantically it ends dialog. Its invoke ID MUST match invoke id from dialog initiating request.
USSD Response
Abort
is used to indicate some sort of error. Its content MUST
provide clue on error origination.
USSD Abort
Error details are encoded within abort reason as one of its values(exlusive):
userSpecific - simple string explaining application level error
userResourceLimitation - simple string explaining application level out of resource error
resourceUnavailable - enumeration type. It can have one of following values:
shortTermResourceLimitation
longTermResourceLimitation
applicationProcedureCancellation - enumeration type. It can have one of following values:
handoverCancellation
radioChannelRelease
networkPathRelease
callRelease
associatedProcedureFailure
tandemDialogueRelease
remoteOperationsFailure
Library classes are plain JAXB POJOs. They are marshalled to XML form in standard way:
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import org.mobicents.ussdgateway.ObjectFactory;
import org.mobicents.ussdgateway.USSDAbort;
import org.mobicents.ussdgateway.USSDRequest;
import org.mobicents.ussdgateway.USSDResponse;
JAXBContext jAXBContext = JAXBContext.newInstance("org.mobicents.ussdgateway");
ObjectFactory objectFactory = new ObjectFactory();
USSDRequest req = this.objectFactory.createUSSDRequest();
req.setInvokeId(1);
req.setUssdCoding(0xFF);
req.setUssdString("#112*");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
JAXBElement<USSDRequest> jxb = this.objectFactory.createRequest(req);
jAXBContext.createMarshaller().marshal(jxb, bos);
String xmlRequest = new String(bos.toByteArray());
Unmarshaller um = this.jAXBContext.createUnmarshaller();
JAXBElement o = (JAXBElement) um
.unmarshal(new ByteArrayInputStream(xmlRequest));
if (o.getDeclaredType().equals(USSDRequest.class)) {
//do something
} else if (o.getDeclaredType().equals(USSDResponse.class)) {
//do something
} else if (o.getDeclaredType().equals(USSDAbort.class)) {
//do something
}
InvokeId has constaraint on its value <-128,127>
In SLEE components library is referenced as follows:
<library-ref>
<library-name>library-ussdgateway</library-name>
<library-vendor>org.mobicents</library-vendor>
<library-version>2.0</library-version>
</library-ref>