Determining the Number of Accounts
In this document, we will explain the process of determining the number of accounts based on various filters. The process involves initializing an AccountsResource
The flow starts by initializing an AccountsResource
ACCOUNT_AVAILABLE_BALANCE
ACCOUNT_NUMBER
ACCOUNT_CUSTOMER_NUMBER
Here is a high level diagram of the flow, showing only the most important functions:
Flow drill down
First, we'll zoom into this section of the flow:
howMany
function
howMany
The howMany
AccountsResource
ACCOUNT_AVAILABLE_BALANCE
getAccountsByBalanceWithOffsetAndLimitExternal
ACCOUNT_NUMBER
getAccountExternal
ACCOUNT_CUSTOMER_NUMBER
getAccountsByCustomerExternal
getAccountsExternal
public int howMany(String filter)
{
// AND ACCOUNT_NUMBER = 0000000024
// AND ACCOUNT_CUSTOMER_NUMBER
AccountsResource myAccountsResource = new AccountsResource();
Response myAccountsResponse = null;
this.count = 0;
try
{
if (filter.contains("AND ACCOUNT_AVAILABLE_BALANCE"))
{
// 01234567890123456789012345678901234567890
// AND ACCOUNT_AVAILABLE_BALANCE <= 33558.0
String operator = filter.substring(31, 32);
BigDecimal balance = BigDecimal
.valueOf(Double.parseDouble(filter.substring(34)));
getAccountsByCustomerExternal
function
getAccountsByCustomerExternal
The getAccountsByCustomerExternal
getAccountsByCustomerInternal
HBankDataAccess
@GET
@Path("/retrieveByCustomerNumber/{customerNumber}")
@Produces("application/json")
public Response getAccountsByCustomerExternal(
@PathParam(JSON_CUSTOMER_NUMBER) Long customerNumber,
@QueryParam("countOnly") Boolean countOnly)
{
/** This will list accounts owned by a specified customer */
logger.entering(this.getClass().getName(),
"getAccountsByCustomerExternal(Long customerNumber, Boolean countOnly)");
Response myResponse = getAccountsByCustomerInternal(customerNumber);
HBankDataAccess myHBankDataAccess = new HBankDataAccess();
myHBankDataAccess.terminate();
logger.exiting(this.getClass().getName(),
"getAccountsByCustomerExternal(Long customerNumber, Boolean countOnly)",
myResponse);
return myResponse;
}
getAccountsExternal
function
getAccountsExternal
The getAccountsExternal
getAccountsInternal
HBankDataAccess
@GET
@Produces("application/json")
public Response getAccountsExternal(@QueryParam("limit") Integer limit,
@QueryParam("offset") Integer offset,
@QueryParam("countOnly") Boolean countOnly)
{
// This method returns a fixed number of accounts, up to limit "limit",
// starting at offset "offset"
logger.entering(this.getClass().getName(),
"getAccountsExternal(Integer limit, Integer offset,Boolean countOnly)");
boolean countOnlyReal = false;
if (countOnly != null)
{
countOnlyReal = countOnly.booleanValue();
}
Response myResponse = getAccountsInternal(limit, offset, countOnlyReal);
HBankDataAccess myHBankDataAccess = new HBankDataAccess();
myHBankDataAccess.terminate();
logger.exiting(this.getClass().getName(),
"getAccountsExternal(Integer limit, Integer offset,Boolean countOnly)",
myResponse);
getAccountsInternal
function
getAccountsInternal
The getAccountsInternal
getAccountsCountOnly
public Response getAccountsInternal(Integer limit, Integer offset,
boolean countOnly)
{
logger.entering(this.getClass().getName(),
"getAccountsInternal(Integer limit, Integer offset,boolean countOnly)");
Response myResponse = null;
com.ibm.cics.cip.bankliberty.web.db2.Account db2Account = null;
JSONObject response = new JSONObject();
JSONArray accounts = null;
int numberOfAccounts = 0;
Integer sortCode = this.getSortCode();
// We want to set a limit to try to avoid OutOfMemory Exceptions.
// 250,000 seems a bit large
if (limit == null)
{
limit = 250000;
}
if (limit == 0)
{
limit = 250000;
getAccountsByCustomerInternal
function
getAccountsByCustomerInternal
The getAccountsByCustomerInternal
getCustomerInternal
public Response getAccountsByCustomerInternal(
@PathParam(JSON_CUSTOMER_NUMBER) Long customerNumber)
{
logger.entering(this.getClass().getName(),
GET_ACCOUNTS_BY_CUSTOMER_INTERNAL);
JSONArray accounts = null;
Response myResponse = null;
JSONObject response = new JSONObject();
Integer sortCode = this.getSortCode();
int numberOfAccounts = 0;
CustomerResource myCustomer = new CustomerResource();
Response customerResponse = myCustomer
.getCustomerInternal(customerNumber);
if (customerResponse.getStatus() != 200)
{
if (customerResponse.getStatus() == 404)
{
Now, lets zoom into this section of the flow:
Handling account retrieval based on balance
First, the getAccountsByBalanceWithOffsetAndLimitExternal
countOnly
getAccountsByBalanceWithOffsetAndLimitInternal
@GET
@Path("/balance")
@Produces("application/json")
public Response getAccountsByBalanceWithOffsetAndLimitExternal(
@QueryParam("balance") BigDecimal balance,
@QueryParam("operator") String operator,
@QueryParam("offset") Integer offset,
@QueryParam("limit") Integer limit,
@QueryParam("countOnly") Boolean countOnly)
{
// return only accounts with a certain balance
logger.entering(this.getClass().getName(),
"getAccountsByBalanceWithOffsetAndLimitExternal(BigDecimal balance, String operator, Integer offset, Integer limit, Boolean countOnly");
boolean countOnlyReal = false;
if (countOnly != null)
{
countOnlyReal = countOnly.booleanValue();
}
Response myResponse = getAccountsByBalanceWithOffsetAndLimitInternal(
balance, operator, offset, limit, countOnlyReal);
Next, the getAccountsByBalanceWithOffsetAndLimitInternal
Account
public Response getAccountsByBalanceWithOffsetAndLimitInternal(
@QueryParam("balance") BigDecimal balance,
@QueryParam("operator") String operator,
@QueryParam("offset") Integer offset,
@QueryParam("limit") Integer limit, boolean countOnly)
{
// return only accounts with a certain balance
logger.entering(this.getClass().getName(),
GET_ACCOUNTS_BY_BALANCE_WITH_OFFSET_AND_LIMIT_INTERNAL);
Response myResponse = null;
boolean lessThan;
if (!operator.startsWith("<") && !(operator.startsWith(">")))
{
JSONObject error = new JSONObject();
error.put(JSON_ERROR_MSG, "Invalid operator, '" + operator
+ "' only <= or >= allowed");
logger.log(Level.WARNING, () -> "Invalid operator, '" + operator
+ "' only <= or >= allowed");
logger.exiting(this.getClass().getName(),
GET_ACCOUNTS_BY_BALANCE_WITH_OFFSET_AND_LIMIT_INTERNAL,
myResponse);
Then, the getAccountsByBalance
Account
public Account[] getAccountsByBalance(Integer sortCode2, BigDecimal balance,
boolean lessThan)
{
logger.entering(this.getClass().getName(), GET_ACCOUNTS_BY_BALANCE);
openConnection();
Account[] temp = new Account[250000];
int i = 0;
StringBuilder myStringBuilder = new StringBuilder();
for (i = sortCode2.toString().length(); i < SORT_CODE_LENGTH; i++)
{
myStringBuilder.append('0');
}
myStringBuilder.append(sortCode2.toString());
String sortCodeString = myStringBuilder.toString();
String sql = "SELECT * from ACCOUNT where ACCOUNT_EYECATCHER LIKE 'ACCT' AND ACCOUNT_SORTCODE like ? ";
if (lessThan)
{
sql = sql.concat(SQL_LESS_THAN);
Alternatively, if only the count of accounts is needed, the getAccountsByBalanceCountOnly
public int getAccountsByBalanceCountOnly(Integer sortCode2,
BigDecimal balance, boolean lessThan)
{
logger.entering(this.getClass().getName(),
GET_ACCOUNTS_BY_BALANCE_COUNT_ONLY);
int accountCount = 0;
openConnection();
String sortCodeString = padSortCode(sortCode2);
String sql = "SELECT COUNT(*) AS ACCOUNT_COUNT from ACCOUNT where ACCOUNT_EYECATCHER LIKE 'ACCT' AND ACCOUNT_SORTCODE like ?";
if (lessThan)
{
sql = sql.concat(SQL_LESS_THAN);
}
else
{
sql = sql.concat(SQL_MORE_THAN);
}
try (PreparedStatement stmt = conn.prepareStatement(sql);)
Finally, the openConnection
HBankDataAccess
DB2
protected void openConnection()
{
// Open a connection to the DB2 database
logger.entering(this.getClass().getName(), "openConnection()");
Integer taskNumberInteger = Task.getTask().getTaskNumber();
String db2ConnString = DB2CONN.concat(taskNumberInteger.toString());
logger.log(Level.FINE,
() -> "Attempting to get DB2CONN for task number "
+ taskNumberInteger.toString());
this.conn = (Connection) cornedBeef.get(db2ConnString);
if (this.conn == null)
{
HBankDataAccess.incrementConnCount();
logger.log(Level.FINE,
() -> "Attempting to create DB2CONN for task number "
+ taskNumberInteger.toString());
// Attempt to open a connection
openConnectionInternal();
logger.log(Level.FINE,
() -> "Creation succcessful for DB2CONN for task number "
Where is this flow used?
This flow is used multiple times in the codebase as represented in the following diagram:
This is an auto-generated document by Swimm 🌊 and has not yet been verified by a human