From 0ca7ddff3dbe697a99fe22991e488497103476ed Mon Sep 17 00:00:00 2001
From: Olivier Maury <Olivier.Maury@inrae.fr>
Date: Thu, 22 Feb 2024 14:07:46 +0100
Subject: [PATCH] =?UTF-8?q?Enregistrer=20la=20date=20et=20l'heure=20de=20l?=
 =?UTF-8?q?'int=C3=A9gration.=20fixes=20#6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../seasonhandler/dao/AmiSimulationDao.java   | 27 ++++++++++++
 .../dao/AmiSimulationDaoHibernate.java        | 44 +++++++++++++++++++
 .../seasonhandler/di/DiHelper.java            | 33 ++++++++++----
 .../seasonhandler/jms/SafranReceiver.java     | 26 +++++++----
 .../jms/SimulationDoneReceiver.java           | 31 ++++++++-----
 5 files changed, 132 insertions(+), 29 deletions(-)
 create mode 100644 src/main/java/fr/agrometinfo/seasonhandler/dao/AmiSimulationDao.java
 create mode 100644 src/main/java/fr/agrometinfo/seasonhandler/dao/AmiSimulationDaoHibernate.java

diff --git a/src/main/java/fr/agrometinfo/seasonhandler/dao/AmiSimulationDao.java b/src/main/java/fr/agrometinfo/seasonhandler/dao/AmiSimulationDao.java
new file mode 100644
index 0000000..a72a151
--- /dev/null
+++ b/src/main/java/fr/agrometinfo/seasonhandler/dao/AmiSimulationDao.java
@@ -0,0 +1,27 @@
+package fr.agrometinfo.seasonhandler.dao;
+
+import java.time.LocalDate;
+
+/**
+ * DAO for table "simulation" in AgroMetInfo database.
+ *
+ * @author Olivier Maury
+ */
+public interface AmiSimulationDao {
+
+    /**
+     * Create a row.
+     *
+     * @param date         date to simulate
+     * @param simulationId ID of simulation
+     */
+    void create(LocalDate date, Integer simulationId);
+
+    /**
+     * Update ended column for the simulation.
+     *
+     * @param simulationId ID of simulation
+     */
+    void setEnded(Integer simulationId);
+
+}
diff --git a/src/main/java/fr/agrometinfo/seasonhandler/dao/AmiSimulationDaoHibernate.java b/src/main/java/fr/agrometinfo/seasonhandler/dao/AmiSimulationDaoHibernate.java
new file mode 100644
index 0000000..b51b9ba
--- /dev/null
+++ b/src/main/java/fr/agrometinfo/seasonhandler/dao/AmiSimulationDaoHibernate.java
@@ -0,0 +1,44 @@
+package fr.agrometinfo.seasonhandler.dao;
+
+import java.time.LocalDate;
+
+import fr.inrae.agroclim.season.core.dao.DaoHibernate;
+import fr.inrae.agroclim.season.core.dao.PersistenceManager;
+
+/**
+ * DAO implementation for table "simulation" in AgroMetInfo database.
+ *
+ * @author Olivier Maury
+ */
+public class AmiSimulationDaoHibernate extends DaoHibernate implements AmiSimulationDao {
+    /**
+     * Constructor.
+     *
+     * @param persistenceManager JPA persistence manager for the Simulation
+     *                           database.
+     */
+    public AmiSimulationDaoHibernate(final PersistenceManager persistenceManager) {
+        super(persistenceManager);
+    }
+
+    @Override
+    public final void create(final LocalDate date, final Integer simulationId) {
+        doInJpaTransaction(em -> {
+            final var sql = "INSERT INTO agrometinfo.simulation (date, simulationid) VALUES (?, ?)";
+            final var query = em.createNativeQuery(sql);
+            query.setParameter(1, date);
+            query.setParameter(2, simulationId);
+            query.executeUpdate();
+        });
+    }
+
+    @Override
+    public final void setEnded(final Integer simulationId) {
+        doInJpaTransaction(em -> {
+            final var sql = "UPDATE agrometinfo.simulation SET ended=CURRENT_TIMESTAMP WHERE simulationid=?";
+            final var query = em.createNativeQuery(sql);
+            query.setParameter(1, simulationId);
+            query.executeUpdate();
+        });
+    }
+}
diff --git a/src/main/java/fr/agrometinfo/seasonhandler/di/DiHelper.java b/src/main/java/fr/agrometinfo/seasonhandler/di/DiHelper.java
index d4c4c72..c980b09 100644
--- a/src/main/java/fr/agrometinfo/seasonhandler/di/DiHelper.java
+++ b/src/main/java/fr/agrometinfo/seasonhandler/di/DiHelper.java
@@ -19,6 +19,8 @@ package fr.agrometinfo.seasonhandler.di;
 import java.util.Locale;
 
 import fr.agrometinfo.seasonhandler.MainConfiguration;
