diff --git a/campaign/src/main/java/com/pudonghot/yo/campaign/feign/response/RespCallingList.java b/campaign/src/main/java/com/pudonghot/yo/campaign/feign/response/RespCallingList.java index da3a96a2..973c6c17 100644 --- a/campaign/src/main/java/com/pudonghot/yo/campaign/feign/response/RespCallingList.java +++ b/campaign/src/main/java/com/pudonghot/yo/campaign/feign/response/RespCallingList.java @@ -3,10 +3,7 @@ package com.pudonghot.yo.campaign.feign.response; import lombok.Getter; import lombok.Setter; import lombok.ToString; -import org.apache.commons.lang3.tuple.Pair; -import com.pudonghot.yo.util.PhoneNumberUtils; import com.fasterxml.jackson.annotation.JsonAlias; -import com.fasterxml.jackson.annotation.JsonProperty; /** * @author Donghuang @@ -16,35 +13,25 @@ import com.fasterxml.jackson.annotation.JsonProperty; @Setter @ToString public class RespCallingList { - @JsonProperty("retcode") + @JsonAlias("retcode") private String code; - @JsonProperty("message") + @JsonAlias("message") private String error; - @JsonProperty("taskid") + @JsonAlias("taskid") private String campaignKey; - @JsonAlias("taskName") - @JsonProperty("taskname") + @JsonAlias({"taskName", "taskname"}) private String campaignName; - @JsonProperty("taskdata") + @JsonAlias("taskdata") private CallingData[] data; @Getter @Setter public static class CallingData { - @JsonProperty("outid") + @JsonAlias("outid") private String caseKey; private String phone; - /** - * to pair (phone, caseKey) - * - * @return pair - */ - public Pair toPair() { - return Pair.of(PhoneNumberUtils.cleanupMobile(phone), caseKey); - } - /** * {@inheritDoc} */ diff --git a/campaign/src/main/java/com/pudonghot/yo/campaign/feign/response/RespCallingListWrapper.java b/campaign/src/main/java/com/pudonghot/yo/campaign/feign/response/RespCallingListWrapper.java deleted file mode 100644 index 8a1e1b71..00000000 --- a/campaign/src/main/java/com/pudonghot/yo/campaign/feign/response/RespCallingListWrapper.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.pudonghot.yo.campaign.feign.response; - -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; -import com.fasterxml.jackson.annotation.JsonProperty; - -/** - * @author Donghuang - * @date Jul 22, 2020 14:17:40 - */ -@Getter -@Setter -@ToString -public class RespCallingListWrapper { - private String code; - @JsonProperty("message") - private String error; - private RespCallingList data; - - /** - * is response success - * - * @return true if code == 000000 - */ - public boolean isSuccess() { - return "000000".equals(code); - } -} diff --git a/campaign/src/main/java/com/pudonghot/yo/campaign/service/CallingListService.java b/campaign/src/main/java/com/pudonghot/yo/campaign/service/CallingListService.java index bc6cf63d..cd00d1fb 100644 --- a/campaign/src/main/java/com/pudonghot/yo/campaign/service/CallingListService.java +++ b/campaign/src/main/java/com/pudonghot/yo/campaign/service/CallingListService.java @@ -1,6 +1,7 @@ package com.pudonghot.yo.campaign.service; import java.util.List; +import com.pudonghot.yo.model.domain.Campaign; import com.wacai.tigon.service.BaseCrudService; import com.pudonghot.yo.model.domain.CallingList; @@ -10,6 +11,12 @@ import com.pudonghot.yo.model.domain.CallingList; */ public interface CallingListService extends BaseCrudService { + /** + * fetch remote calling list + * @param campaign campaign + */ + void fetchRemote(Campaign campaign); + /** * list limit ready records * @@ -17,11 +24,5 @@ public interface CallingListService extends BaseCrudService listReady(final Integer campaignId, final int limit); - - /** - * release calling list lock - * @param callingList callingList - */ - void releaseCallingListLock(final CallingList callingList); + List listReady(Integer campaignId, int limit); } diff --git a/campaign/src/main/java/com/pudonghot/yo/campaign/service/CampaignService.java b/campaign/src/main/java/com/pudonghot/yo/campaign/service/CampaignService.java index a80a3df7..ee33069a 100644 --- a/campaign/src/main/java/com/pudonghot/yo/campaign/service/CampaignService.java +++ b/campaign/src/main/java/com/pudonghot/yo/campaign/service/CampaignService.java @@ -8,4 +8,10 @@ import com.wacai.tigon.service.BaseQueryService; * @date Jul 18, 2020 17:24:50 */ public interface CampaignService extends BaseQueryService { + + /** + * dial campaign call + * @param campaign campaign + */ + void dial(final Campaign campaign); } diff --git a/campaign/src/main/java/com/pudonghot/yo/campaign/service/impl/CallingListServiceImpl.java b/campaign/src/main/java/com/pudonghot/yo/campaign/service/impl/CallingListServiceImpl.java index 5234cb4d..64134b4c 100644 --- a/campaign/src/main/java/com/pudonghot/yo/campaign/service/impl/CallingListServiceImpl.java +++ b/campaign/src/main/java/com/pudonghot/yo/campaign/service/impl/CallingListServiceImpl.java @@ -3,20 +3,31 @@ package com.pudonghot.yo.campaign.service.impl; import java.util.Map; import java.util.Date; import java.util.List; +import lombok.Setter; import java.util.HashMap; +import java.util.stream.Stream; import lombok.extern.slf4j.Slf4j; -import com.pudonghot.yo.util.TimeUtils; +import java.util.stream.Collectors; import com.wacai.tigon.mybatis.Search; +import com.pudonghot.yo.util.TimeUtils; import com.wacai.tigon.sequence.IdSequence; -import org.apache.commons.lang3.time.DateUtils; +import org.apache.commons.lang3.StringUtils; +import com.pudonghot.yo.model.domain.Campaign; +import com.pudonghot.yo.util.PhoneNumberUtils; import org.springframework.stereotype.Service; +import org.apache.commons.lang3.time.DateUtils; import com.pudonghot.yo.mapper.CallingListMapper; import com.pudonghot.yo.model.domain.CallingList; +import org.springframework.context.annotation.Lazy; +import com.pudonghot.yo.campaign.service.CampaignService; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Scheduled; import com.pudonghot.yo.campaign.service.CallingListService; import com.wacai.tigon.service.support.BaseCrudServiceSupport; import org.springframework.beans.factory.annotation.Autowired; +import com.pudonghot.yo.campaign.feign.response.RespCallingList; +import static com.pudonghot.yo.model.domain.Campaign.TargetType.QUEUE; +import com.pudonghot.yo.campaign.feign.service.FeignCallingListService; /** * @author Donghuang @@ -28,23 +39,48 @@ public class CallingListServiceImpl extends BaseCrudServiceSupport implements CallingListService { + @Setter(onMethod_ = {@Lazy, @Autowired}) + private CampaignService campaignService; @Autowired private IdSequence idSeq; + @Autowired + private FeignCallingListService callingListService; - @Value("${yo.br.campaign.callinglist-lock-expire.seconds:300}") + @Value("${yo.campaign.calling-list-lock-expire.seconds:300}") private int expireLockDuration; + @Value("${yo.campaign.calling-list.fetch-size:24}") + private int fetchSize; - @Scheduled(fixedRateString = "${yo.br.campaign.callinglist-lock-expire.rate:180000}") + @Scheduled(fixedRateString = "${yo.campaign.callinglist-lock-expire.rate:120000}") public void expireLock() { - log.info("Expire calling list lock task"); - final Date expireTime = DateUtils.addSeconds(new Date(), -expireLockDuration); - scan(new Search(CallingList.ACTIVE, true) - .gt(CallingList.CREATED_TIME, DateUtils.addDays(new Date(), -1)) - .notNull(CallingList.LAST_CONN_ID) - .lt(CallingList.LOCK_TIME, expireTime), callingList -> { - callingList.setLockTime(null); - callingList.setLockKey(null); - mapper.update(callingList); + log.info("Expire calling list lock task."); + final Map update = new HashMap<>(8); + update.put(CallingList.LOCK_KEY, null); + update.put(CallingList.LOCK_TIME, null); + update.put(CallingList.UPDATED_TIME, new Date()); + + mapper.update(update, + new Search(CallingList.ACTIVE, true) + .gt(CallingList.ADDED_TIME, DateUtils.addDays(new Date(), -1)) + .lt(CallingList.LOCK_TIME, + DateUtils.addSeconds(new Date(), -expireLockDuration))); + } + + @Scheduled(fixedRateString = "${yo.campaign.task-scheduler.fixed-rate:180000}", + initialDelayString = "${yo.campaign.task-scheduler.init-delay:32000}") + public void fetchRemoteTaskScheduler() { + log.debug("Campaign fetch remote calling list task."); + final int secondOfDay = TimeUtils.secondOfDay(new Date()); + campaignService.scan(new Search(Campaign.ACTIVE, true) + .eq(Campaign.STATUS, Campaign.Status.RUNNING) + .lt(Campaign.DAILY_FROM, secondOfDay) + .gt(Campaign.DAILY_TO, secondOfDay), campaign -> { + + if (campaign.getTargetType() != QUEUE) { + log.info("Campaign [{}] target is not queue, ignore.", campaign); + return; + } + fetchRemote(campaign); }); } @@ -52,34 +88,71 @@ public class CallingListServiceImpl * {@inheritDoc} */ @Override - public List listReady(final Integer campaignId, int limit) { - final String lockKey = idSeq.get(); - final Map update = new HashMap<>(8); - update.put(CallingList.LOCK_KEY, lockKey); - update.put(CallingList.LOCK_TIME, new Date()); - update.put(CallingList.STATUS, CallingList.Status.ACHIEVED); + public void fetchRemote(final Campaign campaign) { + log.info("campaign [{}] fetch calling list data.", campaign); - final int time = TimeUtils.secondOfDay(new Date()); + final Integer campaignId = campaign.getId(); + final String campaignKey = campaign.getCampaignKey(); + final RespCallingList callingList = + callingListService.fetchCallingList(fetchSize, + campaignKey, + campaign.getName()); + final RespCallingList.CallingData[] data = + callingList.getData(); - mapper.update(update, - new Search(CallingList.CAMPAIGN_ID, campaignId) - .eq(CallingList.STATUS, CallingList.Status.READY) - .isNull(CallingList.LOCK_KEY) - .lt(CallingList.DAILY_FROM, time) - .gt(CallingList.DAILY_TO, time) - .limit(limit)); + if (data == null || data.length == 0) { + log.error("Fetch calling list data error caused. code [{}], error [{}].", + callingList.getCode(), callingList.getError()); + return; + } - return mapper.list(new Search(CallingList.CAMPAIGN_ID, campaignId) - .eq(CallingList.LOCK_KEY, lockKey).limit(limit)); + if (log.isInfoEnabled()) { + log.info("CallingListData: [{}][{}][{}]", + campaignId, campaignKey, StringUtils.join(data, "|")); + } + + mapper.insert(Stream.of(data).map(it -> { + final CallingList cl = new CallingList(); + cl.setTenantId(campaign.getTenantId()); + cl.setTenantCode(campaign.getTenantCode()); + cl.setCampaignId(campaignId); + cl.setCampaignKey(campaignKey); + cl.setDailyFrom(campaign.getDailyFrom()); + cl.setDailyTo(campaign.getDailyTo()); + cl.setStatus(CallingList.Status.READY); + cl.setCaseKey(it.getCaseKey()); + cl.setPhone(PhoneNumberUtils.cleanupMobile(it.getPhone())); + cl.setLastConnected(false); + final Date now = new Date(); + cl.setAddedTime(now); + cl.setCalledTimes(0); + cl.setCreatedTime(now); + return cl; + }).collect(Collectors.toList())); } /** * {@inheritDoc} */ @Override - public void releaseCallingListLock(final CallingList callingList) { - callingList.setLockKey(null); - callingList.setLockTime(null); - mapper.update(callingList); + public List listReady(final Integer campaignId, final int limit) { + final String lockKey = idSeq.get(); + final Map update = new HashMap<>(8); + update.put(CallingList.LOCK_KEY, lockKey); + update.put(CallingList.LOCK_TIME, new Date()); + update.put(CallingList.STATUS, CallingList.Status.ACHIEVED); + + final int secondOfDay = TimeUtils.secondOfDay(new Date()); + + mapper.update(update, + new Search(CallingList.CAMPAIGN_ID, campaignId) + .eq(CallingList.STATUS, CallingList.Status.READY) + .isNull(CallingList.LOCK_KEY) + .lt(CallingList.DAILY_FROM, secondOfDay) + .gt(CallingList.DAILY_TO, secondOfDay) + .limit(limit)); + + return mapper.list(new Search(CallingList.CAMPAIGN_ID, campaignId) + .eq(CallingList.LOCK_KEY, lockKey).limit(limit)); } } diff --git a/campaign/src/main/java/com/pudonghot/yo/campaign/service/impl/CampaignServiceImpl.java b/campaign/src/main/java/com/pudonghot/yo/campaign/service/impl/CampaignServiceImpl.java index 4df8705c..271e4560 100644 --- a/campaign/src/main/java/com/pudonghot/yo/campaign/service/impl/CampaignServiceImpl.java +++ b/campaign/src/main/java/com/pudonghot/yo/campaign/service/impl/CampaignServiceImpl.java @@ -1,34 +1,33 @@ package com.pudonghot.yo.campaign.service.impl; +import lombok.val; +import lombok.Setter; import java.util.Date; -import java.util.List; -import java.util.stream.Stream; import lombok.extern.slf4j.Slf4j; -import java.util.function.Consumer; import java.util.stream.Collectors; import java.util.concurrent.TimeUnit; import com.pudonghot.yo.util.LogMDC; import lombok.RequiredArgsConstructor; +import com.pudonghot.yo.util.ListUtils; import com.wacai.tigon.mybatis.Search; import com.pudonghot.yo.util.TimeUtils; -import org.apache.commons.lang3.tuple.Pair; -import org.apache.commons.lang3.StringUtils; import com.pudonghot.yo.mapper.CampaignMapper; import org.springframework.stereotype.Service; import com.pudonghot.yo.model.domain.Campaign; import com.pudonghot.yo.mapper.AgentStatusMapper; +import org.springframework.context.annotation.Lazy; import com.pudonghot.yo.service.CommonCallDataService; import com.pudonghot.yo.fsagent.api.CampaignDialService; import com.pudonghot.yo.campaign.service.CampaignService; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Scheduled; import com.pudonghot.yo.fsagent.api.request.ReqCampaignDial; +import com.pudonghot.yo.campaign.service.CallingListService; import org.springframework.beans.factory.annotation.Autowired; import com.wacai.tigon.service.support.BaseQueryServiceSupport; -import com.pudonghot.yo.campaign.feign.response.RespCallingList; import static com.pudonghot.yo.model.domain.Campaign.TargetType.QUEUE; -import com.pudonghot.yo.campaign.feign.service.FeignCallingListService; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import com.pudonghot.yo.fsagent.api.request.ReqCampaignDial.CallingRecord; /** * @author Donghuang @@ -48,8 +47,8 @@ public class CampaignServiceImpl private int dialBatchSleep; @Autowired private AgentStatusMapper agentStatusMapper; - @Autowired - private FeignCallingListService callingListService; + @Setter(onMethod_ = {@Lazy, @Autowired}) + private CallingListService callingListService; @Autowired private CampaignDialService dialService; @Autowired @@ -57,7 +56,7 @@ public class CampaignServiceImpl @Scheduled(fixedRateString = "${yo.campaign.task-scheduler.fixed-rate:180000}", initialDelayString = "${yo.campaign.task-scheduler.init-delay:32000}") public void taskScheduler() { - final int secondOfDay = TimeUtils.secondOfDay(new Date()); + val secondOfDay = TimeUtils.secondOfDay(new Date()); scan(new Search(Campaign.ACTIVE, true) .eq(Campaign.STATUS, Campaign.Status.RUNNING) .lt(Campaign.DAILY_FROM, secondOfDay) @@ -73,19 +72,23 @@ public class CampaignServiceImpl }); } - void dial(final Campaign campaign) { - final String campaignKey = campaign.getCampaignKey(); + /** + * {@inheritDoc} + */ + @Override + public void dial(final Campaign campaign) { + val campaignKey = campaign.getCampaignKey(); LogMDC.setTraceId(campaignKey); log.info("Campaign [{}] dial.", campaign); - final Integer queueId = campaign.getTargetId(); - final int countOnlineAgentOfQueue = + val queueId = campaign.getTargetId(); + val countOnlineAgentOfQueue = agentStatusMapper.countOnlineOfQueue(queueId); if (countOnlineAgentOfQueue == 0) { log.warn("Campaign has no online agent, ignore."); return; } - final int countIdleAgentOfQueue = + val countIdleAgentOfQueue = agentStatusMapper.countIdleOfQueue(queueId); if (countIdleAgentOfQueue == 0) { @@ -93,9 +96,9 @@ public class CampaignServiceImpl return; } - final Integer campaignId = campaign.getId(); - final int maxChannels = campaign.getNumOfChannels(); - int campaignChannel = + val campaignId = campaign.getId(); + val maxChannels = campaign.getNumOfChannels(); + val campaignChannel = commonCallDataService.getCampaignChannel(campaignId); if (campaignChannel >= maxChannels) { @@ -103,7 +106,7 @@ public class CampaignServiceImpl return; } - final int optimizationValue = campaign.getOptimizationValue(); + val optimizationValue = campaign.getOptimizationValue(); int fetchCount = 0; if (countIdleAgentOfQueue > 4) { if (optimizationValue > 0) { @@ -112,35 +115,24 @@ public class CampaignServiceImpl } } - final RespCallingList callingList = - callingListService.fetchCallingList( - fetchCount > 0 ? fetchCount : countIdleAgentOfQueue, - campaignKey, - campaign.getName()); - final RespCallingList.CallingData[] data = - callingList.getData(); + val callingLists = callingListService.listReady( + campaignId, fetchCount > 0 ? fetchCount : countIdleAgentOfQueue); - if (data == null || data.length == 0) { - log.error("Fetch calling list data error caused. code [{}], message [{}].", - callingList.getCode(), callingList.getError()); + if (callingLists.isEmpty()) { + log.info("No ready calling list found, ignore."); return; } - if (log.isInfoEnabled()) { - log.info("CallingListData: [{}][{}][{}]", - campaignId, campaignKey, StringUtils.join(data, "|")); - } - - final ReqCampaignDial req= new ReqCampaignDial(); + val req = new ReqCampaignDial(); req.setCampaignId(campaignId); - final List> dataList = Stream.of(data) - .map(RespCallingList.CallingData::toPair) - .collect(Collectors.toList()); - eachBatch(dataList, dialBatchSize, cl -> { + val dataList = callingLists.stream() + .map(it -> new CallingRecord(it.getId(), it.getCaseKey(), it.getPhone())) + .collect(Collectors.toList()); + ListUtils.eachBatch(dataList, dialBatchSize, cl -> { req.setCallingList(cl); dialService.queueDial(req); try { - log.debug("Sleep [{}] milliseconds.", dialBatchSize); + log.debug("Sleep [{}] milliseconds.", dialBatchSleep); TimeUnit.MILLISECONDS.sleep(dialBatchSleep); } catch (InterruptedException e) { @@ -148,15 +140,4 @@ public class CampaignServiceImpl } }); } - - void eachBatch( - final List list, - final int batch, - final Consumer> consumer) { - - final int size = list.size(); - for (int i = 0; i < size; i += batch) { - consumer.accept(list.subList(i, Math.min(size, i + batch))); - } - } } diff --git a/campaign/src/main/resources/application.properties b/campaign/src/main/resources/application.properties index fe7acde2..be9f0cb4 100644 --- a/campaign/src/main/resources/application.properties +++ b/campaign/src/main/resources/application.properties @@ -29,6 +29,6 @@ dubbo.registry.file=${user.home}/dubbo-cache/${spring.application.name}/dubbo.ca yo.fsagent.dubbo.service.version=1.0.0 # Calling List -yo.campaign.feign.calling-list.base-url=http://localhost:1116 -yo.campaign.feign.calling-list.channel=campaign.json +yo.campaign.feign.calling-list.base-url=http://localhost:8093/callinglist +yo.campaign.feign.calling-list.channel=dx-hzqw diff --git a/campaign/src/test/java/com/pudonghot/yo/campaign/FeignCallingListServiceTest.java b/campaign/src/test/java/com/pudonghot/yo/campaign/FeignCallingListServiceTest.java index e98d70cf..a41c9a3e 100644 --- a/campaign/src/test/java/com/pudonghot/yo/campaign/FeignCallingListServiceTest.java +++ b/campaign/src/test/java/com/pudonghot/yo/campaign/FeignCallingListServiceTest.java @@ -23,8 +23,8 @@ public class FeignCallingListServiceTest { @Test public void testFetchCallingList() { - final val callingList = - callingListService.fetchCallingList(1, "11223", "44556"); + val callingList = + callingListService.fetchCallingList(1, "5694", "5694"); log.info("Calling list [{}].", callingList); } } diff --git a/campaign/src/test/java/com/pudonghot/yo/campaign/service/CallingListServiceTest.java b/campaign/src/test/java/com/pudonghot/yo/campaign/service/CallingListServiceTest.java new file mode 100644 index 00000000..3a3d5f2b --- /dev/null +++ b/campaign/src/test/java/com/pudonghot/yo/campaign/service/CallingListServiceTest.java @@ -0,0 +1,41 @@ +package com.pudonghot.yo.campaign.service; + +import lombok.val; +import org.junit.Test; +import org.junit.runner.RunWith; +import lombok.extern.slf4j.Slf4j; +import com.wacai.tigon.mybatis.Search; +import com.pudonghot.yo.campaign.YoCampaign; +import com.pudonghot.yo.model.domain.Campaign; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +/** + * @author Donghuang + * @date Sep 13, 2020 22:58:41 + */ +@Slf4j +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(classes = YoCampaign.class) +public class CallingListServiceTest { + @Autowired + private CampaignService campaignService; + @Autowired + private CallingListService callingListService; + + @Test + public void testFetchRemote() { + val campaign = campaignService.find( + new Search(Campaign.CAMPAIGN_KEY, "5694")); + callingListService.fetchRemote(campaign); + } + + @Test + public void testList() { + val campaign = campaignService.find( + new Search(Campaign.CAMPAIGN_KEY, "5694")); + val callingLists = callingListService.listReady(campaign.getId(), 2); + log.info("Calling list [{}]", callingLists); + } +} diff --git a/campaign/src/test/java/com/pudonghot/yo/campaign/service/CampaignServiceTest.java b/campaign/src/test/java/com/pudonghot/yo/campaign/service/CampaignServiceTest.java new file mode 100644 index 00000000..6edee2ca --- /dev/null +++ b/campaign/src/test/java/com/pudonghot/yo/campaign/service/CampaignServiceTest.java @@ -0,0 +1,31 @@ +package com.pudonghot.yo.campaign.service; + +import lombok.val; +import org.junit.Test; +import org.junit.runner.RunWith; +import lombok.extern.slf4j.Slf4j; +import com.wacai.tigon.mybatis.Search; +import com.pudonghot.yo.campaign.YoCampaign; +import com.pudonghot.yo.model.domain.Campaign; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +/** + * @author Donghuang + * @date Sep 13, 2020 23:48:58 + */ +@Slf4j +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(classes = YoCampaign.class) +public class CampaignServiceTest { + @Autowired + private CampaignService campaignService; + + @Test + public void testDial() { + val campaign = campaignService.find( + new Search(Campaign.CAMPAIGN_KEY, "donghuang")); + campaignService.dial(campaign); + } +} diff --git a/fetch-event2.sh b/fetch-event2.sh new file mode 100755 index 00000000..e90ff1c6 --- /dev/null +++ b/fetch-event2.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +if [ -z "$1" ]; then + echo 'Usage: ./fetch-event.sh guid' + exit 1 +fi + +url="http://localhost:8093/openapi/resource/agentevent/donghuang?guid=$1" +echo "Listen URL: $url" +count=0 + +while : ; do + ((++count)) + curl $url + echo + echo "[$count] Event fetched." +done diff --git a/fsagent/src/main/java/com/pudonghot/yo/fsagent/controller/DialController.java b/fsagent/src/main/java/com/pudonghot/yo/fsagent/controller/DialController.java index 2d3a1108..efcbfdf0 100644 --- a/fsagent/src/main/java/com/pudonghot/yo/fsagent/controller/DialController.java +++ b/fsagent/src/main/java/com/pudonghot/yo/fsagent/controller/DialController.java @@ -41,14 +41,16 @@ public class DialController { public List campaignDial( @RequestParam("campaignId") final Integer campaignId, + @RequestParam("recId") + final Integer recId, @RequestParam("caseKey") final String caseKey, @RequestParam("phone") final String calledNumber) { - final val req = new ReqCampaignDial(); + val req = new ReqCampaignDial(); req.setCampaignId(campaignId); - req.setCallingList(Arrays.asList(Pair.of(calledNumber, caseKey))); + req.setCallingList(Arrays.asList(new ReqCampaignDial.CallingRecord(recId, caseKey, calledNumber))); return campaignDialService.queueDial(req); } } diff --git a/fsagent/src/main/java/com/pudonghot/yo/fsagent/listener/CampaignChannelCreate.java b/fsagent/src/main/java/com/pudonghot/yo/fsagent/listener/CampaignChannelCreate.java index 90fd2286..1026095a 100644 --- a/fsagent/src/main/java/com/pudonghot/yo/fsagent/listener/CampaignChannelCreate.java +++ b/fsagent/src/main/java/com/pudonghot/yo/fsagent/listener/CampaignChannelCreate.java @@ -1,8 +1,12 @@ package com.pudonghot.yo.fsagent.listener; +import java.util.Date; import lombok.extern.slf4j.Slf4j; import com.pudonghot.yo.util.LogMDC; +import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; +import com.pudonghot.yo.mapper.CallingListMapper; +import com.pudonghot.yo.model.domain.CallingList; import com.pudonghot.yo.fsagent.util.EslEventUtils; import com.pudonghot.yo.service.CommonCallDataService; import org.freeswitch.esl.client.transport.event.Event; @@ -20,14 +24,15 @@ public class CampaignChannelCreate { @Autowired private CommonCallDataService commonCallDataService; - + @Autowired + private CallingListMapper callingListMapper; /** * {@inheritDoc} */ @Async @EventListener(value = Event.class, - condition = "#root.args[0].getName() == 'CHANNEL_DESTROY'" + + condition = "#root.args[0].getName() == 'CHANNEL_CREATE'" + " and #root.args[0].getDialType() == 'CAMPAIGN'") public void onChannelCreate(final Event event) { final String callId = event.getCallId(); @@ -39,8 +44,38 @@ public class CampaignChannelCreate { if (campaignId != null) { log.info("Increase campaign [{}] dial number.", campaignId); commonCallDataService.incrCampaignChannel(campaignId); - commonCallDataService.incrCampaignDailyDialed(campaignId); + + final String strRecId = event.getRecId(); + if (StringUtils.isNotBlank(strRecId)) { + final Integer recId = Integer.parseInt(strRecId); + final String calledNumber = event.getCalledNumber(); + log.info("Channel created update case [{}:{}] calling list.", strRecId, calledNumber); + final CallingList rec = callingListMapper.find(recId); + + if (rec == null) { + log.warn("No case [{}:{}] calling list found, ignore.", strRecId, calledNumber); + return; + } + + rec.setLastCallStartTime(getCallStartTime(event)); + rec.setCalledTimes(rec.getCalledTimes() + 1); + rec.setStatus(CallingList.Status.DIALING); + rec.setLockKey(null); + rec.setLockTime(null); + rec.setUpdatedTime(new Date()); + rec.setLastConnId(callId); + + callingListMapper.update(rec); + } } } } + + private Date getCallStartTime(final Event event) { + final String startEpoch = event.getHeader("variable_start_epoch"); + if (StringUtils.isNotBlank(startEpoch)) { + return new Date(Long.parseLong(startEpoch) * 1000); + } + return new Date(); + } } diff --git a/fsagent/src/main/java/com/pudonghot/yo/fsagent/listener/CampaignChannelDestroy.java b/fsagent/src/main/java/com/pudonghot/yo/fsagent/listener/CampaignChannelDestroy.java index a9028a85..63c6d91f 100644 --- a/fsagent/src/main/java/com/pudonghot/yo/fsagent/listener/CampaignChannelDestroy.java +++ b/fsagent/src/main/java/com/pudonghot/yo/fsagent/listener/CampaignChannelDestroy.java @@ -3,7 +3,6 @@ package com.pudonghot.yo.fsagent.listener; import java.util.Date; import lombok.extern.slf4j.Slf4j; import com.pudonghot.yo.util.LogMDC; -import com.wacai.tigon.mybatis.Search; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; import com.pudonghot.yo.mapper.CallingListMapper; @@ -49,43 +48,29 @@ public class CampaignChannelDestroy { callDataService.decrCampaignChannel(campaignId); - final String caseKey = event.getHeader("variable_x_case_key"); - if (StringUtils.isNotBlank(caseKey)) { - log.info("Update case [{}] calling list call result.", caseKey); - - final CallingList rec = callingListMapper.find( - new Search(CallingList.CASE_KEY, caseKey) - .desc(CallingList.ID) - .limit(1)); + final String strRecId = event.getRecId(); + if (StringUtils.isNotBlank(strRecId)) { + final Integer recId = Integer.parseInt(strRecId); + final String calledNumber = event.getCalledNumber(); + log.info("Channel destroy update case [{}:{}] calling list call result.", + recId, calledNumber); + final CallingList rec = callingListMapper.find(recId); if (rec == null) { - log.warn("No case [{}] calling list found, ignore.", caseKey); + log.warn("No case [{}:{}] calling list found, ignore.", strRecId, calledNumber); return; } - rec.setCalledTimes(rec.getCalledTimes() + 1); - rec.setLastConnId(event.getConnId()); - rec.setLastCallStartTime(getCallStartTime(event)); final String strBillSec = event.getHeader("variable_billsec"); final Long billSec = StringUtils.isNotBlank(strBillSec) ? Long.parseLong(strBillSec) : 0; rec.setLastCallDuration(billSec); rec.setLastConnected(billSec > 0); rec.setLastHangupCause(event.getHangupCause()); - rec.setLockKey(null); - rec.setLockTime(null); + rec.setStatus(CallingList.Status.CALLED); rec.setUpdatedTime(new Date()); callingListMapper.update(rec); } - } } - - private Date getCallStartTime(final Event event) { - final String startEpoch = event.getHeader("variable_start_epoch"); - if (StringUtils.isNotBlank(startEpoch)) { - return new Date(Long.parseLong(startEpoch) * 1000); - } - return new Date(); - } } diff --git a/fsagent/src/main/java/com/pudonghot/yo/fsagent/listener/ChannelCreate.java b/fsagent/src/main/java/com/pudonghot/yo/fsagent/listener/ChannelCreate.java index 0bfe30b7..b4508d41 100644 --- a/fsagent/src/main/java/com/pudonghot/yo/fsagent/listener/ChannelCreate.java +++ b/fsagent/src/main/java/com/pudonghot/yo/fsagent/listener/ChannelCreate.java @@ -94,11 +94,6 @@ public class ChannelCreate { agent.getId(), agent.getAccount(), null)); } - - final Integer campaignId = event.getCampaignId(); - if (campaignId != null) { - commonCallDataService.incrCampaignDailyEstablished(campaignId); - } } } } diff --git a/fsagent/src/main/java/com/pudonghot/yo/fsagent/service/dubbo/impl/CampaignDialServiceImpl.java b/fsagent/src/main/java/com/pudonghot/yo/fsagent/service/dubbo/impl/CampaignDialServiceImpl.java index 979efb24..8075a3cb 100644 --- a/fsagent/src/main/java/com/pudonghot/yo/fsagent/service/dubbo/impl/CampaignDialServiceImpl.java +++ b/fsagent/src/main/java/com/pudonghot/yo/fsagent/service/dubbo/impl/CampaignDialServiceImpl.java @@ -1,14 +1,13 @@ package com.pudonghot.yo.fsagent.service.dubbo.impl; +import lombok.val; import java.util.*; import com.pudonghot.yo.mapper.*; import lombok.extern.slf4j.Slf4j; import com.pudonghot.yo.util.LogMDC; import com.pudonghot.yo.model.domain.*; import org.springframework.util.Assert; -import com.pudonghot.yo.model.domain.Queue; import com.wacai.tigon.sequence.IdSequence; -import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.StringUtils; import com.pudonghot.yo.fsagent.api.request.*; import org.freeswitch.esl.client.inbound.Client; @@ -49,8 +48,8 @@ public class CampaignDialServiceImpl implements CampaignDialService { */ @Override public List queueDial(final ReqCampaignDial req) { - final Integer campaignId = req.getCampaignId(); - final Campaign campaign = campaignMapper.find(campaignId); + val campaignId = req.getCampaignId(); + val campaign = campaignMapper.find(campaignId); Assert.state(campaign != null, () -> "No campaign [" + campaignId + "] found"); Assert.state(campaign.getActive(), @@ -60,32 +59,33 @@ public class CampaignDialServiceImpl implements CampaignDialService { Assert.state(campaign.getTargetType() == Campaign.TargetType.QUEUE, () -> "Campaign [" + campaignId + "] target type is not QUEUE"); - final Queue queue = queueMapper.find(campaign.getTargetId()); + val queue = queueMapper.find(campaign.getTargetId()); Assert.state(queue != null, () -> "Campaign [" + campaignId + "] queue not found"); Assert.state(queue.getActive(), () -> "Campaign [" + campaignId + "] queue is not active"); - final Tenant tenant = tenantMapper.find(campaign.getTenantId()); + val tenant = tenantMapper.find(campaign.getTenantId()); Assert.state(tenant != null, () -> "Campaign [" + campaignId + "] tenant not found"); Assert.state(tenant.getActive(), () -> "Campaign [" + campaignId + "] tenant is not active"); - final List> callingList = req.getCallingList(); - final List callUuidList = new ArrayList<>(callingList.size()); + val callingList = req.getCallingList(); + val callUuidList = new ArrayList(callingList.size()); - for (final Pair callingRec : callingList) { - final String calledNumber = callingRec.getLeft(); - final String caseKey = callingRec.getRight(); + for (val callingRec : callingList) { + val recId = callingRec.getId(); + val calledNumber = callingRec.getPhone(); + val caseKey = callingRec.getCaseKey(); - final Trunk trunk = trunkMapper.findOfCampaign(campaignId); + val trunk = trunkMapper.findOfCampaign(campaignId); Assert.state(trunk != null, () -> "No trunk of campaign [" + campaignId + "] found"); - final String uuid = idSeq.get(); + val uuid = idSeq.get(); - final List globalVars = Arrays.asList( + val globalVars = Arrays.asList( "x_conn_id=" + uuid, "ignore_early_media=true", "x_dial_type=CAMPAIGN", @@ -93,6 +93,7 @@ public class CampaignDialServiceImpl implements CampaignDialService { "x_tenant_id=" + tenant.getId(), "x_tenant_code=" + tenant.getCode(), "x_campaign_id=" + campaignId, + "x_rec_id=" + recId, "x_case_key=" + caseKey, "x_called_number=" + calledNumber, "x_trunk_id=" + trunk.getId(), @@ -111,7 +112,6 @@ public class CampaignDialServiceImpl implements CampaignDialService { "origination_caller_id_number=" + trunk.getCpn() ); - // originate {x_dial_type=CAMPAIGN,x_tenant_id=13,x_tenant_code=GOBLIN,x_account=SYSTEM,x_called_number=13764268709,x_trunk_id=12,x_cpn=28165766}[originate_timeout=30,x_logic_role=CALLED,origination_caller_id_number=28165766]sofia/gateway/GW000001/013764268709 4.Q XML d1.wacai.info fsClient.bgApi(format("originate {{}}[{}]{} {}.Q XML {}", StringUtils.join(globalVars, ","), StringUtils.join(channelVars, ","), @@ -119,9 +119,9 @@ public class CampaignDialServiceImpl implements CampaignDialService { queue.getId(), tenant.getRealm())); - log.info("CampaignCall [{}:{}].", caseKey, calledNumber); + log.info("CampaignCall [{}:{}:{}].", recId, caseKey, calledNumber); - final Map callData = new HashMap<>(4); + val callData = new HashMap(4); callData.put("outid", caseKey); callData.put("phone", calledNumber); callData.put("taskid", campaign.getCampaignKey()); diff --git a/fsagent/src/test/java/com/pudonghot/yo/fsagent/DialServiceTest.java b/fsagent/src/test/java/com/pudonghot/yo/fsagent/DialServiceTest.java index 839f7481..74823cd6 100644 --- a/fsagent/src/test/java/com/pudonghot/yo/fsagent/DialServiceTest.java +++ b/fsagent/src/test/java/com/pudonghot/yo/fsagent/DialServiceTest.java @@ -33,7 +33,7 @@ public class DialServiceTest { @Test public void testDial() { - final val req = new ReqAgentDial(); + val req = new ReqAgentDial(); req.setTenantId(1); req.setAccount("donghuang"); req.setCalledNumber("13764268709"); @@ -43,7 +43,7 @@ public class DialServiceTest { @Test public void testDial2() { - final ReqDial req = new ReqDial(); + val req = new ReqDial(); req.setTenantId(13); req.setCallerLeg(CallLeg.queue("queue1")); req.setCalledLeg(CallLeg.outside(3, "13764268709")); @@ -55,10 +55,12 @@ public class DialServiceTest { @Test public void testCampaignDial() { - final val req = new ReqCampaignDial(); + val req = new ReqCampaignDial(); req.setCampaignId(4); final String calledNumber = "13764268709"; - req.setCallingList(Arrays.asList(Pair.of(calledNumber, calledNumber))); + req.setCallingList( + Arrays.asList(new ReqCampaignDial.CallingRecord( + 1, calledNumber, calledNumber))); campaignDialService.queueDial(req); } } diff --git a/lib/fsagent-api/src/main/java/com/pudonghot/yo/fsagent/api/request/ReqCampaignDial.java b/lib/fsagent-api/src/main/java/com/pudonghot/yo/fsagent/api/request/ReqCampaignDial.java index 2c098c6b..d8fdab9e 100644 --- a/lib/fsagent-api/src/main/java/com/pudonghot/yo/fsagent/api/request/ReqCampaignDial.java +++ b/lib/fsagent-api/src/main/java/com/pudonghot/yo/fsagent/api/request/ReqCampaignDial.java @@ -1,11 +1,8 @@ package com.pudonghot.yo.fsagent.api.request; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; +import lombok.*; import java.util.List; import java.io.Serializable; -import org.apache.commons.lang3.tuple.Pair; /** * @author Donghuang @@ -18,5 +15,18 @@ public class ReqCampaignDial implements Serializable { private static final long serialVersionUID = 1L; private Integer campaignId; - private List> callingList; + private List callingList; + + @Getter + @Setter + @ToString + @NoArgsConstructor + @AllArgsConstructor + public static class CallingRecord implements Serializable { + private static final long serialVersionUID = 1L; + + private Integer id; + private String caseKey; + private String phone; + } } diff --git a/lib/fsesl-api/src/main/java/org/freeswitch/esl/client/transport/model/DataWrapper.java b/lib/fsesl-api/src/main/java/org/freeswitch/esl/client/transport/model/DataWrapper.java index 95e4a893..ef6c4c60 100644 --- a/lib/fsesl-api/src/main/java/org/freeswitch/esl/client/transport/model/DataWrapper.java +++ b/lib/fsesl-api/src/main/java/org/freeswitch/esl/client/transport/model/DataWrapper.java @@ -119,8 +119,6 @@ public class DataWrapper implements Serializable { return getVal("variable_x_called_number"); } - - /** * Convenience method. * get dial type @@ -145,6 +143,26 @@ public class DataWrapper implements Serializable { return null; } + /** + * Convenience method. + * get calling list record id + * + * @return calling list record id + */ + public String getRecId() { + return getVal("variable_x_rec_id"); + } + + /** + * Convenience method. + * get case key + * + * @return case key + */ + public String getCaseKey() { + return getVal("variable_x_case_key"); + } + /** * Convenience method. * get other number diff --git a/lib/mapper/src/test/java/com/pudonghot/yo/mapper/TrunkMapperTest.java b/lib/mapper/src/test/java/com/pudonghot/yo/mapper/TrunkMapperTest.java index b8fb11a6..1f02b541 100644 --- a/lib/mapper/src/test/java/com/pudonghot/yo/mapper/TrunkMapperTest.java +++ b/lib/mapper/src/test/java/com/pudonghot/yo/mapper/TrunkMapperTest.java @@ -33,25 +33,25 @@ public class TrunkMapperTest { @Test public void testListOfStrategy() { - final val trunk = mapper.listOfStrategy(Arrays.asList(1, 2, 3)); + val trunk = mapper.listOfStrategy(Arrays.asList(1, 2, 3)); log.info("Trunk [{}].", trunk); } @Test public void testFindOfStrategy() { - final val trunk = mapper.findOfStrategy(Arrays.asList(1, 2, 3)); + val trunk = mapper.findOfStrategy(Arrays.asList(1, 2, 3)); log.info("Trunk [{}].", trunk); } @Test public void testFindOfAgentGroup() { - final val trunk = mapper.findOfAgentGroup(5); + val trunk = mapper.findOfAgentGroup(5); log.info("Trunk [{}].", trunk); } @Test public void testFindOfCampaign() { - final val trunk = mapper.findOfCampaign(3); + val trunk = mapper.findOfCampaign(3); log.info("Trunk [{}].", trunk); } } diff --git a/lib/model/src/main/java/com/pudonghot/yo/model/domain/CallingList.java b/lib/model/src/main/java/com/pudonghot/yo/model/domain/CallingList.java index 3b1605f2..b42b55e0 100644 --- a/lib/model/src/main/java/com/pudonghot/yo/model/domain/CallingList.java +++ b/lib/model/src/main/java/com/pudonghot/yo/model/domain/CallingList.java @@ -4,9 +4,10 @@ import lombok.Getter; import lombok.Setter; import java.util.Date; import com.wacai.tigon.mybatis.Table; +import com.pudonghot.yo.model.DailyTime; import com.wacai.tigon.mybatis.NotUpdate; +import org.apache.commons.lang3.tuple.Pair; import lombok.experimental.FieldNameConstants; -import com.wacai.tigon.mybatis.UseGeneratedKeys; /** * @author Donghuang
@@ -14,7 +15,6 @@ import com.wacai.tigon.mybatis.UseGeneratedKeys; */ @Getter @Setter -@UseGeneratedKeys @Table("br_calling_list") @FieldNameConstants(prefix = "") public class CallingList extends BaseDomain { @@ -28,11 +28,11 @@ public class CallingList extends BaseDomain { private String campaignKey; @NotUpdate private Date addedTime; + private DailyTime dailyFrom; + private DailyTime dailyTo; @NotUpdate private String phone; private Status status; - private Integer dailyFrom; - private Integer dailyTo; private Integer calledTimes; private String lastConnId; private Date lastCallStartTime; @@ -51,6 +51,6 @@ public class CallingList extends BaseDomain { private Date lockTime; public enum Status { - READY, ACHIEVED, CALLED, CANCELED + READY, ACHIEVED, DIALING, CALLED, CANCELED } } diff --git a/lib/service-common/src/main/java/com/pudonghot/yo/service/CommonCallDataService.java b/lib/service-common/src/main/java/com/pudonghot/yo/service/CommonCallDataService.java index 5df1e6e1..ce647a83 100644 --- a/lib/service-common/src/main/java/com/pudonghot/yo/service/CommonCallDataService.java +++ b/lib/service-common/src/main/java/com/pudonghot/yo/service/CommonCallDataService.java @@ -24,7 +24,6 @@ public interface CommonCallDataService { */ String getIvrCallData(String agentId); - /** * save call data * @@ -47,7 +46,7 @@ public interface CommonCallDataService { * @param campaignId campaign id * @return count of campaign channel */ - int getCampaignChannel(Integer campaignId); + Integer getCampaignChannel(Integer campaignId); /** * increase campaign channel @@ -55,7 +54,7 @@ public interface CommonCallDataService { * @param campaignId campaign id * @return count of campaign channel */ - int incrCampaignChannel(Integer campaignId); + Integer incrCampaignChannel(Integer campaignId); /** * decrease campaign channel @@ -63,51 +62,12 @@ public interface CommonCallDataService { * @param campaignId campaign id * @return count of campaign channel */ - int decrCampaignChannel(Integer campaignId); + Integer decrCampaignChannel(Integer campaignId); /** - * get campaign daily dialed - * - * @param campaignId campaign id - * @return count of campaign daily dialed - */ - int getCampaignDailyDialed(Integer campaignId); - - /** - * increase campaign daily dialed - * - * @param campaignId campaign id - * @return count of campaign daily dialed - */ - int incrCampaignDailyDialed(Integer campaignId); - - /** - * reset campaign daily dialed + * reset campaign channel * * @param campaignId campaign id */ - void resetCampaignDailyDialed(Integer campaignId); - - /** - * get campaign daily established - * - * @param campaignId campaign id - * @return count of campaign daily established - */ - int getCampaignDailyEstablished(Integer campaignId); - - /** - * increase campaign daily established - * - * @param campaignId campaign id - * @return count of campaign daily established - */ - int incrCampaignDailyEstablished(Integer campaignId); - - /** - * reset campaign daily established - * - * @param campaignId campaign id - */ - void resetCampaignDailyEstablished(Integer campaignId); + Integer resetCampaignChannel(Integer campaignId); } diff --git a/lib/service-common/src/main/java/com/pudonghot/yo/service/impl/CommonAgentEventQueueServiceImpl.java b/lib/service-common/src/main/java/com/pudonghot/yo/service/impl/CommonAgentEventQueueServiceImpl.java index 26be835c..1e4c5c51 100644 --- a/lib/service-common/src/main/java/com/pudonghot/yo/service/impl/CommonAgentEventQueueServiceImpl.java +++ b/lib/service-common/src/main/java/com/pudonghot/yo/service/impl/CommonAgentEventQueueServiceImpl.java @@ -24,7 +24,7 @@ public class CommonAgentEventQueueServiceImpl implements CommonAgentEventQueueSe */ @Override public void publish(final AgentEvent event) { - log.debug("Publish agent event [{}].", event); + log.info("Publish agent event [{}].", event); AGENT_EVENT_QUEUE.offer(event); } diff --git a/lib/service-common/src/main/java/com/pudonghot/yo/service/impl/CommonCallDataServiceImpl.java b/lib/service-common/src/main/java/com/pudonghot/yo/service/impl/CommonCallDataServiceImpl.java index e4967f65..d084d256 100644 --- a/lib/service-common/src/main/java/com/pudonghot/yo/service/impl/CommonCallDataServiceImpl.java +++ b/lib/service-common/src/main/java/com/pudonghot/yo/service/impl/CommonCallDataServiceImpl.java @@ -72,8 +72,8 @@ public class CommonCallDataServiceImpl implements CommonCallDataService { * {@inheritDoc} */ @Override - public int getCampaignChannel(final Integer campaignId) { - final int val = CAMPAIGN_DATA.getOrDefault(channelKey(campaignId), 0); + public Integer getCampaignChannel(final Integer campaignId) { + final Integer val = CAMPAIGN_DATA.getOrDefault(channelKey(campaignId), 0); log.debug("Get campaign [{}] channel [{}].", campaignId, val); return val; } @@ -82,8 +82,8 @@ public class CommonCallDataServiceImpl implements CommonCallDataService { * {@inheritDoc} */ @Override - public int incrCampaignChannel(final Integer campaignId) { - final int val = CAMPAIGN_DATA.addAndGet(channelKey(campaignId), 1); + public Integer incrCampaignChannel(final Integer campaignId) { + final Integer val = CAMPAIGN_DATA.addAndGet(channelKey(campaignId), 1); log.info("Increase campaign [{}] channel [{}].", campaignId, val); return val; } @@ -92,8 +92,8 @@ public class CommonCallDataServiceImpl implements CommonCallDataService { * {@inheritDoc} */ @Override - public int decrCampaignChannel(final Integer campaignId) { - final int val = CAMPAIGN_DATA.addAndGet(channelKey(campaignId), -1); + public Integer decrCampaignChannel(final Integer campaignId) { + final Integer val = CAMPAIGN_DATA.addAndGet(channelKey(campaignId), -1); log.info("Decrease campaign [{}] channel [{}].", campaignId, val); return val; } @@ -102,60 +102,12 @@ public class CommonCallDataServiceImpl implements CommonCallDataService { * {@inheritDoc} */ @Override - public int getCampaignDailyDialed(final Integer campaignId) { - final int val = CAMPAIGN_DATA.getOrDefault(dialKey(campaignId), 0); - log.debug("Get campaign [{}] daily dialed [{}].", campaignId, val); + public Integer resetCampaignChannel(final Integer campaignId) { + final Integer val = CAMPAIGN_DATA.remove(channelKey(campaignId)); + log.info("Reset campaign [{}] channel [{}].", campaignId, val); return val; } - /** - * {@inheritDoc} - */ - @Override - public int incrCampaignDailyDialed(final Integer campaignId) { - final int val = CAMPAIGN_DATA.addAndGet(dialKey(campaignId), 1); - log.debug("Increase campaign [{}] daily dialed [{}].", campaignId, val); - return val; - } - - /** - * {@inheritDoc} - */ - @Override - public void resetCampaignDailyDialed(final Integer campaignId) { - final Integer val = CAMPAIGN_DATA.remove(dialKey(campaignId)); - log.debug("Reset campaign [{}] daily dialed [{}].", campaignId, val); - } - - /** - * {@inheritDoc} - */ - @Override - public int getCampaignDailyEstablished(final Integer campaignId) { - final int val = CAMPAIGN_DATA.getOrDefault(establishedKey(campaignId), 0); - log.debug("Get campaign [{}] daily established [{}].", campaignId, val); - return val; - } - - /** - * {@inheritDoc} - */ - @Override - public int incrCampaignDailyEstablished(final Integer campaignId) { - final int val = CAMPAIGN_DATA.addAndGet(establishedKey(campaignId), 1); - log.debug("Increase campaign [{}] daily established [{}].", campaignId, val); - return val; - } - - /** - * {@inheritDoc} - */ - @Override - public void resetCampaignDailyEstablished(final Integer campaignId) { - final Integer val = CAMPAIGN_DATA.remove(establishedKey(campaignId)); - log.debug("Reset campaign [{}] daily established [{}].", campaignId, val); - } - private void put(final String key, final String value) { log.debug("Call data cache [{}] -> [{}].", key, value); CACHE.put(key, value, callDataTimeoutSeconds, TimeUnit.SECONDS); @@ -168,12 +120,4 @@ public class CommonCallDataServiceImpl implements CommonCallDataService { private String channelKey(final Integer campaignId) { return "CC:" + campaignId; } - - private String dialKey(final Integer campaignId) { - return "CD:" + campaignId; - } - - private String establishedKey(final Integer campaignId) { - return "CE:" + campaignId; - } } diff --git a/lib/service-common/src/main/java/com/pudonghot/yo/service/impl/CommonCampaignServiceImpl.java b/lib/service-common/src/main/java/com/pudonghot/yo/service/impl/CommonCampaignServiceImpl.java index 4d98ce3e..3943c402 100644 --- a/lib/service-common/src/main/java/com/pudonghot/yo/service/impl/CommonCampaignServiceImpl.java +++ b/lib/service-common/src/main/java/com/pudonghot/yo/service/impl/CommonCampaignServiceImpl.java @@ -100,7 +100,7 @@ public class CommonCampaignServiceImpl log.info("Update campaign [{}] status [{}].", campaign, status); campaign.setStatus(status); mapper.update(campaign); - resetData(campaign); + commonCallDataService.resetCampaignChannel(campaign.getId()); } private Campaign findValid(final String campaignKey) { @@ -112,10 +112,4 @@ public class CommonCampaignServiceImpl () -> "Campaign [" + campaignKey + "] is not active"); return campaign; } - - private void resetData(final Campaign campaign) { - final Integer campaignId = campaign.getId(); - commonCallDataService.resetCampaignDailyDialed(campaignId); - commonCallDataService.resetCampaignDailyEstablished(campaignId); - } } diff --git a/lib/util/src/main/java/com/pudonghot/yo/util/ListUtils.java b/lib/util/src/main/java/com/pudonghot/yo/util/ListUtils.java new file mode 100644 index 00000000..6fa0121b --- /dev/null +++ b/lib/util/src/main/java/com/pudonghot/yo/util/ListUtils.java @@ -0,0 +1,30 @@ +package com.pudonghot.yo.util; + +import java.util.List; +import java.util.function.Consumer; + +/** + * @author Donghuang + * @date Sep 13, 2020 14:11:09 + */ +public class ListUtils { + + /** + * list each batch + * + * @param list list + * @param batch batch size + * @param consumer consumer + * @param element type + */ + public static void eachBatch( + final List list, + final int batch, + final Consumer> consumer) { + + final int size = list.size(); + for (int i = 0; i < size; i += batch) { + consumer.accept(list.subList(i, Math.min(size, i + batch))); + } + } +} diff --git a/campaign/src/test/java/com/pudonghot/yo/campaign/service/impl/CampaignServiceImplTest.java b/lib/util/src/test/java/com/pudonghot/yo/util/ListUtilsTest.java similarity index 67% rename from campaign/src/test/java/com/pudonghot/yo/campaign/service/impl/CampaignServiceImplTest.java rename to lib/util/src/test/java/com/pudonghot/yo/util/ListUtilsTest.java index ffc9b692..85e3d4d3 100644 --- a/campaign/src/test/java/com/pudonghot/yo/campaign/service/impl/CampaignServiceImplTest.java +++ b/lib/util/src/test/java/com/pudonghot/yo/util/ListUtilsTest.java @@ -1,17 +1,16 @@ -package com.pudonghot.yo.campaign.service.impl; +package com.pudonghot.yo.util; -import lombok.extern.slf4j.Slf4j; import org.junit.Test; - -import java.util.ArrayList; import java.util.List; +import java.util.ArrayList; +import lombok.extern.slf4j.Slf4j; /** * @author Donghuang * @date Sep 13, 2020 10:25:44 */ @Slf4j -public class CampaignServiceImplTest { +public class ListUtilsTest { @Test public void testEachBatch() { @@ -19,6 +18,6 @@ public class CampaignServiceImplTest { for (int i = 0; i < 100; i++) { list.add(i); } - new CampaignServiceImpl(null).eachBatch(list, 8, sub -> log.info("{}", sub)); + ListUtils.eachBatch(list, 8, sub -> log.info("{}", sub)); } } diff --git a/lib/util/src/test/java/com/pudonghot/yo/util/TimeUtilsTest.java b/lib/util/src/test/java/com/pudonghot/yo/util/TimeUtilsTest.java new file mode 100644 index 00000000..51f1362e --- /dev/null +++ b/lib/util/src/test/java/com/pudonghot/yo/util/TimeUtilsTest.java @@ -0,0 +1,21 @@ +package com.pudonghot.yo.util; + +import org.junit.Test; +import java.util.Date; +import java.util.Calendar; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.time.DateUtils; + +/** + * @author Donghuang + * @date Sep 13, 2020 23:12:06 + */ +@Slf4j +public class TimeUtilsTest { + + @Test + public void testEachBatch() { + log.info("val: {}", TimeUtils.secondOfDay( + DateUtils.addSeconds(DateUtils.truncate(DateUtils.addDays(new Date(), 1), Calendar.DATE), -1))); + } +}