Search in sources :

Example 6 with NotificationEvent

use of org.killbill.notificationq.api.NotificationEvent in project killbill by killbill.

the class DefaultBlockingStateDao method recordBusOrFutureNotificationFromTransaction.

private void recordBusOrFutureNotificationFromTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory, final UUID blockingStateId, final DateTime effectiveDate, final UUID blockableId, final BlockingStateType type, final String stateName, final String serviceName, final boolean blockingStateInserted, final BlockingAggregator previousState, final BlockingAggregator currentState, final InternalCallContext context) {
    final boolean isTransitionToBlockedBilling = !previousState.isBlockBilling() && currentState.isBlockBilling();
    final boolean isTransitionToUnblockedBilling = previousState.isBlockBilling() && !currentState.isBlockBilling();
    final boolean isTransitionToBlockedEntitlement = !previousState.isBlockEntitlement() && currentState.isBlockEntitlement();
    final boolean isTransitionToUnblockedEntitlement = previousState.isBlockEntitlement() && !currentState.isBlockEntitlement();
    if (effectiveDate.compareTo(clock.getUTCNow()) > 0) {
        // Add notification entry to send the bus event at the effective date
        final NotificationEvent notificationEvent = new BlockingTransitionNotificationKey(blockingStateId, blockableId, stateName, serviceName, effectiveDate, type, isTransitionToBlockedBilling, isTransitionToUnblockedBilling, isTransitionToBlockedEntitlement, isTransitionToUnblockedEntitlement);
        recordFutureNotificationFromTransaction(entitySqlDaoWrapperFactory, effectiveDate, notificationEvent, context);
    } else {
        if (blockingStateInserted) {
            final BusEvent event = new DefaultBlockingTransitionInternalEvent(blockableId, stateName, serviceName, effectiveDate, type, isTransitionToBlockedBilling, isTransitionToUnblockedBilling, isTransitionToBlockedEntitlement, isTransitionToUnblockedEntitlement, context.getAccountRecordId(), context.getTenantRecordId(), context.getUserToken());
            notifyBusFromTransaction(entitySqlDaoWrapperFactory, event);
        } else {
            log.debug("Skipping event for service {} and blockableId {} (previousState={}, currentState={})", serviceName, blockableId, previousState, currentState);
        }
    }
}
Also used : BlockingTransitionNotificationKey(org.killbill.billing.entitlement.engine.core.BlockingTransitionNotificationKey) DefaultBlockingTransitionInternalEvent(org.killbill.billing.entitlement.api.DefaultBlockingTransitionInternalEvent) NotificationEvent(org.killbill.notificationq.api.NotificationEvent) BusEvent(org.killbill.bus.api.BusEvent)

Example 7 with NotificationEvent

use of org.killbill.notificationq.api.NotificationEvent in project killbill by killbill.

the class DefaultEntitlementService method blockAddOnsIfRequired.

private void blockAddOnsIfRequired(final EntitlementNotificationKey key, final DefaultEntitlement entitlement, final TenantContext callContext, final InternalCallContext internalCallContext) throws EntitlementApiException {
    final Collection<NotificationEvent> notificationEvents = new ArrayList<NotificationEvent>();
    final Collection<BlockingState> blockingStates = entitlement.computeAddOnBlockingStates(key.getEffectiveDate(), notificationEvents, callContext, internalCallContext);
    // Record the new state first, then insert the notifications to avoid race conditions
    entitlementUtils.setBlockingStatesAndPostBlockingTransitionEvent(blockingStates, entitlement.getBundleId(), internalCallContext);
    for (final NotificationEvent notificationEvent : notificationEvents) {
        recordFutureNotification(key.getEffectiveDate(), notificationEvent, internalCallContext);
    }
}
Also used : ArrayList(java.util.ArrayList) NotificationEvent(org.killbill.notificationq.api.NotificationEvent) BlockingState(org.killbill.billing.entitlement.api.BlockingState)

Example 8 with NotificationEvent

use of org.killbill.notificationq.api.NotificationEvent 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 9 with NotificationEvent

use of org.killbill.notificationq.api.NotificationEvent in project killbill by killbill.

the class DefaultOverdueNotifierBase method initialize.

@Override
public void initialize() {
    final OverdueNotifier myself = this;
    final NotificationQueueHandler notificationQueueHandler = new NotificationQueueHandler() {

        @Override
        public void handleReadyNotification(final NotificationEvent notificationKey, final DateTime eventDate, final UUID userToken, final Long accountRecordId, final Long tenantRecordId) {
            myself.handleReadyNotification(notificationKey, eventDate, userToken, accountRecordId, tenantRecordId);
        }
    };
    try {
        overdueQueue = notificationQueueService.createNotificationQueue(DefaultOverdueService.OVERDUE_SERVICE_NAME, getQueueName(), notificationQueueHandler);
    } catch (NotificationQueueAlreadyExists e) {
        throw new RuntimeException(e);
    }
}
Also used : NotificationEvent(org.killbill.notificationq.api.NotificationEvent) UUID(java.util.UUID) NotificationQueueAlreadyExists(org.killbill.notificationq.api.NotificationQueueService.NotificationQueueAlreadyExists) NotificationQueueHandler(org.killbill.notificationq.api.NotificationQueueService.NotificationQueueHandler) DateTime(org.joda.time.DateTime)

Example 10 with NotificationEvent

use of org.killbill.notificationq.api.NotificationEvent 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

NotificationEvent (org.killbill.notificationq.api.NotificationEvent)21 DateTime (org.joda.time.DateTime)16 InternalCallContext (org.killbill.billing.callcontext.InternalCallContext)9 ArrayList (java.util.ArrayList)8 UUID (java.util.UUID)8 DefaultBlockingState (org.killbill.billing.junction.DefaultBlockingState)7 PlanPhasePriceOverride (org.killbill.billing.catalog.api.PlanPhasePriceOverride)6 WithEntitlementPlugin (org.killbill.billing.entitlement.api.EntitlementPluginExecution.WithEntitlementPlugin)6 EntitlementContext (org.killbill.billing.entitlement.plugin.api.EntitlementContext)6 SubscriptionBaseApiException (org.killbill.billing.subscription.api.user.SubscriptionBaseApiException)6 NotificationQueueHandler (org.killbill.notificationq.api.NotificationQueueService.NotificationQueueHandler)6 EntitlementLoggingHelper.logCancelEntitlement (org.killbill.billing.entitlement.logging.EntitlementLoggingHelper.logCancelEntitlement)5 EntitlementLoggingHelper.logUncancelEntitlement (org.killbill.billing.entitlement.logging.EntitlementLoggingHelper.logUncancelEntitlement)5 NotificationEventWithMetadata (org.killbill.notificationq.api.NotificationEventWithMetadata)5 CatalogApiException (org.killbill.billing.catalog.api.CatalogApiException)3 NotificationQueue (org.killbill.notificationq.api.NotificationQueue)3 BlockingState (org.killbill.billing.entitlement.api.BlockingState)2 BlockingTransitionNotificationKey (org.killbill.billing.entitlement.engine.core.BlockingTransitionNotificationKey)2 EntitlementNotificationKey (org.killbill.billing.entitlement.engine.core.EntitlementNotificationKey)2 LifecycleHandlerType (org.killbill.billing.platform.api.LifecycleHandlerType)2