Tuesday 18 June 2013

Aria Subscription Billing System

Aria is a system founded by five Billing Experts, who have worked for LaserLink.net an internet service provider. Aria is basically a billing system which generates bill based upon the usage and the charges. For instance, mobile service providers may use Aria for generating bills of their subscribers based upon the usage of the services. Service Provider registers each subscriber of a service into Aria system with some information like Name, Address, Plans, Bill payment type, etc. Also the information like cost per unit of usage, required for generating the bill has to be provided at the time of user registration.

Aria information can be accessed through the website() or we can access it making http connections or REST calls. Some companies use Aria as a third party bill generating system use it by making REST calls.

For making these calls we have to provide some authentication information like Auth Key and Client No. in the url itself. Also with this information, we have to embed parameters, corresponding to the function that is called. Aria system provided some useful rest calls to access its information. There is proper documentation of these rest calls  here .
For example,

URL Formation:

https://secure.future.stage.ariasystems.net/api/AriaQuery/objects.php?rest_call=get_acct_details_all&client_no=Client_No&auth_key=Auth_key&acct_no=Account_No&output_format=json

Here, https://secure.future.stage.ariasystems.net/api/AriaQuery/objects.php? Is the Base Url and we are making use of the function get_acct_details_all which requires three parameters:
  1. client_no
  2. auth_key
  3. acct_no
Out of these parameters first two are necessary for making any Aria call. Each key-value pair in the url is separated by the delimiter '&'. Aria returns output in the form of Xml or as json.

ARIA Functions:

There are no. of various API functions provided by Aria. These functions are divided into some categories depending upon the functionality they perform. The important thing here is to notice that all functions except the functions with query as a parameter require, same base url.

Functions without query as a parameter:

Base Url:
https://secure.future.stage.ariasystems.net/api/ws/api_ws_class_dispatcher.php?

Functions with Query as a parameter:

The above functions take query string as a parameter-
  1. get_account_details( username, password, limit, offset, query_string)
  2. get_account_status_history(username, password, limit,offset, query_string)
  3. get_account_plan _history( username, password, limit, offset, query_string)
  4. get_payment_details( username, password, limit, offset, query_string)
  5. get_order_details( username, password, limit, offset, query_string)
  6. get_invoice_information( username, password, limit, offset, query_string)
  7. get_transaction_information( username, password, limit, offset, query_string)
  8. get_transaction_information( username, password, limit, offset, query_string)
  9. get_coupon_history (client_no, auth_key, limit, offset, query_string)

where,
limit - The maximum number of objects that should be returned by this call.
offset - The number of records to skip. Note that both "0" and NULL will cause the interface not to skip any records.
query_string - The criteria which all returned objects must match. Different objects have a different .

Base Url:  https://secure.future.stage.ariasystems.net/api/AriaQuery/objects.php?

Some information cannot be directly accessed by these calls, instead we have to write a query along with the function calls. Suppose we have to get information about all the accounts present under a client. For doing this no function is provided by Aria. So, we have to write a query “acct_no != 0” in encoded format like acct_no%20!%3D%200%3E.
For example,

https://secure.future.stage.ariasystems.net/api/AriaQuery/objects.php?rest_call=get_account_details_all&client_no=Client_No&auth_key=Auth_key&acct_no=Account_No&output_format=json&query_string=acct_no%20!%3D%200%3E

Here we have used acct_no as a condition parameter. Aria API Documentation has apparently given which parameters we can specify in the query for a particular function.
Instead of writing the code for accessing information, we can use Postman – Rest Client from the google chrome store which can provide the data in Xml or in Json format.

Based on the previous discussion, we have written the code to get data from Aria. Where we are getting data in the form Json string and then converting it into Json Object as shown.

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;


public JsonObject getAriaResponse(String ariaUri,String ariaFuncString,String queryString)
{
 String responseStr;
 String clientNo = "Enter Client No";
 String authKey = "Enter Auth Key";
 JsonParser jParser = new JsonParser();
 JsonObject obj = new JsonObject();
 String UrlStr;
 
 try
 {         
  if(queryString != null)
   UrlStr = ariaUri + "rest_call=" + ariaFuncString+"&client_no="+clientNo+"&auth_key="+authKey+"&query_string="+queryString+"&output_format=json";
  else
   UrlStr = ariaUri + "rest_call=" + ariaFuncString+"&client_no="+clientNo+"&auth_key="+authKey+"&output_format=json";   
  
  System.out.println("URI: "+UrlStr);
  URL url = new URL(UrlStr);
  URLConnection urlc = url.openConnection();
  urlc.setDoOutput(true);
  urlc.setAllowUserInteraction(false);
  PrintStream ps = new PrintStream(urlc.getOutputStream());
  ps.close();
  BufferedReader br = new BufferedReader(new InputStreamReader(urlc.getInputStream()));  
  responseStr = br.readLine();
  obj = jParser.parse(responseStr).getAsJsonObject(); 
 }
 catch(Exception e)
 {
  e.printStackTrace();
 }
 return obj;
}

