180 lines
6.4 KiB
Java
180 lines
6.4 KiB
Java
package com.alexanderlogistics.metrics;
|
|
|
|
import java.util.List;
|
|
import java.util.logging.Logger;
|
|
|
|
import org.imixs.workflow.ItemCollection;
|
|
import org.imixs.workflow.engine.DocumentService;
|
|
import org.imixs.workflow.exceptions.PluginException;
|
|
import org.imixs.workflow.exceptions.QueryException;
|
|
|
|
import com.alexanderlogistics.InvoiceUtil;
|
|
|
|
import jakarta.ejb.Stateless;
|
|
import jakarta.ejb.TransactionAttribute;
|
|
import jakarta.ejb.TransactionAttributeType;
|
|
import jakarta.inject.Inject;
|
|
import jakarta.ws.rs.GET;
|
|
import jakarta.ws.rs.Path;
|
|
import jakarta.ws.rs.Produces;
|
|
import jakarta.ws.rs.core.MediaType;
|
|
import jakarta.ws.rs.core.Response;
|
|
|
|
@Path("metrics/dbtr")
|
|
@Stateless
|
|
public class MetricDebitorRestService {
|
|
|
|
private static Logger logger = Logger.getLogger(MetricDebitorRestService.class.getName());
|
|
|
|
@Inject
|
|
DocumentService documentService;
|
|
|
|
@Inject
|
|
MetricDebitorService metricDebitorService;
|
|
|
|
@Inject
|
|
MetricDataService metricDataService;
|
|
|
|
@GET
|
|
@Path("/ping")
|
|
@Produces({ MediaType.TEXT_PLAIN })
|
|
public String ping() {
|
|
logger.info("GET ping");
|
|
return "ping: " + System.currentTimeMillis();
|
|
}
|
|
|
|
/**
|
|
* This method initializes the metrics for all debitors with open invoices.
|
|
*
|
|
* The method first deletes all existing metrics and than creates or updates the
|
|
* metric entires for each debitor.
|
|
*
|
|
* @return
|
|
*/
|
|
@GET
|
|
@Path("/rebuild")
|
|
@Produces({ MediaType.TEXT_PLAIN })
|
|
public Response rebuildMetrics() {
|
|
|
|
StringBuffer messageBuffer = new StringBuffer();
|
|
long l = System.currentTimeMillis();
|
|
log("├── rebuild dbtr metrics...", messageBuffer);
|
|
|
|
try {
|
|
log("│ ├── delete all metrics", messageBuffer);
|
|
// first clear the metric cache
|
|
metricDebitorService.reset();
|
|
log("│ ├── reset metric cache", messageBuffer);
|
|
|
|
computeMetrics(messageBuffer);
|
|
|
|
String message = "├── rebuild dbtr metrics completed in "
|
|
+ (System.currentTimeMillis() - l)
|
|
+ "ms";
|
|
log(message, messageBuffer);
|
|
return Response.ok().entity(messageBuffer.toString()).build();
|
|
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
log("Failed to initialize metrics: " + e.getMessage(), messageBuffer);
|
|
return Response.serverError()
|
|
.entity(messageBuffer.toString() + e.getMessage())
|
|
.build();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Diese Methode berechnet alle Metriken auf basis der existierenden Rechnungen
|
|
* neu
|
|
*
|
|
* @throws QueryException
|
|
* @throws InterruptedException
|
|
* @throws PluginException
|
|
*
|
|
*/
|
|
public void computeMetrics(StringBuffer messageBuffer)
|
|
throws QueryException, InterruptedException, PluginException {
|
|
long l = System.currentTimeMillis();
|
|
int batchSize = 500;
|
|
int totalInvoices = 0;
|
|
log("│ │ ├── recalculate metrics...", messageBuffer);
|
|
|
|
String query = "$modelversion:rechnungsausgang-* AND type:workitem";
|
|
// Gesamtanzahl ermitteln
|
|
int totalCount = documentService.count(query);
|
|
log("│ │ ├── found " + totalCount + " open invoices", messageBuffer);
|
|
|
|
// Berechne Anzahl der benötigten Pages
|
|
int totalPages = (int) Math.ceil((double) totalCount / batchSize);
|
|
|
|
// Verarbeite Page für Page
|
|
for (int pageIndex = 0; pageIndex < totalPages; pageIndex++) {
|
|
totalInvoices = totalInvoices + computeInvoiceMetrics(query, batchSize, pageIndex);
|
|
// List<ItemCollection> invoices = documentService.find(query, batchSize,
|
|
// pageIndex);
|
|
|
|
// for (ItemCollection invoice : invoices) {
|
|
// try {
|
|
// ItemCollection metricData = metricDebitorService.getMetricByInvoice(invoice);
|
|
// // Jetzt Rechnung addieren
|
|
// metricDebitorService.addInvoice(metricData, invoice);
|
|
// logger.fine("│ │ │ ├── update metric " + InvoiceUtil.getBPId(invoice));
|
|
// metricDebitorService.updateMetric(metricData, true);
|
|
// totalInvoices++;
|
|
// } catch (PluginException e) {
|
|
// // invalid invoice - e.g. no dbtr. number
|
|
// }
|
|
// }
|
|
|
|
// Fortschritt loggen
|
|
log("│ │ ├── Processed page " + (pageIndex + 1) + " of " + totalPages +
|
|
" (" + totalInvoices + " of " + totalCount + " invoices)", messageBuffer);
|
|
// Optional: Kurze Pause nach jedem 5. Batch
|
|
Thread.sleep(100);
|
|
|
|
}
|
|
long duration = System.currentTimeMillis() - l;
|
|
double invoicesPerSecond = totalInvoices / (duration / 1000.0);
|
|
log("│ │ ├── Successfully processed " + totalInvoices + " invoices in " +
|
|
duration + "ms (" + String.format("%.1f", invoicesPerSecond) + " invoices/sec)", messageBuffer);
|
|
log("│ │ ├── Updated " + metricDebitorService.getMetricCount() + " metrics.", messageBuffer);
|
|
|
|
}
|
|
|
|
/**
|
|
* Helper method runs in new transaction
|
|
*
|
|
* @param query
|
|
* @param batchSize
|
|
* @param pageIndex
|
|
* @throws PluginException
|
|
* @throws QueryException
|
|
*/
|
|
@TransactionAttribute(value = TransactionAttributeType.REQUIRES_NEW)
|
|
public int computeInvoiceMetrics(String query, int batchSize, int pageIndex)
|
|
throws PluginException, QueryException {
|
|
|
|
int updates = 0;
|
|
List<ItemCollection> invoices = documentService.find(query, batchSize, pageIndex);
|
|
|
|
for (ItemCollection invoice : invoices) {
|
|
try {
|
|
ItemCollection metricData = metricDebitorService.getMetricByInvoice(invoice);
|
|
// Jetzt Rechnung addieren
|
|
metricDebitorService.addInvoice(metricData, invoice);
|
|
logger.fine("│ │ │ ├── update metric " + InvoiceUtil.getBPId(invoice));
|
|
metricDebitorService.updateMetric(metricData, true);
|
|
updates++;
|
|
} catch (PluginException e) {
|
|
// invalid invoice - e.g. no dbtr. number
|
|
}
|
|
}
|
|
return updates;
|
|
}
|
|
|
|
private void log(String message, StringBuffer messageLog) {
|
|
logger.info(message);
|
|
messageLog.append(message + "\n");
|
|
|
|
}
|
|
}
|