Key/value replicated storage uses an external database cluster to store session state.
See Replication Support Services for information on the Rhino key/value store as well as the Session Ownership Facility.
To use this replication method:
the application must be deployed on Rhino 2.6.2 or higher,
the Rhino Session Ownership Facility must be configured,
a Key/Value Store must be configured,
the namespace in which the application is running must have the Session Ownership Facility enabled and be configured to use the
KeyValueDatabasereplicated storage resource, and
the service managing the session must write a Diameter session ownership record linked to the convergence name session ownership record.
When using this method, the
ReplicateByDefault RA configuration property controls whether sessions are written to the key/value store immediately on creation (
true) or only after
startReplicating() is called on a particular session (
When session replication is enabled, credit-control session state is written to the external key/value store. If a node handling a charging session within a cluster fails after any hardware, software, or network error, the next event related to that session which occurs on a different node in the cluster will cause the credit-control session to be "adopted" by that node. The adoption is performed using a CAS race on the convergence name session ownership record.
The event triggering the adoption race could be any event related to the overall session such as:
a RAR or ASR sent from the OCS to a different node,
a SIP dialog routed to a different node, or
a timer event from a redundantly armed session timer.
This method also support proxying of
Abort-Session-Request messages between nodes.
Proxying could occur if, for example, a client charging session has been adopted by another node and the original node handling the session has come back up. The OCS could send a RAR or ASR to the original node even though a new node is now handling the session. In this case, the session ownership record will be consulted and the request will be proxied to the owning node. The corresponding RAA or ASA will be proxied back to the receiving node to send back to the OCS.
The ownership of a session is determined by the convergence name session ownership record. Each protocol involved in the overall session also has its own record linked to the convergence name record. For the key/value replication method to work, these session ownership records must be written by the application.
The convergence name session ownership record is created and managed by Rhino.
A service can retrieve it using
The Diameter session ownership record must be written by the service with:
its primary key set to the value returned by
getTrackingKey()on the CCA/Ro/Gx charging session activity,
an owner URI set to the value returned by
getInternalASURI()on the CCA/Ro/Gx provider, and
an associated record attribute with the value being the primary key of the convergence name record.
The following is a brief example of a service using the Diameter Ro RA for a fault-tolerant client charging session using the key/value store.
If the Diameter Ro RA is configured with
ReplicateByDefault set to
false, then the service should call
startReplicating() on the client charging session when the application determines that the overall session (likely involving other protocols) is confirmed.
RoClientSessionActivity roClientSessionActivity = (RoClientSessionActivity) aci.getActivity(); roClientSessionActivity.startReplicating();
At the same time the service should write a session ownership record for the Diameter Ro charging session:
RoClientSessionActivity roClientSessionActivity = (RoClientSessionActivity) aci.getActivity(); // Values for the Diameter session ownership record String roTrackingKey = roClientSessionActivity.getTrackingKey(); String ownerUri = roProviderFactory.getInternalASURI().toString(); String associatedRecordKey = ((RhinoSbbContext) getSbbContext()).getConvergenceNameSessionOwnershipRecord().getPrimaryKey() // Build the record SessionOwnershipRecord.Builder recordBuilder = SessionOwnershipRecord.newBuilder() .setPrimaryKey(roTrackingKey) .addOwnerURI(ownerUri); recordBuilder.addAttribute(SessionOwnershipRecord.ASSOCIATED_RECORD_ATTRIBUTE_NAME, associatedRecordKey); SessionOwnershipRecord record = recordBuilder.build(); // Create an activity to handle the write operation SessionOwnershipActivity sessionOwnershipActivity = sessionOwnershipProvider.createSessionOwnershipActivity(); // To be notified of the result of the write operation the SBB must // attach to the session ownership activity ACI and handle the // corresponding SessionOwnershipWriteResultEvent. ActivityContextInterface aci = sessionOwnershipAciFactory.getActivityContextInterface(sessionOwnershipActivity); aci.attach(getSbbLocalObject()); // write the session ownership record asynchronously sessionOwnershipActivity.storeRecord(record);
When the charging session has finished (on receipt of CCA-T or an unrecoverable error) the service should remove the session ownership record:
String roTrackingKey = roClientSessionActivity.getTrackingKey(); // Create an activity to handle the delete operation SessionOwnershipActivity sessionOwnershipActivity = sessionOwnershipProvider.createSessionOwnershipActivity(); // To be notified of the result of the delete operation the SBB must // attach to the session ownership activity ACI and handle the // corresponding SessionOwnershipWriteResultEvent. ActivityContextInterface aci = sessionOwnershipAciFactory.getActivityContextInterface(sessionOwnershipActivity); aci.attach(getSbbLocalObject()); // delete the session ownership record asynchronously sessionOwnershipActivity.deleteRecord(roTrackingKey, Collections.<String>emptySet());