@Test
  public void testCreateOrder() throws InterruptedException {
    OrderId orderId = new OrderId();
    commandGateway.send(new CreateOrderCommand(orderId, "TestOrder"));

    UnitOfWork unitOfWork = unitOfWorkProvider.get();
    Assert.assertEquals(
        "Order is not created", orderRepository.load(orderId).getIdentifier(), orderId);
    unitOfWork.commit();

    ItemId itemId1 = new ItemId();
    commandGateway.send(new AddOrderItemCommand(orderId, itemId1, 10));

    final AtomicBoolean injectionSuccessful = new AtomicBoolean();
    commandGateway.send(
        new RemoveOrderItemCommand(orderId, itemId1),
        new CommandCallback<Boolean>() {
          @Override
          public void onSuccess(Boolean result) {
            injectionSuccessful.set(true);
          }

          @Override
          public void onFailure(Throwable cause) {
            logger.error("Error", cause);
          }
        });

    Assert.assertTrue(
        "Injection into @CommandHandler method is not successful", injectionSuccessful.get());
  }
 private void offsetIfPossible(Date offsetDate) {
   if (offsetStatus == TransactionStatus.OFFSETED
       && accountPayableStatus == TransactionStatus.CONFIRMED
       && paidFeeStatus == TransactionStatus.CONFIRMED) {
     commandGateway.send(
         new OffsetAccountPayableFeeCommand(accountPayableId, offsetId, offsetDate));
     commandGateway.send(new OffsetPaidFeeCommand(paidFeeId, offsetId, offsetDate));
   }
 }
  @SagaEventHandler(associationProperty = "offsetId")
  public void onOffsetCancelled(final OffsetCancelledEvent event) {
    offsetStatus = TransactionStatus.CANCELLED;

    commandGateway.send(
        new CancelAccountPayableFeeCommand(
            accountPayableId,
            com.icoin.trading.api.fee.domain.fee.CancelledReason.OFFSET_ERROR,
            event.getCancelledDate()));
    commandGateway.send(
        new CancelPaidFeeCommand(
            paidFeeId,
            com.icoin.trading.api.fee.domain.fee.CancelledReason.OFFSET_ERROR,
            event.getCancelledDate()));
  }
  @SagaEventHandler(associationProperty = "feeId", keyName = "accountPayableId")
  public void onPayableCreated(final AccountPayableFeeCreatedEvent event) {
    accountPayableStatus = TransactionStatus.CREATED;

    commandGateway.send(
        new ConfirmAccountPayableFeeCommand(event.getFeeId(), event.getBusinessCreationTime()));
  }
  /**
   * Tests that exceptions thrown by dispatch interceptors on another thread are handled properly.
   *
   * <p>Documentation states,
   *
   * <blockquote>
   *
   * Exceptions have the following effect:<br>
   * Any declared checked exception will be thrown if the Command Handler (or an interceptor) threw
   * an exceptions of that type. If a checked exception is thrown that has not been declared, it is
   * wrapped in a CommandExecutionException, which is a RuntimeException.<br>
   * &hellip;
   *
   * </blockquote>
   */
  @Test(
      expected =
          SecurityException.class, // per documentation, an unchecked exception (theoretically
      // the only kind throwable by an interceptor) is returned unwrapped
      timeout =
          10000) // bug is that the caller waits forever for a CommandCallback.onFailure that never
                 // comes...
  public void testCommandDipatchInterceptorExceptionOnRetryThreadIsThrownToCaller() {
    commandGateway = new DefaultCommandGateway(commandBus, retryScheduler);

    // trigger retry
    commandBus.subscribe(
        String.class.getName(),
        new CommandHandler<String>() {
          @Override
          public Object handle(CommandMessage<String> commandMessage, UnitOfWork unitOfWork)
              throws Throwable {
            throw new ConcurrencyException("some retryable exception");
          }
        });

    // say we have a dispatch interceptor that expects to get the user's session from a
    // ThreadLocal...
    // yes, this should be configured on the gateway instead of the command bus, but still...
    final Thread testThread = Thread.currentThread();
    commandBus.setDispatchInterceptors(
        Collections.singletonList(
            new CommandDispatchInterceptor() {
              @Override
              public CommandMessage<?> handle(CommandMessage<?> commandMessage) {
                if (Thread.currentThread() == testThread) {
                  return commandMessage; // ok
                } else {
                  // also, nothing is logged!
                  LoggerFactory.getLogger(getClass()).info("throwing exception from dispatcher...");
                  throw new SecurityException("test dispatch interceptor exception");
                }
              }
            }));

    // wait, but hopefully not forever...
    commandGateway.sendAndWait("command");
  }
  /**
   * It'd be nice if metadata added by a {@linkplain SimpleCommandBus#setDispatchInterceptors(List)
   * command bus's dispatch interceptors} could be preserved, too, but that doesn't seem to be
   * possible given how {@link RetryingCallback} works, so verify that it behaves as designed (if
   * not as "expected").
   */
  @Test(timeout = 10000)
  public void testCommandBusDispatchInterceptorMetaDataIsNotPreservedOnRetry() {
    final Thread testThread = Thread.currentThread();
    commandGateway = new DefaultCommandGateway(commandBus, retryScheduler);

    // trigger retry, then return metadata for verification
    commandBus.subscribe(
        String.class.getName(),
        new CommandHandler<String>() {
          @Override
          public MetaData handle(CommandMessage<String> commandMessage, UnitOfWork unitOfWork)
              throws Throwable {
            if (Thread.currentThread() == testThread) {
              throw new ConcurrencyException("some retryable exception");
            } else {
              return commandMessage.getMetaData();
            }
          }
        });

    commandBus.setDispatchInterceptors(
        Collections.singletonList(
            new CommandDispatchInterceptor() {
              @Override
              public CommandMessage<?> handle(CommandMessage<?> commandMessage) {
                if (Thread.currentThread() == testThread) {
                  return commandMessage.andMetaData(
                      Collections.singletonMap("commandBusMetaData", "myUserSession"));
                } else {
                  // say the security interceptor example
                  // from #testCommandDipatchInterceptorExceptionOnRetryThreadIsThrownToCaller
                  // has been "fixed" -- on the retry thread, there's no security context
                  return commandMessage.andMetaData(
                      Collections.singletonMap("commandBusMetaData", "noUserSession"));
                }
              }
            }));

    assertEquals(
        "noUserSession",
        ((MetaData) commandGateway.sendAndWait("command")).get("commandBusMetaData"));
  }
  /**
   * Tests that metadata added by a {@linkplain
   * AbstractCommandGateway#AbstractCommandGateway(CommandBus,RetryScheduler,List) command gateway's
   * dispatch interceptors} is preserved on retry.
   *
   * <p>It'd be nice if metadata added by a {@linkplain
   * SimpleCommandBus#setDispatchInterceptors(List) command bus's dispatch interceptors} could be
   * preserved, too, but that doesn't seem to be possible given how {@link RetryingCallback} works,
   * so verify that it is not preserved.
   */
  @Test(timeout = 10000)
  public void testCommandGatewayDispatchInterceptorMetaDataIsPreservedOnRetry() {
    final Thread testThread = Thread.currentThread();
    commandGateway =
        new DefaultCommandGateway(
            commandBus,
            retryScheduler,
            new CommandDispatchInterceptor() {
              @Override
              public CommandMessage<?> handle(CommandMessage<?> commandMessage) {
                if (Thread.currentThread() == testThread) {
                  return commandMessage.andMetaData(
                      Collections.singletonMap("gatewayMetaData", "myUserSession"));
                } else {
                  // gateway interceptor should only be called from the caller's thread
                  throw new SecurityException("test dispatch interceptor exception");
                }
              }
            });

    // trigger retry, then return metadata for verification
    commandBus.subscribe(
        String.class.getName(),
        new CommandHandler<String>() {
          @Override
          public MetaData handle(CommandMessage<String> commandMessage, UnitOfWork unitOfWork)
              throws Throwable {
            if (Thread.currentThread() == testThread) {
              throw new ConcurrencyException("some retryable exception");
            } else {
              return commandMessage.getMetaData();
            }
          }
        });

    assertEquals(
        "myUserSession", ((MetaData) commandGateway.sendAndWait("command")).get("gatewayMetaData"));
  }
