forum.bitel.ru
http://forum.bitel.ru/

Использование EmailSender для отправки писем
http://forum.bitel.ru/viewtopic.php?f=19&t=11664
Страница 1 из 1

Автор:  Antonavt [ 07 июн 2016, 16:54 ]
Заголовок сообщения:  Использование EmailSender для отправки писем

Здравствуйте

Используем BGbilling 6.0
Добавили код рассылки писем по событию прихода платежа.
Для этого повесил в "Функции скриптов поведения" Класс Java на событие "Приход платежа"
Он содержит примерно следующий код:
Код:
   public void onEvent( Event event1, Setup setup2, ConnectionSet connectionSet3 )
      throws Exception
   {
      // Оповещение клиента о пополнении
      if(event1 instanceof PaymentEvent)
      {
         PaymentEvent p_event = (PaymentEvent)event1;
         Payment p = p_event.getPayment();
               ...
// Посылаем письмо с использованием ru.bitel.bgbilling.plugins.dispatch.server.sender.EmailSender
      Сontact c = new Contact();
      c.setContractId(contr.getId());
      c.setContactTypeId(1);
      EmailSender m_sender = new EmailSender();
      ArrayList<String> managerMails; // Содержит список почт
      for(String mail : managerMails)
      {
         c.setValue(mail);
         m_sender.send(c,"Пополнение баланса","Тело", new ArrayList<javax.activation.DataSource>());
      }
   }
}


События платежа так же генерируется в другом java коде:
Код:
// Занесение платежа в систему
EventProcessor.getInstance().publishAfterCommit( new PaymentEvent( contract_id, payment ) );


Код работает нормально до поры до времени.
Иногда по какой то причине(Которую я пытаюсь найти) приходят очень много оповещений об одном и том же платеже.
Например: При 1 платеже должно быть одно оповещение, а приходят больше одного, при этом кол-во оповещений разное.

Ошибок в server.error.log и в scheduler.error.log во время прихода оповещений нет.
Точнее логи содержали Exception-ы но они относились к другому коду.(Могут ли исключения которые выкидываются в другой части биллинга как то влиять на отработку события отправки письма?)

Может кто может подсказать в какую сторону смотреть?

Автор:  skn [ 07 июн 2016, 19:53 ]
Заголовок сообщения:  Re: Использование EmailSender для отправки писем

добавьте в ваш код какую нибудь отладочную инфу, например текущую дату, какой договор какой платеж и т.д.

потом лог выложите сюда... будет хоть какая то инфа для анализа

Автор:  Antonavt [ 08 июн 2016, 11:05 ]
Заголовок сообщения:  Re: Использование EmailSender для отправки писем

Так и сделал, лог кода в котором вызывается событие прихода платежа:
Код:
2016-06-08 03:00:10 | Add event about payment contract id = 9671 sum: 15
2016-06-08 03:00:10 | Add event about payment contract id = 9675 sum: 400
2016-06-08 03:00:10 | Add event about payment contract id = 9677 sum: 10
2016-06-08 03:00:10 | Add event about payment contract id = 9680 sum: 10


И получается письма пришли только по поводу contract id 9680. При чем 4 штуки.

Так же нашел 3 Exception-а.
Код:
java.util.concurrent.ExecutionException: java.lang.Exception: java.lang.NullPointerException
        at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:232)
        at java.util.concurrent.FutureTask.get(FutureTask.java:91)
        at ru.bitel.bgbilling.kernel.script.server.DynamicScriptEventListener$ThreadedScriptEventListener.runScriptImpl(DynamicScriptEventListener.java:267)
        at ru.bitel.bgbilling.kernel.script.server.DynamicScriptEventListener.runScript(DynamicScriptEventListener.java:149)
        at ru.bitel.bgbilling.kernel.script.server.DynamicScriptEventListener.notify(DynamicScriptEventListener.java:117)
        at ru.bitel.bgbilling.kernel.event.AbstractConsumer.notify(AbstractConsumer.java:344)
        at ru.bitel.bgbilling.kernel.event.Consumer.notify(Consumer.java:1)
        at ru.bitel.bgbilling.kernel.event.Consumer.onMessage0(Consumer.java:112)
        at ru.bitel.bgbilling.kernel.event.Consumer$EventListenerRunnable.runImpl(Consumer.java:51)
        at ru.bitel.common.worker.WorkerTask.run(WorkerTask.java:86)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
        at java.lang.Thread.run(Thread.java:662)
        at ru.bitel.common.worker.WorkerThread.run(WorkerThread.java:40)
Caused by: java.lang.Exception: java.lang.NullPointerException
        at ru.bitel.bgbilling.kernel.script.server.DynamicScriptEventListener.runScriptImpl(DynamicScriptEventListener.java:200)
        at ru.bitel.bgbilling.kernel.script.server.DynamicScriptEventListener$ThreadedScriptEventListener.access$0(DynamicScriptEventListener.java:1)
        at ru.bitel.bgbilling.kernel.script.server.DynamicScriptEventListener$ThreadedScriptEventListener$1.call(DynamicScriptEventListener.java:254)
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
        at java.util.concurrent.FutureTask.run(FutureTask.java:138)
        ... 4 more
