Fix mock tests
This commit is contained in:
@@ -38,6 +38,20 @@ class ImageProcessingService {
|
||||
*/
|
||||
boolean processImage(int imageId, String localPath, long lotId) {
|
||||
try {
|
||||
// Check if file exists before processing
|
||||
var file = new java.io.File(localPath);
|
||||
if (!file.exists() || !file.canRead()) {
|
||||
log.warn(" Image file not accessible: {}", localPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check file size (skip very large files that might cause issues)
|
||||
long fileSizeBytes = file.length();
|
||||
if (fileSizeBytes > 50 * 1024 * 1024) { // 50 MB limit
|
||||
log.warn(" Image file too large ({}MB): {}", fileSizeBytes / (1024 * 1024), localPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Run object detection on the local file
|
||||
var labels = detector.detectObjects(localPath);
|
||||
|
||||
|
||||
@@ -104,7 +104,16 @@ public class ObjectDetectionService {
|
||||
for (var i = 0; i < out.rows(); i++) {
|
||||
var data = out.get(i, 0);
|
||||
if (data == null) continue;
|
||||
|
||||
// The first 5 numbers are bounding box, then class scores
|
||||
// Check if data has enough elements before copying
|
||||
int expectedLength = 5 + classNames.size();
|
||||
if (data.length < expectedLength) {
|
||||
log.warn("Detection data too short: expected {} elements, got {}. Skipping detection.",
|
||||
expectedLength, data.length);
|
||||
continue;
|
||||
}
|
||||
|
||||
var scores = new double[classNames.size()];
|
||||
System.arraycopy(data, 5, scores, 0, scores.length);
|
||||
var classId = argMax(scores);
|
||||
@@ -117,6 +126,13 @@ public class ObjectDetectionService {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Release resources
|
||||
image.release();
|
||||
blob.release();
|
||||
for (var out : outs) {
|
||||
out.release();
|
||||
}
|
||||
return labels;
|
||||
}
|
||||
/**
|
||||
|
||||
@@ -94,10 +94,20 @@ public class QuarkusWorkflowScheduler {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG.infof(" → Processing %d images", pendingImages.size());
|
||||
// Limit batch size to prevent thread blocking (max 100 images per run)
|
||||
final int MAX_BATCH_SIZE = 100;
|
||||
int totalPending = pendingImages.size();
|
||||
if (totalPending > MAX_BATCH_SIZE) {
|
||||
LOG.infof(" → Found %d pending images, processing first %d (batch limit)",
|
||||
totalPending, MAX_BATCH_SIZE);
|
||||
pendingImages = pendingImages.subList(0, MAX_BATCH_SIZE);
|
||||
} else {
|
||||
LOG.infof(" → Processing %d images", totalPending);
|
||||
}
|
||||
|
||||
var processed = 0;
|
||||
var detected = 0;
|
||||
var failed = 0;
|
||||
|
||||
for (var image : pendingImages) {
|
||||
try {
|
||||
@@ -121,19 +131,26 @@ public class QuarkusWorkflowScheduler {
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
failed++;
|
||||
}
|
||||
|
||||
// Rate limiting (lighter since no network I/O)
|
||||
Thread.sleep(100);
|
||||
|
||||
|
||||
} catch (Exception e) {
|
||||
failed++;
|
||||
LOG.warnf(" ⚠️ Failed to process image: %s", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
var duration = System.currentTimeMillis() - start;
|
||||
LOG.infof(" ✓ Processed %d images, detected objects in %d (%.1fs)",
|
||||
processed, detected, duration / 1000.0);
|
||||
LOG.infof(" ✓ Processed %d/%d images, detected objects in %d, failed %d (%.1fs)",
|
||||
processed, totalPending, detected, failed, duration / 1000.0);
|
||||
|
||||
if (totalPending > MAX_BATCH_SIZE) {
|
||||
LOG.infof(" → %d images remaining for next run", totalPending - MAX_BATCH_SIZE);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
LOG.errorf(e, " ❌ Image processing failed: %s", e.getMessage());
|
||||
|
||||
7
src/main/resources/META-INF/resources/favicon.svg
Normal file
7
src/main/resources/META-INF/resources/favicon.svg
Normal file
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<rect width="100" height="100" fill="#2563eb" rx="15"/>
|
||||
<path d="M25 40 L50 20 L75 40 L75 70 L25 70 Z" fill="#ffffff" stroke="#ffffff" stroke-width="2"/>
|
||||
<circle cx="50" cy="45" r="8" fill="#2563eb"/>
|
||||
<rect x="40" y="55" width="20" height="3" fill="#2563eb"/>
|
||||
<text x="50" y="90" font-family="Arial" font-size="12" fill="#ffffff" text-anchor="middle" font-weight="bold">AUCTION</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 465 B |
@@ -1355,11 +1355,32 @@ function updatePagination(total, perPage, currentPage) {
|
||||
|
||||
// Trigger workflow with progress tracking
|
||||
async function triggerWorkflow(workflow) {
|
||||
const statusId = `status-${workflow.split('-')[0]}`;
|
||||
const progressId = `progress-${workflow.split('-')[0]}`;
|
||||
// Map workflow names to DOM element IDs
|
||||
const idMap = {
|
||||
'scraper-import': 'scraper',
|
||||
'image-processing': 'images',
|
||||
'bid-monitoring': 'bids',
|
||||
'closing-alerts': 'alerts'
|
||||
};
|
||||
|
||||
const elementId = idMap[workflow];
|
||||
if (!elementId) {
|
||||
console.error('Unknown workflow:', workflow);
|
||||
showToast(`Unknown workflow: ${workflow}`, 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
const statusId = `status-${elementId}`;
|
||||
const progressId = `progress-${elementId}`;
|
||||
const statusEl = document.getElementById(statusId);
|
||||
const progressEl = document.getElementById(progressId);
|
||||
|
||||
if (!statusEl || !progressEl) {
|
||||
console.error('Workflow UI elements not found:', statusId, progressId);
|
||||
showToast(`Cannot trigger workflow: UI elements not found`, 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
// Update UI
|
||||
statusEl.innerHTML = '<span class="inline-block w-2 h-2 bg-blue-500 rounded-full mr-1 animate-pulse"></span>Running';
|
||||
statusEl.className = 'text-xs font-semibold px-2 py-1 rounded-full bg-blue-100 text-blue-800';
|
||||
|
||||
Reference in New Issue
Block a user