Understanding the Home Subscriber Server (HSS) Sh interface

How WebLogic SIP Server Works

This section examines how easy is to use the API included in the current release of WLSS to communicate with an HSS server.

WLSS profile API

The DIAMETER Sh interface is exposed as a Provider, and the container will take care of all DIAMETER behaviors. For a developer, WebLogic SIP Server provides an interface com.bea.wcp.profile.ProfileService whose implementation is registered in the servlet context, and can be used for easily retrieving the profile. The helper class returns the user data as an XML document, and the developer can use standard DOM techniques to work on it. In the case of the Sh Pull Update command, the ProfileService will always return the user data as read-only documents, so you have to explicitly clone it before modifying it. Regarding the Sh Profile Update request, the application can specify a ProfileListener class to be notified of incoming messages from the HSS. Thanks to the converged container you can query the HSS no matter which channel is currently being used, HTTP or SIP.

Building a simple Sh Request

Building an Sh request is pretty simple. An Sh request always follow this schema:

protocol://uri/reference_type/access_key

Where:

  • protocol is obviously sh
  • uri usually is a Public User Identity or a User Identity
  • reference_type specifies the data reference type requested
  • access_key corresponds to the value of the Attribute-Value Pair (AVP)

These are some examples of Document Selector Elements for Sh Data Request:

  • Requesting data related to service IM2SMS (where IM2MS represents a ServiceIndication): sh://sip:username@domain.com/RepositoryData/IM2SMS
  • Requesting public identity related to username@domain: sh://sip:username@domain.com/IMSPublicIdentity/
  • Requesting MSISDN: sh://sip:username@domain.com/MSISDN/

Retrieving the ServiceProfile

In an HTTP or SIP servlet, the very first thing to do is to import com.bea.wcp.profile.ProfileService. In the init() method a reference to the ProfileService is stored for retrieving data from the HSS. This code snippet shows how to do this:


    public void init() throws ServletException 
    {
      ServletContext sc = getServletContext();
      // Get the ProfileService from the ServletContext
      ps = (ProfileService) 
                     sc.getAttribute(ProfileService.PROFILE_SERVICE);
      if (ps == null) 
      {
         throw new ServletException("Profile service not found");
      }
      System.out.println(getClass().getName() + " initialized");
    }
    

Preparing the Sh Request String

It's easy to execute an Sh Pull request in WLSS. The example below shows how to build an Sh Request String, based on the request type using a switch statement:


    public static String buildShRequest( int requestType, 
        String userName,  String ServiceName, int domainType,
                                 String serverName )
    {
      String docSelector = "sh://sip:";
    
      // Get username
      docSelector += userName;
      // Matching RequestType with Data reference      
      switch(requestType)
      {
      case Constants.SH_REPOSITORY_DATA:
      docSelector += "/RepositoryData/" + ServiceName;
      break;
      case Constants.SH_MSISDN:
      docSelector += "/MSISDN/";
      break;
      case Constants.SH_IMS_PUBLIC_IDENTITY:
      docSelector += "/IMSPublicIdentity/";
      break;
      case Constants.SH_CHARGING_INFO:
      docSelector += "/ChargingInformation/";
      break;
      case Constants.SH_USER_STATE:
      docSelector += "/UserState/";
      docSelector += (domainType==Constants.SH_PS_DOMAIN)?"PS-Domain/":"CS-Domain/";
      break;
      case Constants.SH_IMS_USER_STATE:
      docSelector += "/IMSUserState/";
      break;
      case Constants.SH_S_CSCF_NAME:
      docSelector += "/S-CSCFName/";
      break;
      case Constants.SH_INITIAL_FILTER_CRITERIA:
      docSelector += "/InitialFilterCriteria/" + serverName;
      break;
      case Constants.SH_LOCATION_INFO:
      docSelector += "/LocationInformation/";
      docSelector += (domainType == Constants.SH_PS_DOMAIN)? "PS-Domain/":"CS-Domain/";
      break;  
      }
    }
    

Executing an Sh Pull

Now we're going to execute an Sh Pull request in WebLogic SIP Server. In this example we're requesting a RepositoryData, so we need to get extra information beyond the user. You need the service name. After building the Sh request we pass it to the ProfileService previously instantiated:


    private String executeTest(String theShRequest) 
    {
      String response = null;
      try {
        logger.debug("Sh Request: " + theShRequest );
        // Get the document from the HSS
        Document genericDoc = ps.getDocument(theShRequest);
        response = DIAMETERHelper.toString(genericDoc.getDocumentElement());
        logger.debug("HSS Response: \n" + response);
      } catch (ProfileException e) {
        // Get the Message Exception
        MessageException me = (MessageException)e.getCause();
        // Get the DIAMETER ResultCode
        ResultCode rc = me.getResultCode();       
        session.setAttribute(Constants.DIAMETER_RESULT_CODE, rc.toString());
        session.setAttribute("Exception", e.getMessage());
        logger.debug("Exception - DIAMETER Result Code is: " + rc.toString() );
      } catch (Exception e) {
        response = e.getMessage();
        session.setAttribute("Exception", e.getMessage());
        logger.debug("Exception: " + response);
      } 
      return response;
    }
    

Executing an Sh Pull update

After receiving the data from the HSS using Sh Pull, it's now possible to modify it using the standard DOM techniques. Saving the new data is simple: All you have to do is clone the document received previously (because ProfileServer returns a read-only document) and then call the method put() exposed by the ProfileServer, as shown here:


    private String executeTest(String theShRequest, String newData, 
                               String newValue) 
    {
      String response = null;
      try {
        logger.debug("Sh Request: " + theShRequest );
        Document originalDoc = ps.getDocument(theShRequest);
    
        // Preparing to modify the document
        logger.debug("Going to prepare document");
    
        // Modifying original document
        Document modifiedDocument = this.saveDoc(
             (Document)originalDoc.cloneNode(true),newData, newValue);
    
        // Storing using Profile
        ps.putDocument(theShRequest, modifiedDocument);
        logger.debug("Saving data into HSS");
    
        // Store in session the SIP SH Output Request
        session.setAttribute(Constants.SIPAS_OUTPUT, 
             DIAMETERHelper.toString(modifiedDocument));
    
        response = DIAMETERHelper.toString(
                      originalDoc.getDocumentElement());
        logger.debug("HSS Response: \n        " + response);
      } catch (ProfileException e) {
        MessageException me = (MessageException)e.getCause();
        ResultCode rc = me.getResultCode();     
        session.setAttribute(Constants.DIAMETER_RESULT_CODE, 
                             rc.toString());
        session.setAttribute("Exception", e.getMessage());
        logger.debug("Exception - DIAMETER Result Code is: " + 
                     rc.toString() );
      } catch (Exception e) {
        response = e.getMessage();
        session.setAttribute("Exception", e.getMessage());
        logger.debug("Exception: " + response);
      } 
    return response;
    }