예제 #8
0
 @SagaEventHandler(associationProperty = "todoId")
 public void onDeadlineExpired(ToDoItemDeadlineExpiredEvent event) {
   commandGateway.send(new MarkToDoItemOverdueCommand(event.getTodoId()));
 }
예제 #9
0
 @Override
 public void approveClient(final String clientId, final Boolean approved, final String comment) {
   commandGateway.send(new ApproveClientCommand(clientId, approved, comment));
 }
예제 #10
0
 @Override
 public String createClient(final Client client) {
   commandGateway.send(
       new CreateClientCommand(client.getUniqueId(), client.getFirstName(), client.getLastName()));
   return client.getUniqueId();
 }
  @SagaEventHandler(associationProperty = "offsetId")
  public void onOffsetCreated(final OffsetCreatedEvent event) {
    offsetStatus = TransactionStatus.CONFIRMED;

    commandGateway.send(new OffsetFeesCommand(offsetId, event.getStartedDate()));
  }
 @SagaEventHandler(associationProperty = "offsetId")
 public void onOffsetAmountNotMatched(final OffsetAmountNotMatchedEvent event) {
   commandGateway.send(
       new CancelOffsetCommand(
           offsetId, CancelledReason.AMOUNT_NOT_MATCHED, event.getOffsetDate()));
 }