use of org.killbill.notificationq.api.NotificationEventWithMetadata in project killbill by killbill.
the class PaymentProcessor method getPaymentAttempts.
private List<PaymentAttempt> getPaymentAttempts(final List<PaymentAttemptModelDao> pastPaymentAttempts, final InternalTenantContext internalTenantContext) {
List<PaymentAttempt> paymentAttempts = new ArrayList<PaymentAttempt>();
// Add Past Payment Attempts
for (PaymentAttemptModelDao pastPaymentAttempt : pastPaymentAttempts) {
DefaultPaymentAttempt paymentAttempt = new DefaultPaymentAttempt(pastPaymentAttempt.getAccountId(), pastPaymentAttempt.getPaymentMethodId(), pastPaymentAttempt.getId(), pastPaymentAttempt.getCreatedDate(), pastPaymentAttempt.getUpdatedDate(), pastPaymentAttempt.getCreatedDate(), pastPaymentAttempt.getPaymentExternalKey(), pastPaymentAttempt.getTransactionId(), pastPaymentAttempt.getTransactionExternalKey(), pastPaymentAttempt.getTransactionType(), pastPaymentAttempt.getStateName(), pastPaymentAttempt.getAmount(), pastPaymentAttempt.getCurrency(), pastPaymentAttempt.getPluginName(), buildPluginProperties(pastPaymentAttempt));
paymentAttempts.add(paymentAttempt);
}
// Get Future Payment Attempts from Notification Queue and add them to the list
try {
final NotificationQueue retryQueue = notificationQueueService.getNotificationQueue(DefaultPaymentService.SERVICE_NAME, DefaultRetryService.QUEUE_NAME);
final Iterable<NotificationEventWithMetadata<NotificationEvent>> notificationEventWithMetadatas = retryQueue.getFutureNotificationForSearchKeys(internalTenantContext.getAccountRecordId(), internalTenantContext.getTenantRecordId());
for (final NotificationEventWithMetadata<NotificationEvent> notificationEvent : notificationEventWithMetadatas) {
// Last Attempt
PaymentAttemptModelDao lastPaymentAttempt = getLastPaymentAttempt(pastPaymentAttempts, ((PaymentRetryNotificationKey) notificationEvent.getEvent()).getAttemptId());
if (lastPaymentAttempt != null) {
DefaultPaymentAttempt futurePaymentAttempt = new DefaultPaymentAttempt(// accountId
lastPaymentAttempt.getAccountId(), // paymentMethodId
lastPaymentAttempt.getPaymentMethodId(), // id
((PaymentRetryNotificationKey) notificationEvent.getEvent()).getAttemptId(), // createdDate
null, // updatedDate
null, // effectiveDate
notificationEvent.getEffectiveDate(), // paymentExternalKey
lastPaymentAttempt.getPaymentExternalKey(), // transactionId
null, // transactionExternalKey
lastPaymentAttempt.getTransactionExternalKey(), // transactionType
lastPaymentAttempt.getTransactionType(), // stateName
SCHEDULED, // amount
lastPaymentAttempt.getAmount(), // currency
lastPaymentAttempt.getCurrency(), // pluginName,
((PaymentRetryNotificationKey) notificationEvent.getEvent()).getPaymentControlPluginNames().get(0), // pluginProperties
buildPluginProperties(lastPaymentAttempt));
paymentAttempts.add(futurePaymentAttempt);
}
}
} catch (NoSuchNotificationQueue noSuchNotificationQueue) {
log.error("ERROR Loading Notification Queue - " + noSuchNotificationQueue.getMessage());
}
return paymentAttempts;
}
use of org.killbill.notificationq.api.NotificationEventWithMetadata in project killbill by killbill.
the class AdminResource method getQueueEntries.
@GET
@Path("/queues")
@Produces(APPLICATION_JSON)
@ApiOperation(value = "Get queues entries", response = Response.class)
@ApiResponses(value = {})
public Response getQueueEntries(@QueryParam("accountId") final String accountIdStr, @QueryParam("queueName") final String queueName, @QueryParam("serviceName") final String serviceName, @QueryParam("withHistory") @DefaultValue("true") final Boolean withHistory, @QueryParam("minDate") final String minDateOrNull, @QueryParam("maxDate") final String maxDateOrNull, @QueryParam("withInProcessing") @DefaultValue("true") final Boolean withInProcessing, @QueryParam("withBusEvents") @DefaultValue("true") final Boolean withBusEvents, @QueryParam("withNotifications") @DefaultValue("true") final Boolean withNotifications, @javax.ws.rs.core.Context final HttpServletRequest request) {
final TenantContext tenantContext = context.createContext(request);
final Long tenantRecordId = recordIdApi.getRecordId(tenantContext.getTenantId(), ObjectType.TENANT, tenantContext);
final Long accountRecordId = Strings.isNullOrEmpty(accountIdStr) ? null : recordIdApi.getRecordId(UUID.fromString(accountIdStr), ObjectType.ACCOUNT, tenantContext);
// Limit search results by default
final DateTime minDate = Strings.isNullOrEmpty(minDateOrNull) ? clock.getUTCNow().minusDays(2) : DATE_TIME_FORMATTER.parseDateTime(minDateOrNull).toDateTime(DateTimeZone.UTC);
final DateTime maxDate = Strings.isNullOrEmpty(maxDateOrNull) ? clock.getUTCNow().plusDays(2) : DATE_TIME_FORMATTER.parseDateTime(maxDateOrNull).toDateTime(DateTimeZone.UTC);
final StreamingOutput json = new StreamingOutput() {
@Override
public void write(final OutputStream output) throws IOException, WebApplicationException {
Iterator<BusEventWithMetadata<BusEvent>> busEventsIterator = null;
Iterator<NotificationEventWithMetadata<NotificationEvent>> notificationsIterator = null;
try {
final JsonGenerator generator = mapper.getFactory().createGenerator(output);
generator.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false);
generator.writeStartObject();
if (withBusEvents) {
generator.writeFieldName("busEvents");
generator.writeStartArray();
busEventsIterator = getBusEvents(withInProcessing, withHistory, minDate, maxDate, accountRecordId, tenantRecordId).iterator();
while (busEventsIterator.hasNext()) {
final BusEventWithMetadata<BusEvent> busEvent = busEventsIterator.next();
generator.writeObject(new BusEventWithRichMetadata(busEvent));
}
generator.writeEndArray();
}
if (withNotifications) {
generator.writeFieldName("notifications");
generator.writeStartArray();
notificationsIterator = getNotifications(queueName, serviceName, withInProcessing, withHistory, minDate, maxDate, accountRecordId, tenantRecordId).iterator();
while (notificationsIterator.hasNext()) {
final NotificationEventWithMetadata<NotificationEvent> notification = notificationsIterator.next();
generator.writeObject(notification);
}
generator.writeEndArray();
}
generator.writeEndObject();
generator.close();
} finally {
// In case the client goes away (IOException), make sure to close the underlying DB connection
if (busEventsIterator != null) {
while (busEventsIterator.hasNext()) {
busEventsIterator.next();
}
}
if (notificationsIterator != null) {
while (notificationsIterator.hasNext()) {
notificationsIterator.next();
}
}
}
}
};
return Response.status(Status.OK).entity(json).build();
}
use of org.killbill.notificationq.api.NotificationEventWithMetadata in project killbill by killbill.
the class InvoiceDispatcher method getNextScheduledInvoiceEffectiveDate.
private Iterable<DateTime> getNextScheduledInvoiceEffectiveDate(final Iterable<UUID> filteredSubscriptionIds, final InternalCallContext internalCallContext) {
try {
final NotificationQueue notificationQueue = notificationQueueService.getNotificationQueue(DefaultInvoiceService.INVOICE_SERVICE_NAME, DefaultNextBillingDateNotifier.NEXT_BILLING_DATE_NOTIFIER_QUEUE);
final Iterable<NotificationEventWithMetadata<NextBillingDateNotificationKey>> futureNotifications = notificationQueue.getFutureNotificationForSearchKeys(internalCallContext.getAccountRecordId(), internalCallContext.getTenantRecordId());
final Collection<DateTime> effectiveDates = new LinkedList<DateTime>();
for (final NotificationEventWithMetadata<NextBillingDateNotificationKey> input : futureNotifications) {
final boolean isEventForSubscription = !filteredSubscriptionIds.iterator().hasNext() || Iterables.contains(filteredSubscriptionIds, input.getEvent().getUuidKey());
final boolean isEventDryRunForNotifications = input.getEvent().isDryRunForInvoiceNotification() != null ? input.getEvent().isDryRunForInvoiceNotification() : false;
if (isEventForSubscription && !isEventDryRunForNotifications) {
effectiveDates.add(input.getEffectiveDate());
}
}
return effectiveDates;
} catch (final NoSuchNotificationQueue noSuchNotificationQueue) {
throw new IllegalStateException(noSuchNotificationQueue);
}
}
use of org.killbill.notificationq.api.NotificationEventWithMetadata in project killbill by killbill.
the class DefaultOverduePosterBase method clearOverdueCheckNotifications.
@Override
public <T extends OverdueCheckNotificationKey> void clearOverdueCheckNotifications(final UUID accountId, final String overdueQueueName, final Class<T> clazz, final InternalCallContext context) {
try {
final NotificationQueue checkOverdueQueue = notificationQueueService.getNotificationQueue(DefaultOverdueService.OVERDUE_SERVICE_NAME, overdueQueueName);
transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<Void>() {
@Override
public Void inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
final Iterable<NotificationEventWithMetadata<T>> futureNotifications = getFutureNotificationsForAccountInTransaction(entitySqlDaoWrapperFactory, checkOverdueQueue, clazz, context);
for (final NotificationEventWithMetadata<T> notification : futureNotifications) {
checkOverdueQueue.removeNotificationFromTransaction(entitySqlDaoWrapperFactory.getHandle().getConnection(), notification.getRecordId());
}
return null;
}
});
} catch (final NoSuchNotificationQueue e) {
log.error("Attempting to clear items from a non-existent queue (DefaultOverdueCheck).", e);
}
}
use of org.killbill.notificationq.api.NotificationEventWithMetadata in project killbill by killbill.
the class TestIncompletePaymentTransactionTaskWithDB method testHandleLockExceptions.
@Test(groups = "slow", description = "https://github.com/killbill/killbill/issues/675")
public void testHandleLockExceptions() throws PaymentApiException {
final Payment payment = paymentApi.createPurchase(account, account.getPaymentMethodId(), null, BigDecimal.TEN, Currency.EUR, UUID.randomUUID().toString(), UUID.randomUUID().toString(), ImmutableList.<PluginProperty>of(new PluginProperty(MockPaymentProviderPlugin.PLUGIN_PROPERTY_PAYMENT_PLUGIN_STATUS_OVERRIDE, PaymentPluginStatus.PENDING.toString(), false)), callContext);
final UUID transactionId = payment.getTransactions().get(0).getId();
final JanitorNotificationKey notificationKey = new JanitorNotificationKey(transactionId, incompletePaymentTransactionTask.getClass().toString(), 1);
final UUID userToken = UUID.randomUUID();
Assert.assertTrue(Iterables.<NotificationEventWithMetadata<NotificationEvent>>isEmpty(incompletePaymentTransactionTask.janitorQueue.getFutureNotificationForSearchKeys(internalCallContext.getAccountRecordId(), internalCallContext.getTenantRecordId())));
GlobalLock lock = null;
try {
lock = locker.lockWithNumberOfTries(LockerType.ACCNT_INV_PAY.toString(), account.getId().toString(), paymentConfig.getMaxGlobalLockRetries());
incompletePaymentTransactionTask.processNotification(notificationKey, userToken, internalCallContext.getAccountRecordId(), internalCallContext.getTenantRecordId());
final Iterable<NotificationEventWithMetadata<NotificationEvent>> futureNotifications = incompletePaymentTransactionTask.janitorQueue.getFutureNotificationForSearchKeys(internalCallContext.getAccountRecordId(), internalCallContext.getTenantRecordId());
Assert.assertFalse(Iterables.<NotificationEventWithMetadata<NotificationEvent>>isEmpty(futureNotifications));
final NotificationEventWithMetadata<NotificationEvent> notificationEventWithMetadata = ImmutableList.<NotificationEventWithMetadata<NotificationEvent>>copyOf(futureNotifications).get(0);
Assert.assertEquals(notificationEventWithMetadata.getUserToken(), userToken);
Assert.assertEquals(notificationEventWithMetadata.getEvent().getClass(), JanitorNotificationKey.class);
final JanitorNotificationKey event = (JanitorNotificationKey) notificationEventWithMetadata.getEvent();
Assert.assertEquals(event.getUuidKey(), transactionId);
Assert.assertEquals((int) event.getAttemptNumber(), 2);
// Based on config "15s,1m,3m,1h,1d,1d,1d,1d,1d"
Assert.assertTrue(notificationEventWithMetadata.getEffectiveDate().compareTo(clock.getUTCNow().plusMinutes(1).plusSeconds(1)) < 0);
} catch (final LockFailedException e) {
Assert.fail();
} finally {
if (lock != null) {
lock.release();
}
}
}
Aggregations