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);
}
}
}
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);
}
}
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();
}
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);
}
}
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();
}
}
}
Aggregations