Search in sources :

Example 6 with CreditControlUnit

use of org.mobicents.charging.server.account.CreditControlUnit in project charging-server by RestComm.

the class DiameterChargingServerSbb method collectUsedUnits.

private ArrayList<CreditControlUnit> collectUsedUnits(UsedServiceUnitAvp[] usuAvps, ArrayList<CreditControlUnit> reservedCCUnits) {
    if (tracer.isInfoEnabled()) {
        tracer.info("[><] " + sidString + " Collecting " + usuAvps.length + " Used Units AVPs.");
    }
    ArrayList<CreditControlUnit> usedCCUnits = new ArrayList<CreditControlUnit>();
    for (UsedServiceUnitAvp usuAvp : usuAvps) {
        for (int n = 0; n < CcUnitType.values().length; n++) {
            CcUnitType type = CcUnitType.fromInt(n);
            // MONEY is not supported by 3GPP
            if (type == CcUnitType.MONEY) {
                continue;
            }
            String methodName = "getCreditControl" + toCamelCase(type.toString());
            try {
                Method m = usuAvp.getClass().getMethod(methodName);
                long value = (Long) m.invoke(usuAvp);
                if (value == Long.MIN_VALUE) {
                    // It means the AVP was not present.. no null or NoSuchAvpException :(
                    continue;
                }
                if (tracer.isInfoEnabled()) {
                    tracer.info("[><] " + sidString + " Got " + value + " Used Units of type '" + type.toString() + "' ");
                }
                CreditControlUnit ccUnit = new CreditControlUnit();
                ccUnit.setUnitType(type);
                ccUnit.setUsedUnits(ccUnit.getUsedUnits() + value);
                // If we can find Reserved Units and Rate Information, let's fill with it
                for (CreditControlUnit reservedCCUnit : reservedCCUnits) {
                    if (reservedCCUnit.getUnitType() == type) {
                        // Copy the reserved amount from the last session into this session so that ABMF can update used units.
                        ccUnit.setReservedUnits(reservedCCUnit.getReservedUnits());
                        ccUnit.setReservedAmount(reservedCCUnit.getReservedAmount());
                        ccUnit.setUsedAmount((long) Math.ceil(reservedCCUnit.getRateForService() * ccUnit.getUsedUnits()));
                        ccUnit.setRateForService(reservedCCUnit.getRateForService());
                    }
                }
                usedCCUnits.add(ccUnit);
            } catch (Exception e) {
                tracer.severe("[xx] " + sidString + " Unable to retrieve/invoke '" + methodName + "' for extracting Used Units of type " + type, e);
            }
        }
    }
    return usedCCUnits;
}
Also used : CcUnitType(net.java.slee.resource.diameter.cca.events.avp.CcUnitType) ArrayList(java.util.ArrayList) Method(java.lang.reflect.Method) UsedServiceUnitAvp(net.java.slee.resource.diameter.cca.events.avp.UsedServiceUnitAvp) CreateException(javax.slee.CreateException) IOException(java.io.IOException) SLEEException(javax.slee.SLEEException) CreditControlUnit(org.mobicents.charging.server.account.CreditControlUnit)

Example 7 with CreditControlUnit

use of org.mobicents.charging.server.account.CreditControlUnit in project charging-server by RestComm.

the class ReserveUnitsJdbcTask method executeSimple.