Friday 31 May 2013

SAX Parser


SAX is the Simple API for XML originally a Java API. SAX parser can be used for parsing XML documents in an efficient and well mannered way. SAX parser use callback function (org.xml.sax.helpers.DefaultHandler) to inform clients of the XML document structure. In case of Java, we can extend DeafultHanlder and override few methods to achieve XML parsing.
There are some methods or functions provided:

1) startDocument() : This function executes at the start of the document.
2) startElement() : This function executes at the start of each and every tag where we can set some boolean variables to true.
3) endDocument() : This function executes at the end of the document.
4) endElement() : This function executes at the end of each and every tag where we can set some boolean variables to false.
5) characters() : It is an important function as it displays the text between the start tag and its corresponding end tag.
Now, consider that we have to parse the above xml file.


<company>
           <employee>
                          <name>Azim</name>
                          <id>201205556</id>
                          <degree>M.Tech</degree>
                          <history>
                                      <name>Progress Software</name>
                          </history>
           </employee>
           <employee>
                         <name>Aditya</name>
                         <id>AK47</id>
                         <degree>B.Tech</degree>
                         <history>
                                     <name>Synechron</name>
                         </history>
            </employee>
            <employee>
                          <name>Abdul</name>
                          <id>40040</id>
                          <degree>B.E</degree>
                          <history>
                                     <name>Cognizant</name>
                                     <name>Wipro</name>
                          </history>
            </employee>
</company>


The following example demonstrates the use of DefaultHandler and various functionalities provided in Java.
import java.io.File;
import java.io.OutputStreamWriter;
import java.io.Writer;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;



public class SAX extends DefaultHandler
{
 public static String inputXMLFile = "/home/star/workspace1/PracticeSession/sample.xml";
 public static Writer out;    
 public static boolean empFlag,nameFlag,idFlag,historyFlag,degFlag,histNameFlag;
 
 public static void main (String argv []) 
 {       
  empFlag = nameFlag = idFlag = historyFlag = degFlag = histNameFlag =false;
  SAXParserFactory factory = SAXParserFactory.newInstance();        
  try 
  {
   //Setting up the output stream - in this case System.out with UTF8 encoding
   out = new OutputStreamWriter(System.out, "UTF8");
   //Getting a parser from the factory
   SAXParser saxParser = factory.newSAXParser();
   //Parsing the XML document using the parser
   saxParser.parse( new File(inputXMLFile), new SAX());
  } 
  catch (Throwable throwable) 
  { 
   throwable.printStackTrace ();
  }
 } 
 
 public void startDocument() throws SAXException
 {
  System.out.println("Document Parsing Started:");
 }

 public void endDocument()throws SAXException
 {     
  System.out.println("Document Parsing Completed Successfully:");
 }

 public void startElement(String namespaceURI, String localName, String qName, Attributes atts)throws SAXException
 {  
  if(qName.equalsIgnoreCase("employee"))
   empFlag = true;
  else if(qName.equalsIgnoreCase("name") && historyFlag)   // for  tag in 
   histNameFlag = true;
  else if(qName.equalsIgnoreCase("name"))   // for only  tag
   nameFlag = true;
  else if(qName.equalsIgnoreCase("id"))
   idFlag = true;
  else if(qName.equalsIgnoreCase("history"))
   historyFlag = true;
 }

 public void endElement(String namespaceURI, String localName, String qName) throws SAXException
 {
  if(qName.equalsIgnoreCase("employee"))
   empFlag = false;
  else if(qName.equalsIgnoreCase("name") && historyFlag)
   histNameFlag = false;
  else if(qName.equalsIgnoreCase("name"))
   nameFlag = false;
  else if(qName.equalsIgnoreCase("id"))
   idFlag = false;
  else if(qName.equalsIgnoreCase("history"))
   historyFlag = false;
 }

 public void characters(char buffer [], int offset, int length) throws SAXException
 {
  String str = new String(buffer, offset, length);
  if(nameFlag && !historyFlag)
  {
   System.out.println("Employee Details:");
   System.out.println("Name: "+ str);
  }
  else if(histNameFlag)
   System.out.println("Previous Company Name: "+ str);
  else if(idFlag)
   System.out.println("Id: "+ str);
  else if(degFlag)
   System.out.println("Degree: "+ str);
 }
};

Output:
Document Parsing Started:
Employee Details:
Name: Azim
Id: 201205556
Previous Company Name: Progress Software
Employee Details:
Name: Aditya
Id: AK47
Previous Company Name: Synechron
Employee Details:
Name: Abdul
Id: 40040
Previous Company Name: Cognizant
Previous Company Name: Wipro
Document Parsing Completed Successfully: