@Override public void onError(Exception exception, EventMessage<?> event, EventMessageHandler eventHandler) { logger.error("EventListener [{}] failed to handle event [{}] ({}). " + "Continuing processing with next listener", eventHandler.getTargetType().getSimpleName(), event.getIdentifier(), event.getPayloadType().getName(), exception); } }
private void doPublish(EventMessage<?> message, T target) { getHandler(message).ifPresent(h -> { try { h.handle(message, target); } catch (Exception e) { throw new MessageHandlerInvocationException( format("Error handling event of type [%s] in aggregate", message.getPayloadType()), e); } }); children.forEach(i -> i.publish(message, target)); }
@Override public ResultValidator<T> expectEvents(EventMessage... expectedEvents) { this.expectEvents(Stream.of(expectedEvents).map(Message::getPayload).toArray()); Iterator<EventMessage<?>> iterator = publishedEvents.iterator(); for (EventMessage expectedEvent : expectedEvents) { EventMessage actualEvent = iterator.next(); if (!verifyMetaDataEquality(expectedEvent.getPayloadType(), expectedEvent.getMetaData(), actualEvent.getMetaData())) { reporter.reportWrongEvent(publishedEvents, Arrays.asList(expectedEvents), actualException); } } return this; }
/** * Builds the JobDetail instance for Quartz, which defines the Job that needs to be executed when the trigger * fires. * <p/> * The resulting JobDetail must be identified by the given {@code jobKey} and represent a Job that dispatches * the given {@code event}. * <p/> * This method may be safely overridden to change behavior. Defaults to a JobDetail to fire a {@link FireEventJob}. * * @param event The event to be scheduled for dispatch * @param jobKey The key of the Job to schedule * @return a JobDetail describing the Job to be executed */ protected JobDetail buildJobDetail(EventMessage event, JobKey jobKey) { JobDataMap jobData = jobDataBinder.toJobData(event); return JobBuilder.newJob(FireEventJob.class) .withDescription(event.getPayloadType().getName()) .withIdentity(jobKey) .usingJobData(jobData) .build(); }
@SuppressWarnings("unchecked") @Override public void run() { EventMessage<?> eventMessage = createMessage(); if (logger.isDebugEnabled()) { logger.debug("Triggered the publication of event [{}]", eventMessage.getPayloadType().getSimpleName()); } try { UnitOfWork<EventMessage<?>> unitOfWork = new DefaultUnitOfWork<>(null); unitOfWork.attachTransaction(transactionManager); unitOfWork.execute(() -> eventBus.publish(eventMessage)); } finally { tokens.remove(tokenId); } }
@Override public BiFunction<Integer, EventMessage<?>, EventMessage<?>> handle(List<? extends EventMessage<?>> messages) { StringBuilder sb = new StringBuilder(String.format("Events published: [%s]", messages.stream().map(m -> m.getPayloadType().getSimpleName()).collect(Collectors.joining(", ")))); CurrentUnitOfWork.ifStarted(unitOfWork -> { Message<?> message = unitOfWork.getMessage(); if (message == null) { sb.append(" while processing an operation not tied to an incoming message"); } else { sb.append(String.format(" while processing a [%s]", message.getPayloadType().getSimpleName())); } ExecutionResult executionResult = unitOfWork.getExecutionResult(); if (executionResult != null) { if (executionResult.isExceptionResult()) { @SuppressWarnings("ThrowableResultOfMethodCallIgnored") Throwable exception = executionResult.getExceptionResult(); exception = exception instanceof ExecutionException ? exception.getCause() : exception; sb.append(String.format(" which failed with a [%s]", exception.getClass().getSimpleName())); } else if (executionResult.getResult() != null) { sb.append(String.format(" which yielded a [%s] return value", executionResult.getResult().getClass().getSimpleName())); } } }); logger.info(sb.toString()); return (i, m) -> m; } }
@Override public void execute(JobExecutionContext context) throws JobExecutionException { logger.debug("Starting job to publish a scheduled event"); JobDetail jobDetail = context.getJobDetail(); JobDataMap jobData = jobDetail.getJobDataMap(); try { SchedulerContext schedulerContext = context.getScheduler().getContext(); EventJobDataBinder jobDataBinder = (EventJobDataBinder) schedulerContext.get(EVENT_JOB_DATA_BINDER_KEY); Object event = jobDataBinder.fromJobData(jobData); EventMessage<?> eventMessage = createMessage(event); EventBus eventBus = (EventBus) context.getScheduler().getContext().get(EVENT_BUS_KEY); TransactionManager txManager = (TransactionManager) context.getScheduler().getContext().get(TRANSACTION_MANAGER_KEY); UnitOfWork<EventMessage<?>> unitOfWork = DefaultUnitOfWork.startAndGet(null); if (txManager != null) { unitOfWork.attachTransaction(txManager); } unitOfWork.execute(() -> eventBus.publish(eventMessage)); if (logger.isInfoEnabled()) { logger.info("Job successfully executed. Scheduled Event [{}] has been published.", eventMessage.getPayloadType().getSimpleName()); } } catch (Exception e) { logger.error("Exception occurred while publishing scheduled event [{}]", jobDetail.getDescription(), e); throw new JobExecutionException(e); } }
@Test public void testCommandsAreRoutedToCorrectEntity() throws Exception { AggregateModel<Book> bookAggregateModel = AnnotatedAggregateMetaModelFactory.inspectAggregate(Book.class); EventBus mockEventBus = SimpleEventBus.builder().build(); mockEventBus.subscribe(m -> m.forEach(i -> System.out.println(i.getPayloadType().getName()))); AnnotatedAggregate<Book> bookAggregate = AnnotatedAggregate.initialize((Book) null, bookAggregateModel, mockEventBus); bookAggregate.handle(command(new CreateBookCommand("book1"))); bookAggregate.handle(command(new CreatePageCommand("book1"))); bookAggregate.handle(command(new CreateParagraphCommand("book1", 0))); bookAggregate.handle(command(new CreateParagraphCommand("book1", 0))); bookAggregate.handle(command(new UpdateParagraphCommand("book1", 0, 0, "Hello world"))); bookAggregate.handle(command(new UpdateParagraphCommand("book1", 0, 1, "Hello world2"))); assertEquals("Hello world", bookAggregate.getAggregateRoot().getPages().get(0).getParagraphs().get(0).getText()); assertEquals("Hello world2", bookAggregate.getAggregateRoot().getPages().get(0).getParagraphs().get(1).getText()); }
@Override public String resolveRoutingKey(EventMessage<?> event) { return event.getPayloadType().getPackage().getName(); } }
@Override public String resolveRoutingKey(EventMessage<?> event) { return event.getPayloadType().getPackage().getName(); } }
@Override public void onError(Exception exception, EventMessage<?> event, EventListener eventListener) { Class<?> eventListenerType = getEventListenerType(eventListener); logger.error("EventListener [{}] failed to handle event [{}] ({}). " + "Continuing processing with next listener", eventListenerType.getSimpleName(), event.getIdentifier(), event.getPayloadType().getName(), exception); }
@Override public void onError(Exception exception, EventMessage<?> event, EventMessageHandler eventHandler) { logger.error("EventListener [{}] failed to handle event [{}] ({}). " + "Continuing processing with next listener", eventHandler.getTargetType().getSimpleName(), event.getIdentifier(), event.getPayloadType().getName(), exception); } }
private void doPublish(EventMessage<?> message, T target) { getHandler(message).ifPresent(h -> { try { h.handle(message, target); } catch (Exception e) { throw new MessageHandlerInvocationException( format("Error handling event of type [%s] in aggregate", message.getPayloadType()), e); } }); children.forEach(i -> i.publish(message, target)); }
/** * Builds the JobDetail instance for Quartz, which defines the Job that needs to be executed when the trigger * fires. * <p/> * The resulting JobDetail must be identified by the given {@code jobKey} and represent a Job that dispatches * the given {@code event}. * <p/> * This method may be safely overridden to change behavior. Defaults to a JobDetail to fire a {@link FireEventJob}. * * @param event The event to be scheduled for dispatch * @param jobKey The key of the Job to schedule * @return a JobDetail describing the Job to be executed */ protected JobDetail buildJobDetail(EventMessage event, JobKey jobKey) { JobDataMap jobData = jobDataBinder.toJobData(event); return JobBuilder.newJob(FireEventJob.class) .withDescription(event.getPayloadType().getName()) .withIdentity(jobKey) .usingJobData(jobData) .build(); }
private void doPublish(EventMessage<?> message, T target) { getHandler(message).ifPresent(h -> { try { h.handle(message, target); } catch (Exception e) { throw new MessageHandlerInvocationException( format("Error handling event of type [%s] in aggregate", message.getPayloadType()), e); } }); children.forEach(i -> i.publish(message, target)); }
/** * Builds the JobDetail instance for Quartz, which defines the Job that needs to be executed when the trigger * fires. * <p/> * The resulting JobDetail must be identified by the given {@code jobKey} and represent a Job that dispatches * the given {@code event}. * <p/> * This method may be safely overridden to change behavior. Defaults to a JobDetail to fire a {@link FireEventJob}. * * @param event The event to be scheduled for dispatch * @param jobKey The key of the Job to schedule * @return a JobDetail describing the Job to be executed */ protected JobDetail buildJobDetail(EventMessage event, JobKey jobKey) { JobDataMap jobData = jobDataBinder.toJobData(event); return JobBuilder.newJob(FireEventJob.class) .withDescription(event.getPayloadType().getName()) .withIdentity(jobKey) .usingJobData(jobData) .build(); }
@SuppressWarnings("unchecked") @Override public void run() { EventMessage<?> eventMessage = createMessage(); if (logger.isDebugEnabled()) { logger.debug("Triggered the publication of event [{}]", eventMessage.getPayloadType().getSimpleName()); } try { UnitOfWork<EventMessage<?>> unitOfWork = new DefaultUnitOfWork<>(null); unitOfWork.attachTransaction(transactionManager); unitOfWork.execute(() -> eventBus.publish(eventMessage)); } finally { tokens.remove(tokenId); } }
@Override public BiFunction<Integer, EventMessage<?>, EventMessage<?>> handle(List<? extends EventMessage<?>> messages) { StringBuilder sb = new StringBuilder(String.format("Events published: [%s]", messages.stream().map(m -> m.getPayloadType().getSimpleName()).collect(Collectors.joining(", ")))); CurrentUnitOfWork.ifStarted(unitOfWork -> { Message<?> message = unitOfWork.getMessage(); if (message == null) { sb.append(" while processing an operation not tied to an incoming message"); } else { sb.append(String.format(" while processing a [%s]", message.getPayloadType().getSimpleName())); } ExecutionResult executionResult = unitOfWork.getExecutionResult(); if (executionResult != null) { if (executionResult.isExceptionResult()) { @SuppressWarnings("ThrowableResultOfMethodCallIgnored") Throwable exception = executionResult.getExceptionResult(); exception = exception instanceof ExecutionException ? exception.getCause() : exception; sb.append(String.format(" which failed with a [%s]", exception.getClass().getSimpleName())); } else if (executionResult.getResult() != null) { sb.append(String.format(" which yielded a [%s] return value", executionResult.getResult().getClass().getSimpleName())); } } }); logger.info(sb.toString()); return (i, m) -> m; } }
@SuppressWarnings("unchecked") @Override public void run() { EventMessage<?> eventMessage = createMessage(); if (logger.isDebugEnabled()) { logger.debug("Triggered the publication of event [{}]", eventMessage.getPayloadType().getSimpleName()); } try { UnitOfWork<EventMessage<?>> unitOfWork = new DefaultUnitOfWork<>(null); unitOfWork.attachTransaction(transactionManager); unitOfWork.execute(() -> eventBus.publish(eventMessage)); } finally { tokens.remove(tokenId); } }
@Override public void execute(JobExecutionContext context) throws JobExecutionException { logger.debug("Starting job to publish a scheduled event"); JobDetail jobDetail = context.getJobDetail(); JobDataMap jobData = jobDetail.getJobDataMap(); try { SchedulerContext schedulerContext = context.getScheduler().getContext(); EventJobDataBinder jobDataBinder = (EventJobDataBinder) schedulerContext.get(EVENT_JOB_DATA_BINDER_KEY); Object event = jobDataBinder.fromJobData(jobData); EventMessage<?> eventMessage = createMessage(event); EventBus eventBus = (EventBus) context.getScheduler().getContext().get(EVENT_BUS_KEY); TransactionManager txManager = (TransactionManager) context.getScheduler().getContext().get(TRANSACTION_MANAGER_KEY); UnitOfWork<EventMessage<?>> unitOfWork = DefaultUnitOfWork.startAndGet(null); if (txManager != null) { unitOfWork.attachTransaction(txManager); } unitOfWork.execute(() -> eventBus.publish(eventMessage)); if (logger.isInfoEnabled()) { logger.info("Job successfully executed. Scheduled Event [{}] has been published.", eventMessage.getPayloadType().getSimpleName()); } } catch (Exception e) { logger.error("Exception occurred while publishing scheduled event [{}]", jobDetail.getDescription(), e); throw new JobExecutionException(e); } }