+import fr.agrometinfo.seasonhandler.dao.AmiSimulationDao;
+import fr.agrometinfo.seasonhandler.dao.AmiSimulationDaoHibernate;
 import fr.agrometinfo.seasonhandler.dao.DailyvalueDao;
 import fr.agrometinfo.seasonhandler.dao.DailyvalueDaoHibernate;
 import fr.agrometinfo.seasonhandler.jms.SafranReceiver;
@@ -34,6 +36,8 @@ import fr.inrae.agroclim.season.core.dao.SimulationResultDao;
 import fr.inrae.agroclim.season.core.dao.SimulationResultDaoHibernate;
 import fr.inrae.agroclim.season.core.dao.VarietyParameterDao;
 import fr.inrae.agroclim.season.core.dao.VarietyParameterDaoHibernate;
+import fr.inrae.agroclim.season.core.model.Simulation;
+import fr.inrae.agroclim.season.core.model.SimulationResult;
 import lombok.Getter;
 import lombok.RequiredArgsConstructor;
 
@@ -68,6 +72,7 @@ public final class DiHelper {
     public void inject(final SafranReceiver receiver) {
         final PersistenceManager pm = providePersitenceManager();
         receiver.setConfig(config);
+        receiver.setAmiSimulationDao(provideAmiSimulationDao(pm));
         receiver.setClimaticScenarioDao(provideClimaticScenarioDao(pm));
         receiver.setVarietyParameterDao(provideVarietyParameterDao(pm));
         final SimulationLauncher launcher = new SimulationLauncher(config.getDatabaseRoles(), pm);
@@ -82,9 +87,19 @@ public final class DiHelper {
      * @param receiver receiver.
      */
     public void inject(final SimulationDoneReceiver receiver) {
-        receiver.setDailyvalueDao(provideDailyvalueDao());
-        receiver.setSimulationDao(provideSimulationDao());
-        receiver.setSimulationResultDao(provideSimulationResultDao());
+        final PersistenceManager pm = providePersitenceManager();
+        receiver.setAmiSimulationDao(provideAmiSimulationDao(pm));
+        receiver.setDailyvalueDao(provideDailyvalueDao(pm));
+        receiver.setSimulationDao(provideSimulationDao(pm));
+        receiver.setSimulationResultDao(provideSimulationResultDao(pm));
+    }
+
+    /**
+     * @param pm JPA persistence manager
+     * @return DAO for AmiSimulationDao.
+     */
+    private AmiSimulationDao provideAmiSimulationDao(final PersistenceManager pm) {
+        return new AmiSimulationDaoHibernate(pm);
     }
 
     /**
@@ -96,10 +111,10 @@ public final class DiHelper {
     }
 
     /**
+     * @param pm JPA persistence manager
      * @return DAO for dailyvalue table.
      */
-    private DailyvalueDao provideDailyvalueDao() {
-        final PersistenceManager pm = providePersitenceManager();
+    private DailyvalueDao provideDailyvalueDao(final PersistenceManager pm) {
         return new DailyvalueDaoHibernate(pm);
     }
 
@@ -115,18 +130,18 @@ public final class DiHelper {
     }
 
     /**
+     * @param pm JPA persistence manager
      * @return DAO for {@link Simulation}.
      */
-    private SimulationDao provideSimulationDao() {
-        final PersistenceManager pm = providePersitenceManager();
+    private SimulationDao provideSimulationDao(final PersistenceManager pm) {
         return new SimulationDaoHibernate(pm);
     }
 
     /**
+     * @param pm JPA persistence manager
      * @return DAO for {@link SimulationResult}.
      */
-    private SimulationResultDao provideSimulationResultDao() {
-        final PersistenceManager pm = providePersitenceManager();
+    private SimulationResultDao provideSimulationResultDao(final PersistenceManager pm) {
         return new SimulationResultDaoHibernate(pm, config.getDatabaseRoles());
     }
 
diff --git a/src/main/java/fr/agrometinfo/seasonhandler/jms/SafranReceiver.java b/src/main/java/fr/agrometinfo/seasonhandler/jms/SafranReceiver.java
index 4b1eb9e..bb030e0 100644
--- a/src/main/java/fr/agrometinfo/seasonhandler/jms/SafranReceiver.java
+++ b/src/main/java/fr/agrometinfo/seasonhandler/jms/SafranReceiver.java
@@ -17,9 +17,12 @@
 package fr.agrometinfo.seasonhandler.jms;
 
 import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
+import java.util.stream.Collectors;
 
 import javax.jms.Destination;
 import javax.jms.JMSConsumer;
@@ -31,6 +34,7 @@ import javax.jms.MessageListener;
 import org.apache.activemq.artemis.jms.client.ActiveMQMessage;
 
 import fr.agrometinfo.seasonhandler.MainConfiguration;
+import fr.agrometinfo.seasonhandler.dao.AmiSimulationDao;
 import fr.inrae.agroclim.indicators.exception.IndicatorsException;
 import fr.inrae.agroclim.indicators.model.Evaluation;
 import fr.inrae.agroclim.indicators.model.indicator.CompositeIndicator;
@@ -39,9 +43,6 @@ import fr.inrae.agroclim.season.core.dao.ClimaticScenarioDao;
 import fr.inrae.agroclim.season.core.dao.VarietyParameterDao;
 import fr.inrae.agroclim.season.core.model.ClimaticScenario;
 import fr.inrae.agroclim.season.core.simulationproperties.SimulationProperties;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
 import lombok.Setter;
 import lombok.extern.log4j.Log4j2;
 
@@ -61,15 +62,16 @@ public final class SafranReceiver implements MessageListener, Runnable {
     private static final String USERNAME = "agrometinfo";
 
     /**
-     * DAO for {@link ClimaticScenario}.
+     * DAO for table "simulation" in AgroMetInfo database.
      */
     @Setter
-    private ClimaticScenarioDao climaticScenarioDao;
+    private AmiSimulationDao amiSimulationDao;
 
     /**
-     * Consumer of JMS messages.
+     * DAO for {@link ClimaticScenario}.
      */
-    private final JMSConsumer consumer;
+    @Setter
+    private ClimaticScenarioDao climaticScenarioDao;
 
     /**
      * Application configuration.
@@ -77,6 +79,11 @@ public final class SafranReceiver implements MessageListener, Runnable {
     @Setter
     private MainConfiguration config;
 
+    /**
+     * Consumer of JMS messages.
+     */
+    private final JMSConsumer consumer;
+
     /**
      * Last date received from JMS message.
      */
@@ -148,7 +155,7 @@ public final class SafranReceiver implements MessageListener, Runnable {
         final int lastDoy = lastDate.getDayOfYear() + doyOffset;
         LOGGER.trace("nban: {}, lastDoy: {}", nbOfYears, lastDoy);
         LOGGER.traceEntry("Loop on each phase of the evaluation");
-        List<CompositeIndicator> phasesToRemove = new ArrayList<>();
+        final List<CompositeIndicator> phasesToRemove = new ArrayList<>();
         for (final CompositeIndicator phase : evaluation.getPhases()) {
             final String endStage = phase.getName();
             final String startStage = phase.getFirstIndicator().getName();
@@ -172,7 +179,7 @@ public final class SafranReceiver implements MessageListener, Runnable {
                 stage.setValue(lastDoy);
             }
         }
-        var newStages = stages.entrySet().stream() //
+        final var newStages = stages.entrySet().stream() //
                 .map(e -> e.getKey().concat(": ").concat(String.valueOf(e.getValue()))) //
                 .collect(Collectors.joining(", "));
         props.set(SimulationProperties.Property.STAGES, newStages);
@@ -188,6 +195,7 @@ public final class SafranReceiver implements MessageListener, Runnable {
         props.unset(SimulationProperties.Property.PHENOLOGICAL_MODEL);
         final Integer simulationId = launcher.launch(evaluation, props, USERNAME);
         LOGGER.info("Simulation is created: #{}", simulationId);
+        amiSimulationDao.create(lastDate, simulationId);
     }
 
     /**
diff --git a/src/main/java/fr/agrometinfo/seasonhandler/jms/SimulationDoneReceiver.java b/src/main/java/fr/agrometinfo/seasonhandler/jms/SimulationDoneReceiver.java
index 2aa4b83..0d1a28d 100644
--- a/src/main/java/fr/agrometinfo/seasonhandler/jms/SimulationDoneReceiver.java
+++ b/src/main/java/fr/agrometinfo/seasonhandler/jms/SimulationDoneReceiver.java
@@ -1,20 +1,22 @@
 package fr.agrometinfo.seasonhandler.jms;
 
-import fr.agrometinfo.seasonhandler.dao.DailyvalueDao;
-import fr.inrae.agroclim.season.core.dao.SimulationDao;
-import fr.inrae.agroclim.season.core.dao.SimulationResultDao;
-import fr.inrae.agroclim.season.core.model.Simulation;
 import java.util.Objects;
+
 import javax.jms.Destination;
 import javax.jms.JMSConsumer;
 import javax.jms.JMSContext;
 import javax.jms.JMSException;
 import javax.jms.Message;
 import javax.jms.MessageListener;
-import lombok.Setter;
 
 import org.apache.activemq.artemis.jms.client.ActiveMQMessage;
 
+import fr.agrometinfo.seasonhandler.dao.AmiSimulationDao;
+import fr.agrometinfo.seasonhandler.dao.DailyvalueDao;
+import fr.inrae.agroclim.season.core.dao.SimulationDao;
+import fr.inrae.agroclim.season.core.dao.SimulationResultDao;
+import fr.inrae.agroclim.season.core.model.Simulation;
+import lombok.Setter;
 import lombok.extern.log4j.Log4j2;
 
 /**
@@ -26,28 +28,34 @@ import lombok.extern.log4j.Log4j2;
  */
 @Log4j2
 public final class SimulationDoneReceiver implements MessageListener, Runnable {
+    /**
+     * DAO for table "simulation" in AgroMetInfo database.
+     */
+    @Setter
+    private AmiSimulationDao amiSimulationDao;
+
     /**
      * Consumer of JMS messages.
      */
     private final JMSConsumer consumer;
 
     /**
-     * DAO for {@link Simuation}.
+     * DAO for {@code dailyvalue} table.
      */
     @Setter
-    private SimulationDao simulationDao;
+    private DailyvalueDao dailyvalueDao;
 
     /**
-     * DAO for {@link SimuationResult}.
+     * DAO for {@link Simulation}.
      */
     @Setter
-    private SimulationResultDao simulationResultDao;
+    private SimulationDao simulationDao;
 
     /**
-     * DAO for {@code dailyvalue} table.
+     * DAO for {@link SimuationResult}.
      */
     @Setter
-    private DailyvalueDao dailyvalueDao;
+    private SimulationResultDao simulationResultDao;
 
     /**
      * Constructor.
@@ -81,6 +89,7 @@ public final class SimulationDoneReceiver implements MessageListener, Runnable {
                 LOGGER.info("Simulation results in {}.{}", schemaName, tableName);
                 dailyvalueDao.insertFromTable(tableName);
                 msg.acknowledge();
+                amiSimulationDao.setEnded(simulationId);
                 LOGGER.info("Simulation results in {}.{} handled", schemaName, tableName);
             } catch (final JMSException ex) {
                 LOGGER.fatal(ex);
-- 
GitLab