|
|
|
@@ -6,6 +6,7 @@ import static io.smallrye.graphql.client.core.Field.field;
|
|
|
|
|
import static io.smallrye.graphql.client.core.Operation.operation;
|
|
|
|
|
|
|
|
|
|
import com.drinkool.dtos.CartItemRequest;
|
|
|
|
|
import com.drinkool.dtos.event.MenuItemValidation;
|
|
|
|
|
import io.quarkus.redis.datasource.ReactiveRedisDataSource;
|
|
|
|
|
import io.quarkus.redis.datasource.hash.ReactiveHashCommands;
|
|
|
|
|
import io.quarkus.redis.datasource.keys.ReactiveKeyCommands;
|
|
|
|
@@ -21,6 +22,7 @@ import jakarta.ws.rs.QueryParam;
|
|
|
|
|
import jakarta.ws.rs.core.Response;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.UUID;
|
|
|
|
|
import org.eclipse.microprofile.reactive.messaging.Incoming;
|
|
|
|
|
|
|
|
|
|
@Path("/")
|
|
|
|
|
public class CartController {
|
|
|
|
@@ -58,16 +60,16 @@ public class CartController {
|
|
|
|
|
|
|
|
|
|
return valueCommands
|
|
|
|
|
.get(eateryCacheKey)
|
|
|
|
|
.chain((String existsInCache) -> {
|
|
|
|
|
if (existsInCache != null && existsInCache.equals("true")) {
|
|
|
|
|
return Uni.createFrom().item(Boolean.TRUE);
|
|
|
|
|
}
|
|
|
|
|
.<Boolean>chain(existsInCache -> {
|
|
|
|
|
if (
|
|
|
|
|
existsInCache != null && Boolean.TRUE.equals(existsInCache)
|
|
|
|
|
) return Uni.createFrom().item(Boolean.TRUE);
|
|
|
|
|
|
|
|
|
|
var query = document(
|
|
|
|
|
operation(
|
|
|
|
|
field(
|
|
|
|
|
"eateryById",
|
|
|
|
|
List.of(arg("id", eateryId.toString())), // Bọc arg vào List.of()
|
|
|
|
|
List.of(arg("id", eateryId.toString())),
|
|
|
|
|
field("id")
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
@@ -75,28 +77,21 @@ public class CartController {
|
|
|
|
|
|
|
|
|
|
return dynamicClient
|
|
|
|
|
.executeAsync(query)
|
|
|
|
|
.map(response -> {
|
|
|
|
|
if (response.hasError()) {
|
|
|
|
|
return false;
|
|
|
|
|
.map(response -> !response.hasError() && response.getData() != null);
|
|
|
|
|
})
|
|
|
|
|
.chain(isValid -> {
|
|
|
|
|
if (Boolean.TRUE.equals(isValid)) {
|
|
|
|
|
String cartId = UUID.randomUUID().toString();
|
|
|
|
|
return valueCommands
|
|
|
|
|
.setex("cart:" + cartId, 86400, eateryId.toString())
|
|
|
|
|
.replaceWith(Response.ok(cartId).build());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var data = response.getData();
|
|
|
|
|
return data != null && !data.isNull("eateryById");
|
|
|
|
|
});
|
|
|
|
|
})
|
|
|
|
|
.map((Boolean isValid) -> {
|
|
|
|
|
if (isValid) {
|
|
|
|
|
String cartId = UUID.randomUUID().toString();
|
|
|
|
|
valueCommands
|
|
|
|
|
.setex("cart:" + cartId, 86400, eateryId.toString())
|
|
|
|
|
.subscribe()
|
|
|
|
|
.with(item -> {});
|
|
|
|
|
return Response.ok(cartId).build();
|
|
|
|
|
} else {
|
|
|
|
|
return Response.status(Response.Status.NOT_FOUND)
|
|
|
|
|
.entity("EateryNotFound")
|
|
|
|
|
.build();
|
|
|
|
|
}
|
|
|
|
|
return Uni.createFrom().item(
|
|
|
|
|
Response.status(Response.Status.NOT_FOUND)
|
|
|
|
|
.entity("InvalidEateryId")
|
|
|
|
|
.build()
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -121,25 +116,27 @@ public class CartController {
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UUID eateryId = UUID.fromString(cart);
|
|
|
|
|
|
|
|
|
|
return valueCommands
|
|
|
|
|
.get(menuKey)
|
|
|
|
|
.chain(menuData -> {
|
|
|
|
|
return hashCommands
|
|
|
|
|
.chain(menuData ->
|
|
|
|
|
hashCommands
|
|
|
|
|
.hincrby(
|
|
|
|
|
cartItemsKey,
|
|
|
|
|
request.menuItemId.toString(),
|
|
|
|
|
request.quantity
|
|
|
|
|
)
|
|
|
|
|
.call(_ -> keyCommands.expire(cartItemsKey, 86400))
|
|
|
|
|
.map(b -> menuData);
|
|
|
|
|
})
|
|
|
|
|
.call(_ -> keyCommands.expire(cartItemsKey, 86400L))
|
|
|
|
|
.replaceWith(menuData)
|
|
|
|
|
)
|
|
|
|
|
.map(menuData -> {
|
|
|
|
|
if (menuData != null) {
|
|
|
|
|
return Response.ok("ItemAdded").build();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
validationEmitter.send(
|
|
|
|
|
new MenuItemValidationEvent(request.menuItemId, cartId)
|
|
|
|
|
new MenuItemValidation(request.menuItemId, eateryId)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return Response.status(Response.Status.ACCEPTED)
|
|
|
|
@@ -148,4 +145,22 @@ public class CartController {
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Incoming("menu-validation-results") // Tên channel trong application.properties
|
|
|
|
|
public Uni<Void> processValidationResult(MenuItemStatusEvent event) {
|
|
|
|
|
// Giả sử event trả về có: menuItemId, eateryId, exists (boolean)
|
|
|
|
|
|
|
|
|
|
if (!event.exists) {
|
|
|
|
|
// Nếu món ăn không tồn tại, ta xóa nó khỏi Redis
|
|
|
|
|
// Lưu ý: Vì ta không biết món này nằm ở cartId nào (do bạn yêu cầu bỏ cartId)
|
|
|
|
|
// Bạn sẽ cần một chiến lược tìm kiếm hoặc quản lý key hiệu quả.
|
|
|
|
|
// Cách 1: Nếu bạn có danh sách Cart của Eatery đó, duyệt qua và xóa:
|
|
|
|
|
// String cartItemsKey = "cart:" + event.cartId + ":items";
|
|
|
|
|
// return hashCommands.hdel(cartItemsKey, event.menuItemId.toString()).replaceWithVoid();
|
|
|
|
|
// Cách 2: Nếu xóa cache thông tin món ăn để các request sau cũng fail:
|
|
|
|
|
// return keyCommands.del("menu:item:" + event.menuItemId).replaceWithVoid();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Uni.createFrom().voidItem();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|