Skip to content

Commit

Permalink
Merge branch 'issue1349_recursive_cdr_fetch'
Browse files Browse the repository at this point in the history
  • Loading branch information
gvagenas committed Sep 15, 2016
2 parents 90e8a7e + 323b311 commit 19b2f64
Show file tree
Hide file tree
Showing 26 changed files with 1,051 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,11 @@
type=#{type}, status=#{status}, auth_token=#{auth_token}, role=#{role}
WHERE sid=#{sid};
</update>

<select id="getSubAccountSids" parameterType="java.util.List" resultType="string">
SELECT sid FROM restcomm_accounts WHERE account_sid IN
<foreach item="item" index="index" collection="list" open="(" separator="," close=")">
#{item}
</foreach>
</select>
</mapper>
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,23 @@
<!-- Issue 153: https://bitbucket.org/telestax/telscale-restcomm/issue/153 -->
<!-- Issue 153: https://bitbucket.org/telestax/telscale-restcomm/issue/110 -->
<select id="getTotalCallDetailRecordByUsingFilters" parameterType="org.mobicents.servlet.restcomm.entities.CallDetailRecordFilter" resultType="int">
SELECT COUNT(*) FROM restcomm_call_detail_records WHERE account_sid=#{accountSid}
SELECT COUNT(*) FROM restcomm_call_detail_records WHERE

<!-- are we counting cdrs from a single account or from an account set -->
<if test="accountSidSet == null">
account_sid=#{accountSid}
</if>
<if test="accountSidSet != null">
<if test="!accountSidSet.isEmpty()">
account_sid IN
<foreach item="item" index="index" collection="accountSidSet" open="(" separator="," close=")">
#{item}
</foreach>
</if>
<if test="accountSidSet.isEmpty()">
account_sid=''
</if>
</if>

<if test="instanceid != null">
AND instanceid like #{instanceid}
Expand Down Expand Up @@ -51,7 +67,23 @@
<!-- Issue 153: https://bitbucket.org/telestax/telscale-restcomm/issue/153 -->
<!-- Issue 153: https://bitbucket.org/telestax/telscale-restcomm/issue/110 -->
<select id="getCallDetailRecordByUsingFilters" parameterType="org.mobicents.servlet.restcomm.entities.CallDetailRecordFilter" resultType="hashmap">
SELECT * FROM restcomm_call_detail_records AS restcomm_call_detail_records WHERE account_sid=#{accountSid}
SELECT * FROM restcomm_call_detail_records AS restcomm_call_detail_records WHERE

<!-- are we retrieving cdrs from a single account or from an account set -->
<if test="accountSidSet == null">
account_sid=#{accountSid}
</if>
<if test="accountSidSet != null">
<if test="!accountSidSet.isEmpty()">
account_sid IN
<foreach item="item" index="index" collection="accountSidSet" open="(" separator="," close=")">
#{item}
</foreach>
</if>
<if test="accountSidSet.isEmpty()">
account_sid=''
</if>
</if>

<if test="instanceid != null">
AND instanceid like #{instanceid}
Expand All @@ -77,9 +109,10 @@
</if>