@Override
public Object executeSimple(JdbcTaskContext taskContext) {
    try {
        long balance = 0;
        // get Balance Before (can this be made more efficient?)
        PreparedStatement preparedStatement = taskContext.getConnection().prepareStatement(DataSourceSchemaInfo._QUERY_SELECT);
        preparedStatement.setString(1, msisdn);
        preparedStatement.execute();
        ResultSet resultSet = preparedStatement.getResultSet();
        while (resultSet.next()) {
            balance = resultSet.getLong(DataSourceSchemaInfo._COL_BALANCE);
            ccInfo.setBalanceBefore(balance);
        }
        for (int i = 0; i < ccUnits.size(); i++) {
            CreditControlUnit ccUnit = ccUnits.get(i);
            if (balance <= 0 && ccUnit.getRateForService() > 0) {
                accountData = new UserAccountData();
                accountData.setMsisdn(msisdn);
                accountData.setBalance(0);
                accountData.setFailure(true);
                ccUnit.setReservedUnits(0);
                ccUnit.setReservedAmount(0);
                if (tracer.isInfoEnabled()) {
                    tracer.info("[//] User does not have sufficient balance for reservation. Balance available: " + balance + ".");
                }
                break;
            } else {
                long reservedAmount = ccUnit.getReservedAmount();
                long usedAmount = ccUnit.getUsedAmount();
                long requestedAmount = ccUnit.getRequestedAmount();
                long requestedUnits = ccUnit.getRequestedUnits();
                if (ccUnit.getRateForService() > 0) {
                    // If RSU < balance, reserve and set GSU=balance
                    if ((reservedAmount - usedAmount + requestedAmount) > balance) {
                        long newRequestedAmount = balance;
                        long newRequestedUnits = (long) Math.floor(newRequestedAmount / ccUnit.getRateForService());
                        if (tracer.isInfoEnabled()) {
                            tracer.info("[//] User does not have sufficient balance for the entire reservation request (" + requestedUnits + " " + ccUnit.getUnitType() + " units @rate=" + ccUnit.getRateForService() + "). Balance available: " + balance + ". Reserving " + newRequestedUnits + " units instead ...");
                        }
                        requestedAmount = newRequestedAmount;
                        requestedUnits = newRequestedUnits;
                    // TODO: Need to set Final Unit Indication for this case.
                    // See http://www.ietf.org/rfc/rfc4006.txt, 8.34.  Final-Unit-Indication AVP
                    }
                }
                int n = 1;
                tracer.info(("[//] Executing DB Statement '" + DataSourceSchemaInfo._QUERY_RESERVE).replaceFirst("\\?", String.valueOf(reservedAmount - usedAmount)).replaceFirst("\\?", String.valueOf(requestedAmount)).replaceFirst("\\?", String.valueOf(requestedAmount)).replaceFirst("\\?", msisdn));
                preparedStatement = taskContext.getConnection().prepareStatement(DataSourceSchemaInfo._QUERY_RESERVE);
                preparedStatement.setLong(n++, (reservedAmount - usedAmount));
                preparedStatement.setLong(n++, requestedAmount);
                preparedStatement.setLong(n++, requestedAmount);
                preparedStatement.setString(n++, msisdn);
                accountData = new UserAccountData();
                accountData.setMsisdn(msisdn);
                if (preparedStatement.executeUpdate() == 1) {
                    // ok great, we have successfully reserved the units
                    preparedStatement = taskContext.getConnection().prepareStatement(DataSourceSchemaInfo._QUERY_SELECT);
                    preparedStatement.setString(1, msisdn);
                    // tracer.info(("[//] Executing DB Statement '" + DataSourceSchemaInfo._QUERY_SELECT).replaceFirst("\\?", msisdn));
                    preparedStatement.execute();
                    resultSet = preparedStatement.getResultSet();
                    while (resultSet.next()) {
                        balance = resultSet.getLong(DataSourceSchemaInfo._COL_BALANCE);
                        accountData.setBalance(balance);
                        accountData.setFailure(false);
                        ccUnit.setReservedUnits(requestedUnits);
                        ccUnit.setReservedAmount(requestedAmount);
                        ccInfo.setBalanceAfter(balance);
                    }
                } else {
                    // check what kind of error happened
                    accountData.setBalance(0);
                    accountData.setFailure(true);
                    ccUnit.setReservedUnits(0);
                    ccUnit.setReservedAmount(0);
                }
            }
        }
    } catch (Exception e) {
        tracer.severe("[xx] Failed to execute task to Reserve Units for MSISDN '" + msisdn + "'", e);
    }
    return this;
}
Also used : UserAccountData(org.mobicents.charging.server.data.UserAccountData) ResultSet(java.sql.ResultSet) PreparedStatement(java.sql.PreparedStatement) CreditControlUnit(org.mobicents.charging.server.account.CreditControlUnit)

Aggregations

CreditControlUnit (org.mobicents.charging.server.account.CreditControlUnit)7 ArrayList (java.util.ArrayList)4 IOException (java.io.IOException)3 CreateException (javax.slee.CreateException)3 SLEEException (javax.slee.SLEEException)3 CreditControlInfo (org.mobicents.charging.server.account.CreditControlInfo)3 Method (java.lang.reflect.Method)2 PreparedStatement (java.sql.PreparedStatement)2 ResultSet (java.sql.ResultSet)2 CcUnitType (net.java.slee.resource.diameter.cca.events.avp.CcUnitType)2 MultipleServicesCreditControlAvp (net.java.slee.resource.diameter.cca.events.avp.MultipleServicesCreditControlAvp)2 UsedServiceUnitAvp (net.java.slee.resource.diameter.cca.events.avp.UsedServiceUnitAvp)2 RoCreditControlAnswer (net.java.slee.resource.diameter.ro.events.RoCreditControlAnswer)2 UserAccountData (org.mobicents.charging.server.data.UserAccountData)2 SimpleDateFormat (java.text.SimpleDateFormat)1 Date (java.util.Date)1 FinalUnitIndicationAvp (net.java.slee.resource.diameter.cca.events.avp.FinalUnitIndicationAvp)1 GrantedServiceUnitAvp (net.java.slee.resource.diameter.cca.events.avp.GrantedServiceUnitAvp)1 RequestedActionType (net.java.slee.resource.diameter.cca.events.avp.RequestedActionType)1 RequestedServiceUnitAvp (net.java.slee.resource.diameter.cca.events.avp.RequestedServiceUnitAvp)1