start
This commit is contained in:
289
src/main/java/com/auction/AuctionMonitorResource.java
Normal file
289
src/main/java/com/auction/AuctionMonitorResource.java
Normal file
@@ -0,0 +1,289 @@
|
||||
package com.auction;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.ws.rs.*;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* REST API for Auction Monitor control and status.
|
||||
* Provides endpoints for:
|
||||
* - Status checking
|
||||
* - Manual workflow triggers
|
||||
* - Statistics
|
||||
*/
|
||||
@Path("/api/monitor")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public class AuctionMonitorResource {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(AuctionMonitorResource.class);
|
||||
|
||||
@Inject
|
||||
DatabaseService db;
|
||||
|
||||
@Inject
|
||||
QuarkusWorkflowScheduler scheduler;
|
||||
|
||||
@Inject
|
||||
NotificationService notifier;
|
||||
|
||||
/**
|
||||
* GET /api/monitor/status
|
||||
* Returns current monitoring status
|
||||
*/
|
||||
@GET
|
||||
@Path("/status")
|
||||
public Response getStatus() {
|
||||
try {
|
||||
Map<String, Object> status = new HashMap<>();
|
||||
status.put("running", true);
|
||||
status.put("auctions", db.getAllAuctions().size());
|
||||
status.put("lots", db.getAllLots().size());
|
||||
status.put("images", db.getImageCount());
|
||||
|
||||
// Count closing soon
|
||||
int closingSoon = 0;
|
||||
for (var lot : db.getAllLots()) {
|
||||
if (lot.closingTime() != null && lot.minutesUntilClose() < 30) {
|
||||
closingSoon++;
|
||||
}
|
||||
}
|
||||
status.put("closingSoon", closingSoon);
|
||||
|
||||
return Response.ok(status).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
LOG.error("Failed to get status", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /api/monitor/statistics
|
||||
* Returns detailed statistics
|
||||
*/
|
||||
@GET
|
||||
@Path("/statistics")
|
||||
public Response getStatistics() {
|
||||
try {
|
||||
Map<String, Object> stats = new HashMap<>();
|
||||
|
||||
var auctions = db.getAllAuctions();
|
||||
var lots = db.getAllLots();
|
||||
|
||||
stats.put("totalAuctions", auctions.size());
|
||||
stats.put("totalLots", lots.size());
|
||||
stats.put("totalImages", db.getImageCount());
|
||||
|
||||
// Lot statistics
|
||||
int activeLots = 0;
|
||||
int lotsWithBids = 0;
|
||||
double totalBids = 0;
|
||||
|
||||
for (var lot : lots) {
|
||||
if (lot.closingTime() != null && lot.minutesUntilClose() > 0) {
|
||||
activeLots++;
|
||||
}
|
||||
if (lot.currentBid() > 0) {
|
||||
lotsWithBids++;
|
||||
totalBids += lot.currentBid();
|
||||
}
|
||||
}
|
||||
|
||||
stats.put("activeLots", activeLots);
|
||||
stats.put("lotsWithBids", lotsWithBids);
|
||||
stats.put("totalBidValue", String.format("€%.2f", totalBids));
|
||||
stats.put("averageBid", lotsWithBids > 0 ? String.format("€%.2f", totalBids / lotsWithBids) : "€0.00");
|
||||
|
||||
return Response.ok(stats).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
LOG.error("Failed to get statistics", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* POST /api/monitor/trigger/scraper-import
|
||||
* Manually trigger scraper import workflow
|
||||
*/
|
||||
@POST
|
||||
@Path("/trigger/scraper-import")
|
||||
public Response triggerScraperImport() {
|
||||
try {
|
||||
scheduler.importScraperData();
|
||||
return Response.ok(Map.of("message", "Scraper import triggered successfully")).build();
|
||||
} catch (Exception e) {
|
||||
LOG.error("Failed to trigger scraper import", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* POST /api/monitor/trigger/image-processing
|
||||
* Manually trigger image processing workflow
|
||||
*/
|
||||
@POST
|
||||
@Path("/trigger/image-processing")
|
||||
public Response triggerImageProcessing() {
|
||||
try {
|
||||
scheduler.processImages();
|
||||
return Response.ok(Map.of("message", "Image processing triggered successfully")).build();
|
||||
} catch (Exception e) {
|
||||
LOG.error("Failed to trigger image processing", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* POST /api/monitor/trigger/bid-monitoring
|
||||
* Manually trigger bid monitoring workflow
|
||||
*/
|
||||
@POST
|
||||
@Path("/trigger/bid-monitoring")
|
||||
public Response triggerBidMonitoring() {
|
||||
try {
|
||||
scheduler.monitorBids();
|
||||
return Response.ok(Map.of("message", "Bid monitoring triggered successfully")).build();
|
||||
} catch (Exception e) {
|
||||
LOG.error("Failed to trigger bid monitoring", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* POST /api/monitor/trigger/closing-alerts
|
||||
* Manually trigger closing alerts workflow
|
||||
*/
|
||||
@POST
|
||||
@Path("/trigger/closing-alerts")
|
||||
public Response triggerClosingAlerts() {
|
||||
try {
|
||||
scheduler.checkClosingTimes();
|
||||
return Response.ok(Map.of("message", "Closing alerts triggered successfully")).build();
|
||||
} catch (Exception e) {
|
||||
LOG.error("Failed to trigger closing alerts", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /api/monitor/auctions
|
||||
* Returns list of all auctions
|
||||
*/
|
||||
@GET
|
||||
@Path("/auctions")
|
||||
public Response getAuctions(@QueryParam("country") String country) {
|
||||
try {
|
||||
var auctions = country != null && !country.isEmpty()
|
||||
? db.getAuctionsByCountry(country)
|
||||
: db.getAllAuctions();
|
||||
|
||||
return Response.ok(auctions).build();
|
||||
} catch (Exception e) {
|
||||
LOG.error("Failed to get auctions", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /api/monitor/lots
|
||||
* Returns list of active lots
|
||||
*/
|
||||
@GET
|
||||
@Path("/lots")
|
||||
public Response getActiveLots() {
|
||||
try {
|
||||
var lots = db.getActiveLots();
|
||||
return Response.ok(lots).build();
|
||||
} catch (Exception e) {
|
||||
LOG.error("Failed to get lots", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /api/monitor/lots/closing-soon
|
||||
* Returns lots closing within specified minutes (default 30)
|
||||
*/
|
||||
@GET
|
||||
@Path("/lots/closing-soon")
|
||||
public Response getLotsClosingSoon(@QueryParam("minutes") @DefaultValue("30") int minutes) {
|
||||
try {
|
||||
var allLots = db.getActiveLots();
|
||||
var closingSoon = allLots.stream()
|
||||
.filter(lot -> lot.closingTime() != null && lot.minutesUntilClose() < minutes)
|
||||
.toList();
|
||||
|
||||
return Response.ok(closingSoon).build();
|
||||
} catch (Exception e) {
|
||||
LOG.error("Failed to get closing lots", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /api/monitor/lots/{lotId}/images
|
||||
* Returns images for a specific lot
|
||||
*/
|
||||
@GET
|
||||
@Path("/lots/{lotId}/images")
|
||||
public Response getLotImages(@PathParam("lotId") int lotId) {
|
||||
try {
|
||||
var images = db.getImagesForLot(lotId);
|
||||
return Response.ok(images).build();
|
||||
} catch (Exception e) {
|
||||
LOG.error("Failed to get lot images", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* POST /api/monitor/test-notification
|
||||
* Send a test notification
|
||||
*/
|
||||
@POST
|
||||
@Path("/test-notification")
|
||||
public Response sendTestNotification(Map<String, String> request) {
|
||||
try {
|
||||
String message = request.getOrDefault("message", "Test notification from Auction Monitor");
|
||||
String title = request.getOrDefault("title", "Test Notification");
|
||||
int priority = Integer.parseInt(request.getOrDefault("priority", "0"));
|
||||
|
||||
notifier.sendNotification(message, title, priority);
|
||||
|
||||
return Response.ok(Map.of("message", "Test notification sent successfully")).build();
|
||||
} catch (Exception e) {
|
||||
LOG.error("Failed to send test notification", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user