<if test="endTime != null">
AND end_time &lt;= DATE_ADD(#{endTime},INTERVAL 1 DAY) order by start_time
AND end_time &lt;= DATE_ADD(#{endTime},INTERVAL 1 DAY)
</if>


order by start_time
LIMIT #{limit} OFFSET #{offset}
</select>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,11 @@
UPDATE "restcomm_accounts" SET "date_updated"=#{date_updated}, "email_address"=#{email_address}, "friendly_name"=#{friendly_name},
"type"=#{type}, "status"=#{status}, "auth_token"=#{auth_token}, "role"=#{role} WHERE "sid"=#{sid};
</update>

<select id="getSubAccountSids" parameterType="java.util.List" resultType="string">
SELECT "sid" FROM "restcomm_accounts" WHERE "account_sid" IN
<foreach item="item" index="index" collection="list" open="(" separator="," close=")">
#{item}
</foreach>
</select>
</mapper>
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,23 @@
<!-- Issue 153: https://bitbucket.org/telestax/telscale-restcomm/issue/153 -->
<!-- Issue 153: https://bitbucket.org/telestax/telscale-restcomm/issue/110 -->
<select id="getTotalCallDetailRecordByUsingFilters" parameterType="org.mobicents.servlet.restcomm.entities.CallDetailRecordFilter" resultType="int">
SELECT COUNT(*) FROM "restcomm_call_detail_records" WHERE "account_sid"=#{accountSid}
SELECT COUNT(*) FROM "restcomm_call_detail_records" WHERE

<!-- are we counting cdrs from a single account or from an account set -->
<if test="accountSidSet == null">
"account_sid"=#{accountSid}
</if>
<if test="accountSidSet != null">
<if test="!accountSidSet.isEmpty()">
"account_sid" IN
<foreach item="item" index="index" collection="accountSidSet" open="(" separator="," close=")">
#{item}
</foreach>
</if>
<if test="accountSidSet.isEmpty()">
"account_sid"=''
</if>
</if>

<if test="instanceid != null">
AND "instanceid" like #{instanceid}
Expand Down Expand Up @@ -52,7 +68,23 @@
<!-- Issue 153: https://bitbucket.org/telestax/telscale-restcomm/issue/153 -->
<!-- Issue 153: https://bitbucket.org/telestax/telscale-restcomm/issue/110 -->
<select id="getCallDetailRecordByUsingFilters" parameterType="org.mobicents.servlet.restcomm.entities.CallDetailRecordFilter" resultType="hashmap">
SELECT * FROM "restcomm_call_detail_records" AS "restcomm_call_detail_records" WHERE "account_sid"=#{accountSid}
SELECT * FROM "restcomm_call_detail_records" AS "restcomm_call_detail_records" WHERE

<!-- are we retrieving cdrs from a single account or from an account set -->
<if test="accountSidSet == null">
"account_sid"=#{accountSid}
</if>
<if test="accountSidSet != null">
<if test="!accountSidSet.isEmpty()">
"account_sid" IN
<foreach item="item" index="index" collection="accountSidSet" open="(" separator="," close=")">
#{item}
</foreach>
</if>
<if test="accountSidSet.isEmpty()">
"account_sid"=''
</if>
</if>

<if test="instanceid != null">
AND "instanceid" like #{instanceid}
Expand All @@ -77,9 +109,9 @@
AND "start_time" &gt;= #{startTime}
</if>
<if test="endTime != null">
AND "end_time" &lt;= DATE_ADD(#{endTime},INTERVAL 1 DAY) order by "start_time"
AND "end_time" &lt;= DATE_ADD(#{endTime},INTERVAL 1 DAY)
</if>

order by "start_time"
LIMIT #{limit} OFFSET #{offset}
</select>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,16 @@ public interface AccountsDao {
void removeAccount(Sid sid);

void updateAccount(Account account);

/**
* Returns a list of all sub-accounts under a parent account. All nested sub-accounts in
* any level will be returned.
*
* It will return an empty array in case the parent has no children or the parent does
* not exist.
*
* @param parentAccountSid
* @return list of account sid or null
*/
List<String> getSubAccountSidsRecursive(Sid parentAccountSid);
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,18 @@
@ThreadSafe
public final class MybatisAccountsDao implements AccountsDao {
private static final String namespace = "org.mobicents.servlet.sip.restcomm.dao.AccountsDao.";
private Integer accountRecursionDepth = 4; // maximum value for recursive account queries
private final SqlSessionFactory sessions;

public MybatisAccountsDao(final SqlSessionFactory sessions) {
super();
this.sessions = sessions;
}

public void setAccountRecursionDepth(Integer accountRecursionDepth) {
this.accountRecursionDepth = accountRecursionDepth;
}

@Override
public void addAccount(final Account account) {
final SqlSession session = sessions.openSession();
Expand Down Expand Up @@ -143,6 +148,34 @@ public void updateAccount(final Account account) {
updateAccount(namespace + "updateAccount", account);
}

@Override
public List<String> getSubAccountSidsRecursive(Sid parentAccountSid) {
List<String> parentList = new ArrayList<String>();
parentList.add(parentAccountSid.toString());
List<String> allChildren = new ArrayList<String>();

int depth = 1;
List<String> childrenList = getSubAccountsSids(parentList);
while (childrenList != null && !childrenList.isEmpty() && depth < accountRecursionDepth) {
allChildren.addAll(childrenList);
childrenList = getSubAccountsSids(childrenList); // retrieve children's children

depth ++;
}

return allChildren;
}

private List<String> getSubAccountsSids(List<String> parentAccountSidList) {
final SqlSession session = sessions.openSession();
try {
final List<String> results = session.selectList(namespace + "getSubAccountSids", parentAccountSidList);
return results;
} finally {
session.close();
}
}

private void updateAccount(final String selector, final Account account) {
final SqlSession session = sessions.openSession();
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import org.mobicents.servlet.restcomm.annotations.concurrency.Immutable;

Expand All @@ -33,6 +34,7 @@
public class CallDetailRecordFilter {

private final String accountSid;
private final List<String> accountSidSet; // if not-null we need the cdrs that belong to several accounts
private final String recipient;
private final String sender;
private final String status;
Expand All @@ -44,14 +46,15 @@ public class CallDetailRecordFilter {
private final Integer offset;
private final String instanceid;

public CallDetailRecordFilter(String accountSid, String recipient, String sender, String status, String startTime, String endTime,
String parentCallSid, String conferenceSid, Integer limit, Integer offset) throws ParseException {
this(accountSid,recipient,sender,status,startTime,endTime,parentCallSid, conferenceSid, limit,offset,null);
public CallDetailRecordFilter(String accountSid, List<String> accountSidSet, String recipient, String sender, String status, String startTime, String endTime,
String parentCallSid, String conferenceSid, Integer limit, Integer offset) throws ParseException {
this(accountSid, accountSidSet, recipient,sender,status,startTime,endTime,parentCallSid, conferenceSid, limit,offset,null);
}

public CallDetailRecordFilter(String accountSid, String recipient, String sender, String status, String startTime, String endTime,
String parentCallSid, String conferenceSid, Integer limit, Integer offset, String instanceId) throws ParseException {
public CallDetailRecordFilter(String accountSid, List<String> accountSidSet, String recipient, String sender, String status, String startTime, String endTime,
String parentCallSid, String conferenceSid, Integer limit, Integer offset, String instanceId) throws ParseException {
this.accountSid = accountSid;
this.accountSidSet = accountSidSet;

// The LIKE keyword uses '%' to match any (including 0) number of characters, and '_' to match exactly one character
// Add here the '%' keyword so +15126002188 will be the same as 15126002188 and 6002188
Expand Down Expand Up @@ -92,6 +95,10 @@ public String getSid() {
return accountSid;
}

public List<String> getAccountSidSet() {
return accountSidSet;
}

public String getRecipient() {
return recipient;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
package org.mobicents.servlet.restcomm.dao.mybatis;

import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.List;

import junit.framework.Assert;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mobicents.servlet.restcomm.dao.AccountsDao;
import org.mobicents.servlet.restcomm.entities.Account;
import org.mobicents.servlet.restcomm.entities.Sid;

public class AccountsDaoTest {
public class AccountsDaoTest extends DaoTest {
private static MybatisDaoManager manager;

public AccountsDaoTest() {
Expand All @@ -17,7 +24,12 @@ public AccountsDaoTest() {

@Before
public void before() throws Exception {
final InputStream data = getClass().getResourceAsStream("/mybatis.xml");
sandboxRoot = createTempDir("accountsTest");
String mybatisFilesPath = getClass().getResource("/accountsDao").getFile();
setupSandbox(mybatisFilesPath, sandboxRoot);

String mybatisXmlPath = sandboxRoot.getPath() + "/mybatis_updated.xml";
final InputStream data = new FileInputStream(mybatisXmlPath);
final SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
final SqlSessionFactory factory = builder.build(data);
manager = new MybatisDaoManager();
Expand All @@ -27,10 +39,40 @@ public void before() throws Exception {
@After
public void after() throws Exception {
manager.shutdown();
removeTempDir(sandboxRoot.getAbsolutePath());
}

@Test
public void createReadUpdateDelete() {
public void readAccount() {
AccountsDao dao = manager.getAccountsDao();
Account account = dao.getAccount(new Sid("AC00000000000000000000000000000000"));
Assert.assertNotNull("Account not found",account);
}

@Test
public void nestedSubAccountRetrieval() {
// retrieve all sub-accounts of AC00000000000000000000000000000000
AccountsDao dao = manager.getAccountsDao();
Sid parentSid = new Sid("AC00000000000000000000000000000000");
List<String> sidList = dao.getSubAccountSidsRecursive(parentSid);
Assert.assertEquals("Invalid number of subaccounts returned",5, sidList.size());
// a parent with no sub-accounts should get zero
parentSid = new Sid("AC99999999999999999999999999999999");
sidList = dao.getSubAccountSidsRecursive(parentSid);
Assert.assertEquals("No sub-account sids should be returned", 0, sidList.size());
// check 2nd-level parents too
parentSid = new Sid("AC10000000000000000000000000000000");
sidList = dao.getSubAccountSidsRecursive(parentSid);
Assert.assertEquals("Invalid number of sub-account for 2nd level perent", 3, sidList.size());
// check third-level perent too
parentSid = new Sid("AC11000000000000000000000000000000");
sidList = dao.getSubAccountSidsRecursive(parentSid);
Assert.assertEquals("Invalid number of sub-account for 3rd level perent", 1, sidList.size());
// test behaviour for non-existing parents. An empty list should be returned
parentSid = new Sid("AC59494830204948392023934839392092"); // this does not exist
sidList = dao.getSubAccountSidsRecursive(parentSid);
Assert.assertEquals("Invalid number of sub-account for 3rd level perent", 0, sidList.size());

}

}
Loading

0 comments on commit 19b2f64

Please sign in to comment.