Любые входящие или исходящие звонки абонентов нашего оператора фиксируются в CDR файле, который собирается на коммутаторе. Данные поступают в виде записей типа:
- тип вызова (01 - исходящие, 02 - входящие);
- номер обслуживаемого абонента;
- номер абонента, с которым осуществлялась связь;
- дата и время начала звонка (ISO 8601);
- дата и время окончания звонка (ISO 8601);
- разделитель данных – запятая;
- разделитель записей – перенос строки;
- данные обязательно формируются в хронологическом порядке;
- в рамках задания CDR может быть обычным txt/csv;
Каждые 10 записей составляют CDR, который отправляется на тарификацию в сервис BRT.
При этом, если звонок начинается до полуночи, а заканчивается после, коммутатор генерирует по такому звонку 2 записи в CDR.
Пример фрагмента CDR:
02,79876543221,79123456789,2025-02-10T14:56:12,2025-02-10T14:58:20
01,79996667755,79876543221,2025-02-10T10:12:25,2025-02-10T10:12:57
Напишите сервис, эмулирующий работу коммутатора, т.е. генерирующий записи действий абонента и собирающий из них CDR файлы.
- Установленный список абонентов (не менее 10) хранится в локальной БД (H2); данные о звонках помещаются в соседнюю таблицу этой БД.
- CDR собирается из записей, которые могут генерироваться параллельно (TODO).
- На один месяц может приходиться случайное количество CDR файлов. Тарифицируемый период в рамках задания — 1 год.
- Данные в CDR идут не по порядку, т.е. записи по одному абоненту могут быть в разных частях файла.
- Хронология звонков при этом должна обязательно соблюдаться.
- Количество и длительность звонков определяется случайным образом.
- CDR, по мере генерации, асинхронно отправляются в сервис BRT через брокер сообщений.
Микросервис cdr представляет собой эмуляцию работы реального коммутатора. Его задачи:
- Сгенерировать 10 пользователей и сохранить в ин-мемори БД H2.
- Сгенерировать n количество CDR записей и сохранить в ин-мемори БД H2.
- Каждые 10 сгенерированных записей отправлять в брокер сообщений RabbitMQ для обработки сервисом BRT.
Сообщения посылаются в формате JSON.
Генерация данных происходит в момент обновления Spring контекста — когда он собран.
- Генерация пользователей: Реализовано в
com.mobile.network.report.service.impl.CustomerServiceImpl#generateCustomers. - Генерация CDR: Реализовано в
com.mobile.network.report.service.impl.CDRRecordGeneratorServiceImpl#generateCDRRecords.
Настройка RabbitMQ (exchange, queue, binding и routing key) автоматически происходит при старте приложения благодаря конфигурации в классе RabbitMQConfiguration. Это позволяет использовать RabbitTemplate для отправки сообщений без дополнительных настроек, уже полностью сконфигурированным.
CDR записи генерируются по переданному году. Алгоритм:
- Получаем все номера пользователей из базы.
- Рандомизируется количество звонков в год от 100 до 599 (
totalCalls). - Вычисляется количество секунд в году:
totalSecondsInYear = endOfYear - startOfYear. - Вычисляется средний интервал между звонками:
averageIntervalSeconds = totalSecondsInYear / totalCalls. - В цикле, начиная с начала года:
- Проверяется список для отправки в брокер; если в нем ровно 10 записей, отправляем их в брокер, список очищаем (временное решение).
- Вычисляется интервал, к среднему добавляется случайное отклонение.
- Проверяется, что время не вышло за границы года.
- Генерируется одиночная запись
CDRRecordDto. - Получаем два случайных номера; если они совпадают, присваиваем второму новый номер, пока они не будут разными.
- Рандомизируем
CallType(01 или 02). - Рандомизируем длительность разговора от 10 до 600 секунд.
- Длительность звонка вычисляется как сумма начала звонка и длительности разговора.
- Собранный объект добавляется в список для последующего сохранения.
- Собранный объект добавляется в список для последующей отправки в брокер.
- После цикла проверяется, есть ли в списке для отправки в брокер еще записи; если есть — отправка в брокер (на случай генерации не кратного 10 количеству записей).
В качестве базы используется H2, работа с ней происходит посредством Spring JPA.
- MapStruct: Для уменьшения шаблонного кода генерации мапперов Message <-> DTO <-> Entity.
- Lombok: Для уменьшения бойлерплейт кода.
- Скачать джарник из релиза, и докер компоуз
- docker compose up в директории где лежит docker-compose.yml
- Стартануть приложение java -jar report-1.0.2-SNAPSHOT.jar
- Проверить по http://localhost:15672 что в реббит пришло кол-во сообщений равное кол-ву записей в бд / 10 + 1 http://localhost:8080/h2-console
Доступы:
- username: user
- password: password
- username: test
- password: test
- Проверить что они пришли в нужный exchange (cdr.report.send), queue (cdr.queue) и имеют верный routing key (cdr_record)