Caused by: java.lang.NullPointerException
        at api.ru.customservice.bgbilling.bean.Status.getStatus(Status.java:58)
        at StatusWorker.onEvent(StatusWorker.java:74)  <-------------Этот код находится ниже отправки письма
        at ru.bitel.bgbilling.kernel.script.server.DynamicScriptEventListener.runScriptImpl(DynamicScriptEventListener.java:196)
        ... 8 more


Предположение то что использую не тот метод для вызова события платежа.(или не правильно использую)
Код:
for(...)
{
 // Занесение платежа в систему
 EventProcessor.getInstance().publishAfterCommit( new PaymentEvent( contract_id, payment ) );
}

Видимо надо использовать метод:
Код:
public final void publish(Event e)
                   throws ru.bitel.bgbilling.common.BGException

Правильно?

Автор:  dimOn [ 08 июн 2016, 11:53 ]
Заголовок сообщения:  Re: Использование EmailSender для отправки писем

вообще непонятно зачем вы откуда-то руками посылаете событие по приходу платежа (откуда? откуда-то из дин кода). а потом его же где-то ловите (скрипт на дин коде?). вы до этого платёж добавляете или что или как?

Автор:  Antonavt [ 08 июн 2016, 12:16 ]
Заголовок сообщения:  Re: Использование EmailSender для отправки писем

Почему сделано так:
В начале была необходимость: отсылать письма по приходу платежей через платежную систему.
Появился класс который при событии платежа отправляет письмо.

Далее появилась необходимость: по информации из 3 системы раз в сутки генерировать платежи.
Вот и пришли к такой реализации.

Код:
for(...)
{
 // <--- Добавляется платеж в контракт
 // Занесение платежа в систему
 EventProcessor.getInstance().publishAfterCommit( new PaymentEvent( contract_id, payment ) );
}


Все делается в дин коде.
Если есть система событий, почему ее не использовать?

Автор:  dimOn [ 08 июн 2016, 12:22 ]
Заголовок сообщения:  Re: Использование EmailSender для отправки писем

а платёж как добавляется?

Автор:  Antonavt [ 08 июн 2016, 12:33 ]
Заголовок сообщения:  Re: Использование EmailSender для отправки писем

Вот так выглядит код:
Код:
Payment p = new Payment();
PaymentManager pm = new PaymentManager(connectionSet2.getConnection());
BalanceUtils bu = new BalanceUtils(connectionSet2.getConnection());
for(int i = 0; i < payment_list.size(); ++i)
{
   BigDecimal sum = getSumm(payment_list.get(i));//получаем платеж
   p.setSumma(sum);
   p.setContractId(payment_list.get(i).getContractId());
   p.setComment("Коммент ");
   p.setTypeId(6);
   p.setId(-1);
   p.setPaymentDate(date);
   p.setTimeChange(date.toString());
   p.setTypeTitle("Бонусы");
   p.setUserId(12);
   pm.updatePayment(p);
   EventProcessor.getInstance().publishAfterCommit( new PaymentEvent( payment_list.get(i).getContractId(), p ) );
   bu.updateBalance(date, p.getContractId());
}

Платежи все корректно добавляются, сбоев не было.

Автор:  dimOn [ 08 июн 2016, 14:19 ]
Заголовок сообщения:  Re: Использование EmailSender для отправки писем

первый аргумент PaymentEvent - не ContractId, а userId, хотя не уверен что относится к проблеме

Автор:  Antonavt [ 09 июн 2016, 10:44 ]
Заголовок сообщения:  Re: Использование EmailSender для отправки писем

Цитата:
первый аргумент PaymentEvent - не ContractId, а userId, хотя не уверен что относится к проблеме

Проверил, Изменение на фиксированный user_id никак не повлияло на проблему.

Автор:  dimOn [ 09 июн 2016, 11:07 ]
Заголовок сообщения:  Re: Использование EmailSender для отправки писем

Antonavt писал(а):
Так и сделал, лог кода в котором вызывается событие прихода платежа:
Код:
2016-06-08 03:00:10 | Add event about payment contract id = 9671 sum: 15
2016-06-08 03:00:10 | Add event about payment contract id = 9675 sum: 400
2016-06-08 03:00:10 | Add event about payment contract id = 9677 sum: 10
2016-06-08 03:00:10 | Add event about payment contract id = 9680 sum: 10


И получается письма пришли только по поводу contract id 9680. При чем 4 штуки.


Вот у вас 4 отправки евента и пришло 4 письма, но не вполне корректно, причём для последнего, и вас это не натолкнуло ни на какую мысль?
А всё потому что вы 4 раза сделали отправку события, куда передали один и тот же инстанс (p). Просто в цикле 4 раза перетёрли ему параметры, естественно, к моменту отправки (что происходит after commit) его состояние было то, каким вы его сделали на 4й раз, потому все 4 события отправили для одного и того же объекта (Payment p, четвёртого состояния).

Автор:  dimOn [ 09 июн 2016, 11:08 ]
Заголовок сообщения:  Re: Использование EmailSender для отправки писем

Ну, решение, очевидно, new Payment() делать для каждой отправки отдельно.

Автор:  Antonavt [ 09 июн 2016, 11:56 ]
Заголовок сообщения:  Re: Использование EmailSender для отправки писем

Да, вы правы, давно не писал на Java.
При передаче параметров копируется ссылка на объект а не значение объекта...
Большое спасибо за помощь.

Страница 1 из 1 Часовой пояс: UTC + 5 часов [ Летнее время ]
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/