use of io.confluent.examples.streams.avro.microservices.Order in project kafka-streams-examples by confluentinc.
the class OrdersService method fetchLocal.
/**
* Fetch the order from the local materialized view
*
* @param id ID to fetch
* @param asyncResponse the response to call once completed
* @param predicate a filter that for this fetch, so for example we might fetch only VALIDATED
* orders.
*/
private void fetchLocal(String id, AsyncResponse asyncResponse, Predicate<String, Order> predicate) {
log.info("running GET on this node");
try {
Order order = ordersStore().get(id);
if (order == null || !predicate.test(id, order)) {
log.info("Delaying get as order not present for id " + id);
outstandingRequests.put(id, new FilteredResponse<>(asyncResponse, predicate));
} else {
asyncResponse.resume(toBean(order));
}
} catch (InvalidStateStoreException e) {
// Store not ready so delay
outstandingRequests.put(id, new FilteredResponse<>(asyncResponse, predicate));
}
}
use of io.confluent.examples.streams.avro.microservices.Order in project kafka-streams-examples by confluentinc.
the class ValidationsAggregatorService method aggregateOrderValidations.
private KafkaStreams aggregateOrderValidations(String bootstrapServers, String stateDir) {
// TODO put into a KTable to make dynamically configurable
final int numberOfRules = 3;
StreamsBuilder builder = new StreamsBuilder();
KStream<String, OrderValidation> validations = builder.stream(ORDER_VALIDATIONS.name(), serdes1);
KStream<String, Order> orders = builder.stream(ORDERS.name(), serdes2).filter((id, order) -> OrderState.CREATED.equals(order.getState()));
// If all rules pass then validate the order
validations.groupByKey(serdes3).windowedBy(SessionWindows.with(5 * MIN)).aggregate(() -> 0L, (id, result, total) -> PASS.equals(result.getValidationResult()) ? total + 1 : total, // include a merger as we're using session windows.
(k, a, b) -> b == null ? a : b, Materialized.with(null, Serdes.Long())).toStream((windowedKey, total) -> windowedKey.key()).filter((k1, v) -> v != null).filter((k, total) -> total >= numberOfRules).join(orders, (id, order) -> newBuilder(order).setState(VALIDATED).build(), JoinWindows.of(5 * MIN), serdes4).to(ORDERS.name(), serdes5);
// If any rule fails then fail the order
validations.filter((id, rule) -> FAIL.equals(rule.getValidationResult())).join(orders, (id, order) -> newBuilder(order).setState(OrderState.FAILED).build(), JoinWindows.of(5 * MIN), serdes7).groupByKey(serdes6).reduce((order, v1) -> order).toStream().to(ORDERS.name(), Produced.with(ORDERS.keySerde(), ORDERS.valueSerde()));
return new KafkaStreams(builder.build(), baseStreamsConfig(bootstrapServers, stateDir, ORDERS_SERVICE_APP_ID));
}
use of io.confluent.examples.streams.avro.microservices.Order in project kafka-streams-examples by confluentinc.
the class FraudServiceTest method shouldValidateWhetherOrderAmountExceedsFraudLimitOverWindow.
@Test
public void shouldValidateWhetherOrderAmountExceedsFraudLimitOverWindow() throws Exception {
// Given
fraudService = new FraudService();
List<Order> orders = asList(new Order(id(0L), 0L, CREATED, UNDERPANTS, 3, 5.00d), new Order(id(1L), 0L, CREATED, JUMPERS, 1, 75.00d), new Order(id(2L), 1L, CREATED, JUMPERS, 1, 75.00d), new Order(id(3L), 1L, CREATED, JUMPERS, 1, 75.00d), // Should fail as over limit
new Order(id(4L), 1L, CREATED, JUMPERS, 50, 75.00d), // First should pass
new Order(id(5L), 2L, CREATED, UNDERPANTS, 10, 100.00d), // Second should fail as rolling total by customer is over limit
new Order(id(6L), 2L, CREATED, UNDERPANTS, 10, 100.00d), // Third should fail as rolling total by customer is still over limit
new Order(id(7L), 2L, CREATED, UNDERPANTS, 1, 5.00d));
sendOrders(orders);
// When
fraudService.start(CLUSTER.bootstrapServers());
// Then there should be failures for the two orders that push customers over their limit.
List<OrderValidation> expected = asList(new OrderValidation(id(0L), FRAUD_CHECK, PASS), new OrderValidation(id(1L), FRAUD_CHECK, PASS), new OrderValidation(id(2L), FRAUD_CHECK, PASS), new OrderValidation(id(3L), FRAUD_CHECK, PASS), new OrderValidation(id(4L), FRAUD_CHECK, FAIL), new OrderValidation(id(5L), FRAUD_CHECK, PASS), new OrderValidation(id(6L), FRAUD_CHECK, FAIL), new OrderValidation(id(7L), FRAUD_CHECK, FAIL));
List<OrderValidation> read = read(Topics.ORDER_VALIDATIONS, 8, CLUSTER.bootstrapServers());
assertThat(read).isEqualTo(expected);
}
use of io.confluent.examples.streams.avro.microservices.Order in project kafka-streams-examples by confluentinc.
the class OrdersServiceTest method shouldGetValidatedOrderOnRequest.
@Test
public void shouldGetValidatedOrderOnRequest() {
Order orderV1 = new Order(id(1L), 3L, OrderState.CREATED, Product.JUMPERS, 10, 100d);
OrderBean beanV1 = OrderBean.toBean(orderV1);
final Client client = ClientBuilder.newClient();
// Given a rest service
rest = new OrdersService("localhost");
rest.start(CLUSTER.bootstrapServers());
Paths paths = new Paths("localhost", rest.port());
// When we post an order
client.target(paths.urlPost()).request(APPLICATION_JSON_TYPE).post(Entity.json(beanV1));
// Simulate the order being validated
MicroserviceTestUtils.sendOrders(Collections.singletonList(newBuilder(orderV1).setState(OrderState.VALIDATED).build()));
// When we GET the order from the returned location
OrderBean returnedBean = client.target(paths.urlGetValidated(beanV1.getId())).queryParam("timeout", MIN / 2).request(APPLICATION_JSON_TYPE).get(new GenericType<OrderBean>() {
});
// Then status should be Validated
assertThat(returnedBean.getState()).isEqualTo(OrderState.VALIDATED);
}
use of io.confluent.examples.streams.avro.microservices.Order in project kafka-streams-examples by confluentinc.
the class ValidationsAggregatorServiceTest method shouldAggregateRuleSuccesses.
@Test
public void shouldAggregateRuleSuccesses() throws Exception {
// Given
ordersService = new ValidationsAggregatorService();
orders = asList(new Order(id(0L), 0L, CREATED, UNDERPANTS, 3, 5.00d), new Order(id(1L), 0L, CREATED, JUMPERS, 1, 75.00d));
sendOrders(orders);
ruleResults = asList(new OrderValidation(id(0L), OrderValidationType.FRAUD_CHECK, OrderValidationResult.PASS), new OrderValidation(id(0L), OrderValidationType.ORDER_DETAILS_CHECK, OrderValidationResult.PASS), new OrderValidation(id(0L), OrderValidationType.INVENTORY_CHECK, OrderValidationResult.PASS), new OrderValidation(id(1L), OrderValidationType.FRAUD_CHECK, OrderValidationResult.PASS), new OrderValidation(id(1L), OrderValidationType.ORDER_DETAILS_CHECK, OrderValidationResult.FAIL), new OrderValidation(id(1L), OrderValidationType.INVENTORY_CHECK, OrderValidationResult.PASS));
sendOrderValuations(ruleResults);
// When
ordersService.start(CLUSTER.bootstrapServers());
// Then
List<KeyValue<String, Order>> finalOrders = MicroserviceTestUtils.readKeyValues(Topics.ORDERS, 4, CLUSTER.bootstrapServers());
assertThat(finalOrders.size()).isEqualTo(4);
// And the first order should have been validated but the second should have failed
assertThat(finalOrders.stream().map(kv -> kv.value).collect(Collectors.toList())).contains(new Order(id(0L), 0L, VALIDATED, UNDERPANTS, 3, 5.00d), new Order(id(1L), 0L, FAILED, JUMPERS, 1, 75.00d));
}
Aggregations