From e629c522eb1563ffcd9a14a8124cc560fda8be77 Mon Sep 17 00:00:00 2001 From: melchinger Date: Wed, 28 Aug 2024 15:04:24 +0200 Subject: [PATCH] ProcessingOrder: Implementation of the order history class and the usage of it. Odip: Fix in findProductsByClassAndStartStop, use Map<...> instead of RestProduct --- .../model/service/RepositoryService.java | 14 +++- .../ordermgr/rest/ProcessingOrderMgr.java | 19 +++++- .../planner/dispatcher/OrderDispatcher.java | 1 + .../proseo/planner/util/OrderPlanThread.java | 1 + .../planner/util/OrderReleaseThread.java | 4 ++ .../de/dlr/proseo/planner/util/OrderUtil.java | 64 ++++++++++++++++++- 6 files changed, 100 insertions(+), 3 deletions(-) diff --git a/model/src/main/java/de/dlr/proseo/model/service/RepositoryService.java b/model/src/main/java/de/dlr/proseo/model/service/RepositoryService.java index ecb5b3f51..40f3f5fd8 100644 --- a/model/src/main/java/de/dlr/proseo/model/service/RepositoryService.java +++ b/model/src/main/java/de/dlr/proseo/model/service/RepositoryService.java @@ -30,6 +30,7 @@ import de.dlr.proseo.model.dao.MonServiceStateRepository; import de.dlr.proseo.model.dao.OrbitRepository; import de.dlr.proseo.model.dao.OrderRepository; +import de.dlr.proseo.model.dao.ProcessingOrderHistoryRepository; import de.dlr.proseo.model.dao.ClassOutputParameterRepository; import de.dlr.proseo.model.dao.ProcessorClassRepository; import de.dlr.proseo.model.dao.ProcessorRepository; @@ -182,6 +183,10 @@ public class RepositoryService { @Autowired private MonExtServiceStateOperationMonthRepository monExtServiceStateOperationMonthRepository; + /** The repository for the ProcessingOrder class */ + @Autowired + private ProcessingOrderHistoryRepository processingOrderHistoryRepository; + /** The repository for the Workflow class */ @Autowired private WorkflowRepository workflowRepository; @@ -464,7 +469,7 @@ public static MonServiceStateOperationMonthRepository getMonServiceStateOperatio public static MonExtServiceStateOperationDayRepository getMonExtServiceStateOperationDayRepository() { return theRepositoryService.monExtServiceStateOperationDayRepository; } - + /** * @return the monExtServiceStateOperationMonthRepository */ @@ -472,6 +477,13 @@ public static MonExtServiceStateOperationMonthRepository getMonExtServiceStateOp return theRepositoryService.monExtServiceStateOperationMonthRepository; } + /** + * @return the processingOrderHistoryRepository + */ + public static ProcessingOrderHistoryRepository getProcessingOrderHistoryRepository() { + return theRepositoryService.processingOrderHistoryRepository; + } + /** * @return the workflowRepository */ diff --git a/order-mgr/src/main/java/de/dlr/proseo/ordermgr/rest/ProcessingOrderMgr.java b/order-mgr/src/main/java/de/dlr/proseo/ordermgr/rest/ProcessingOrderMgr.java index 99f86ca5e..05666ab06 100644 --- a/order-mgr/src/main/java/de/dlr/proseo/ordermgr/rest/ProcessingOrderMgr.java +++ b/order-mgr/src/main/java/de/dlr/proseo/ordermgr/rest/ProcessingOrderMgr.java @@ -51,6 +51,7 @@ import de.dlr.proseo.model.Parameter; import de.dlr.proseo.model.ProcessingFacility; import de.dlr.proseo.model.ProcessingOrder; +import de.dlr.proseo.model.ProcessingOrderHistory; import de.dlr.proseo.model.Product; import de.dlr.proseo.model.ProductClass; import de.dlr.proseo.model.ProductQuery; @@ -340,7 +341,17 @@ public RestOrder createOrder(RestOrder order) throws IllegalArgumentException, S // Everything OK, store new order in database modelOrder = RepositoryService.getOrderRepository().save(modelOrder); logger.log(OrderMgrMessage.ORDER_CREATED, order.getIdentifier(), order.getMissionCode()); - + + // Create and initialize the history element of the processing order. + ProcessingOrderHistory orderHistory = new ProcessingOrderHistory(); + orderHistory.setIdentifier(modelOrder.getIdentifier()); + orderHistory.setMissionCode(modelOrder.getMission().getCode()); + orderHistory.setCreationTime(Instant.now()); + orderHistory.setOrderState(modelOrder.getOrderState()); + for (ProductClass pc : modelOrder.getRequestedProductClasses()) { + orderHistory.getProductTypes().add(pc.getProductType()); + } + RepositoryService.getProcessingOrderHistoryRepository().save(orderHistory); return OrderUtil.toRestOrder(modelOrder); } catch (org.springframework.dao.DataIntegrityViolationException e) { @@ -431,6 +442,12 @@ private void deleteOrder(ProcessingOrder order) throws EntityNotFoundException, prepareOrderToDelete(order); // Delete the order long id = order.getId(); + ProcessingOrderHistory history = RepositoryService.getProcessingOrderHistoryRepository() + .findByMissionCodeAndIdentifier(order.getMission().getCode(), order.getIdentifier()); + if (history != null) { + history.setDeletionTime(Instant.now()); + RepositoryService.getProcessingOrderHistoryRepository().save(history); + } RepositoryService.getOrderRepository().delete(order); // Test whether the deletion was successful Optional modelOrder = RepositoryService.getOrderRepository().findById(id); diff --git a/planner/src/main/java/de/dlr/proseo/planner/dispatcher/OrderDispatcher.java b/planner/src/main/java/de/dlr/proseo/planner/dispatcher/OrderDispatcher.java index 05502dbc5..8edfb3948 100644 --- a/planner/src/main/java/de/dlr/proseo/planner/dispatcher/OrderDispatcher.java +++ b/planner/src/main/java/de/dlr/proseo/planner/dispatcher/OrderDispatcher.java @@ -172,6 +172,7 @@ public PlannerResultMessage prepareExpectedJobs(long orderId, ProcessingFacility order.setStateMessage(ProductionPlanner.STATE_MESSAGE_COMPLETED); answer.setMessage(PlannerMessage.ORDER_ALREADY_COMPLETED); + UtilService.getOrderUtil().setOrderHistory(order); } break; diff --git a/planner/src/main/java/de/dlr/proseo/planner/util/OrderPlanThread.java b/planner/src/main/java/de/dlr/proseo/planner/util/OrderPlanThread.java index 5da3a5620..4c2354cae 100644 --- a/planner/src/main/java/de/dlr/proseo/planner/util/OrderPlanThread.java +++ b/planner/src/main/java/de/dlr/proseo/planner/util/OrderPlanThread.java @@ -273,6 +273,7 @@ public PlannerResultMessage plan(long orderId) throws InterruptedException { UtilService.getOrderUtil().setTimes(lambdaOrder); UtilService.getOrderUtil().setStateMessage(lambdaOrder, ProductionPlanner.STATE_MESSAGE_COMPLETED); lambdaAnswer.setMessage(PlannerMessage.ORDER_PRODUCT_EXIST); + UtilService.getOrderUtil().setOrderHistory(lambdaOrder); } else { lambdaOrder.setOrderState(OrderState.PLANNED); UtilService.getOrderUtil().setStateMessage(lambdaOrder, ProductionPlanner.STATE_MESSAGE_QUEUED); diff --git a/planner/src/main/java/de/dlr/proseo/planner/util/OrderReleaseThread.java b/planner/src/main/java/de/dlr/proseo/planner/util/OrderReleaseThread.java index a1c7ae76b..1a74955cc 100644 --- a/planner/src/main/java/de/dlr/proseo/planner/util/OrderReleaseThread.java +++ b/planner/src/main/java/de/dlr/proseo/planner/util/OrderReleaseThread.java @@ -431,6 +431,7 @@ public int compare(Job o1, Job o2) { UtilService.getOrderUtil().setTimes(lambdaOrder); UtilService.getOrderUtil().setStateMessage(lambdaOrder, ProductionPlanner.STATE_MESSAGE_COMPLETED); lambdaAnswer.setMessage(PlannerMessage.ORDER_PRODUCT_EXIST); + UtilService.getOrderUtil().setOrderHistory(lambdaOrder); } else { // check whether order is already running Boolean running = false; @@ -449,6 +450,7 @@ public int compare(Job o1, Job o2) { } } lambdaAnswer.setMessage(PlannerMessage.ORDER_RELEASED); + UtilService.getOrderUtil().setOrderHistory(lambdaOrder); } lambdaAnswer.setText(logger.log(lambdaAnswer.getMessage(), lambdaOrder.getIdentifier())); lambdaOrder.incrementVersion(); @@ -485,6 +487,8 @@ public int compare(Job o1, Job o2) { logger.debug("... exception in getOrderRepository.save2(" + lambdaOrder.getIdentifier() + "): ", e); throw e; } + + UtilService.getOrderUtil().setOrderHistory(lambdaOrder); } return lambdaAnswer; }); diff --git a/planner/src/main/java/de/dlr/proseo/planner/util/OrderUtil.java b/planner/src/main/java/de/dlr/proseo/planner/util/OrderUtil.java index 381c7f63b..b50e9e6ef 100644 --- a/planner/src/main/java/de/dlr/proseo/planner/util/OrderUtil.java +++ b/planner/src/main/java/de/dlr/proseo/planner/util/OrderUtil.java @@ -42,6 +42,7 @@ import de.dlr.proseo.model.JobStep; import de.dlr.proseo.model.ProcessingFacility; import de.dlr.proseo.model.ProcessingOrder; +import de.dlr.proseo.model.ProcessingOrderHistory; import de.dlr.proseo.model.Product; import de.dlr.proseo.model.ProductFile; import de.dlr.proseo.model.enums.OrderSource; @@ -121,6 +122,7 @@ public PlannerResultMessage cancel(ProcessingOrder orderX) { order.incrementVersion(); RepositoryService.getOrderRepository().save(order); logOrderState(order); + UtilService.getOrderUtil().setOrderHistory(order); answer.setMessage(PlannerMessage.ORDER_CANCELED); break; case RELEASED: @@ -358,6 +360,7 @@ public PlannerResultMessage delete(ProcessingOrder order) { case INITIAL: case APPROVED: // jobs are in initial state, no change + UtilService.getOrderUtil().setOrderHistoryOrderDeleted(order); RepositoryService.getOrderRepository().delete(order); answer.setMessage(PlannerMessage.ORDER_DELETED); break; @@ -383,6 +386,7 @@ public PlannerResultMessage delete(ProcessingOrder order) { RepositoryService.getJobRepository().delete(job); } } + UtilService.getOrderUtil().setOrderHistoryOrderDeleted(order); RepositoryService.getOrderRepository().delete(order); answer.setMessage(PlannerMessage.ORDER_DELETED); break; @@ -915,7 +919,8 @@ public PlannerResultMessage suspend(long id, Boolean force) { setStateMessage(orderz, ProductionPlanner.STATE_MESSAGE_COMPLETED); checkAutoClose(orderz); RepositoryService.getOrderRepository().save(orderz); - logOrderState(orderz); + logOrderState(orderz); + UtilService.getOrderUtil().setOrderHistory(orderz); return new PlannerResultMessage(PlannerMessage.ORDER_COMPLETED); } else { orderz.setOrderState(OrderState.PLANNED); @@ -1229,6 +1234,7 @@ public PlannerResultMessage retry(ProcessingOrder order) { order.incrementVersion(); RepositoryService.getOrderRepository().save(order); answer.setMessage(PlannerMessage.ORDER_COMPLETED); + UtilService.getOrderUtil().setOrderHistory(order); } else { if (order.getOrderState() == OrderState.RUNNING) { order.setOrderState(OrderState.SUSPENDING); @@ -1322,6 +1328,7 @@ public PlannerResultMessage close(Long orderId) { locOrder.setOrderState(OrderState.CLOSED); if (locOrder.getHasFailedJobSteps()) { setStateMessage(locOrder, ProductionPlanner.STATE_MESSAGE_FAILED); + UtilService.getOrderUtil().setOrderHistory(locOrder); } else { setStateMessage(locOrder, ProductionPlanner.STATE_MESSAGE_COMPLETED); } @@ -1408,12 +1415,14 @@ public Boolean checkFinish(Long orderId) { checkAutoClose(order); setTimes(order); setStateMessage(order, ProductionPlanner.STATE_MESSAGE_COMPLETED); + UtilService.getOrderUtil().setOrderHistory(order); } else { order.setOrderState(OrderState.FAILED); setStateMessage(order, ProductionPlanner.STATE_MESSAGE_FAILED); } checkFurther = true; RepositoryService.getOrderRepository().save(order); + UtilService.getOrderUtil().setOrderHistory(order); em.merge(order); hasChanged = true; } @@ -1457,12 +1466,14 @@ public Boolean checkFinish(Long orderId) { order.setOrderState(OrderState.FAILED); setStateMessage(order, ProductionPlanner.STATE_MESSAGE_FAILED); RepositoryService.getOrderRepository().save(order); + UtilService.getOrderUtil().setOrderHistory(order); em.merge(order); } else { order.setOrderState(OrderState.COMPLETED); setTimes(order); setStateMessage(order, ProductionPlanner.STATE_MESSAGE_COMPLETED); checkAutoClose(order); + UtilService.getOrderUtil().setOrderHistory(order); sendNotification(order); } hasChanged = true; @@ -1531,6 +1542,57 @@ public void setStateMessage(ProcessingOrder order, String stateMessage) { } } + /** + * Set the order state and time of an order history object. + * The time setting depends on the current order state. + * + * @param order The processing order + */ + @Transactional(isolation = Isolation.REPEATABLE_READ) + public void setOrderHistory(ProcessingOrder order) { + if (order != null) { + ProcessingOrderHistory history = RepositoryService.getProcessingOrderHistoryRepository() + .findByMissionCodeAndIdentifier(order.getMission().getCode(), order.getIdentifier()); + if (history != null) { + history.setOrderState(order.getOrderState()); + switch (order.getOrderState()) { + case RELEASED: + case RUNNING: + if (history.getReleaseTime() == null) { + history.setReleaseTime(Instant.now()); + } + break; + case FAILED: + case COMPLETED: + if (history.getCompletionTime() == null) { + history.setCompletionTime(Instant.now()); + } + break; + default: + break; + } + RepositoryService.getProcessingOrderHistoryRepository().save(history); + } + } + } + + /** + * Set the deletion time of an order history object. + * + * @param order The processing order + */ + @Transactional(isolation = Isolation.REPEATABLE_READ) + public void setOrderHistoryOrderDeleted(ProcessingOrder order) { + if (order != null) { + ProcessingOrderHistory history = RepositoryService.getProcessingOrderHistoryRepository() + .findByMissionCodeAndIdentifier(order.getMission().getCode(), order.getIdentifier()); + if (history != null) { + history.setDeletionTime(Instant.now()); + RepositoryService.getProcessingOrderHistoryRepository().save(history); + } + } + } + @Transactional(isolation = Isolation.REPEATABLE_READ) public Boolean sendNotification(ProcessingOrder order) {