Search in sources :

Example 1 with NotificationEventWithMetadata

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;
}
Also used : PaymentAttemptModelDao(org.killbill.billing.payment.dao.PaymentAttemptModelDao) NoSuchNotificationQueue(org.killbill.notificationq.api.NotificationQueueService.NoSuchNotificationQueue) DefaultPaymentAttempt(org.killbill.billing.payment.api.DefaultPaymentAttempt) ArrayList(java.util.ArrayList) PaymentRetryNotificationKey(org.killbill.billing.payment.retry.PaymentRetryNotificationKey) DefaultPaymentAttempt(org.killbill.billing.payment.api.DefaultPaymentAttempt) PaymentAttempt(org.killbill.billing.payment.api.PaymentAttempt) NotificationEventWithMetadata(org.killbill.notificationq.api.NotificationEventWithMetadata) NotificationEvent(org.killbill.notificationq.api.NotificationEvent) NotificationQueue(org.killbill.notificationq.api.NotificationQueue) NoSuchNotificationQueue(org.killbill.notificationq.api.NotificationQueueService.NoSuchNotificationQueue)

Example 2 with NotificationEventWithMetadata

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();
}
Also used : BusEventWithMetadata(org.killbill.bus.api.BusEventWithMetadata) OutputStream(java.io.OutputStream) TenantContext(org.killbill.billing.util.callcontext.TenantContext) StreamingOutput(javax.ws.rs.core.StreamingOutput) NotificationEvent(org.killbill.notificationq.api.NotificationEvent) DateTime(org.joda.time.DateTime) JsonGenerator(com.fasterxml.jackson.core.JsonGenerator) NotificationEventWithMetadata(org.killbill.notificationq.api.NotificationEventWithMetadata) BusEvent(org.killbill.bus.api.BusEvent) Path(javax.ws.rs.Path) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses)

Example 3 with NotificationEventWithMetadata

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);
    }
}
Also used : NoSuchNotificationQueue(org.killbill.notificationq.api.NotificationQueueService.NoSuchNotificationQueue) NextBillingDateNotificationKey(org.killbill.billing.invoice.notification.NextBillingDateNotificationKey) NotificationEventWithMetadata(org.killbill.notificationq.api.NotificationEventWithMetadata) NotificationQueue(org.killbill.notificationq.api.NotificationQueue) NoSuchNotificationQueue(org.killbill.notificationq.api.NotificationQueueService.NoSuchNotificationQueue) LinkedList(java.util.LinkedList) DateTime(org.joda.time.DateTime)

Example 4 with NotificationEventWithMetadata

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);
    }
}
Also used : NoSuchNotificationQueue(org.killbill.notificationq.api.NotificationQueueService.NoSuchNotificationQueue) EntitySqlDaoWrapperFactory(org.killbill.billing.util.entity.dao.EntitySqlDaoWrapperFactory) NotificationEventWithMetadata(org.killbill.notificationq.api.NotificationEventWithMetadata) NoSuchNotificationQueue(org.killbill.notificationq.api.NotificationQueueService.NoSuchNotificationQueue) NotificationQueue(org.killbill.notificationq.api.NotificationQueue)

Example 5 with NotificationEventWithMetadata

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();
        }
    }
}
Also used : GlobalLock(org.killbill.commons.locker.GlobalLock) PluginProperty(org.killbill.billing.payment.api.PluginProperty) Payment(org.killbill.billing.payment.api.Payment) LockFailedException(org.killbill.commons.locker.LockFailedException) NotificationEvent(org.killbill.notificationq.api.NotificationEvent) NotificationEventWithMetadata(org.killbill.notificationq.api.NotificationEventWithMetadata) UUID(java.util.UUID) Test(org.testng.annotations.Test)

Aggregations

NotificationEventWithMetadata (org.killbill.notificationq.api.NotificationEventWithMetadata)10 NotificationQueue (org.killbill.notificationq.api.NotificationQueue)7 NoSuchNotificationQueue (org.killbill.notificationq.api.NotificationQueueService.NoSuchNotificationQueue)7 NotificationEvent (org.killbill.notificationq.api.NotificationEvent)5 DateTime (org.joda.time.DateTime)4 IOException (java.io.IOException)2 LocalDate (org.joda.time.LocalDate)2 JsonGenerator (com.fasterxml.jackson.core.JsonGenerator)1 ApiOperation (io.swagger.annotations.ApiOperation)1 ApiResponses (io.swagger.annotations.ApiResponses)1 OutputStream (java.io.OutputStream)1 ArrayList (java.util.ArrayList)1 LinkedList (java.util.LinkedList)1 UUID (java.util.UUID)1 Nullable (javax.annotation.Nullable)1 GET (javax.ws.rs.GET)1 Path (javax.ws.rs.Path)1 Produces (javax.ws.rs.Produces)1 StreamingOutput (javax.ws.rs.core.StreamingOutput)1 PlanPhasePriceOverride (org.killbill.billing.catalog.api.PlanPhasePriceOverride)1