From e14893ab0ce4b7a2c58961443ba9011948ea6f7d Mon Sep 17 00:00:00 2001
From: Tor-Einar Skog <tor-einar.skog@nibio.no>
Date: Tue, 9 Feb 2021 13:43:10 +0100
Subject: [PATCH] Added actual track keeping of updates in the crop category
 and organism tables

---
 nb-configuration.xml                          |   1 +
 .../vips/logic/VIPSLogicApplication.java      |   1 +
 .../controller/session/OrganismBean.java      |  28 ++++
 .../no/nibio/vips/logic/entity/DbUpdate.java  | 134 ++++++++++++++++++
 .../logic/service/ObservationService.java     |  12 +-
 .../db/migration/V8__db_update_catalog.sql    |   9 ++
 6 files changed, 179 insertions(+), 6 deletions(-)
 create mode 100644 src/main/java/no/nibio/vips/logic/entity/DbUpdate.java
 create mode 100644 src/main/resources/db/migration/V8__db_update_catalog.sql

diff --git a/nb-configuration.xml b/nb-configuration.xml
index 77a7b4eb..0a350507 100755
--- a/nb-configuration.xml
+++ b/nb-configuration.xml
@@ -27,4 +27,5 @@ Any value defined here will override the pom.xml file value but is only applicab
         <netbeans.compile.on.save>none</netbeans.compile.on.save>
         <org-netbeans-modules-maven-j2ee.netbeans_2e_hint_2e_deploy_2e_server>WildFly</org-netbeans-modules-maven-j2ee.netbeans_2e_hint_2e_deploy_2e_server>
     </properties>
+    <libraries xmlns="http://www.netbeans.org/ns/cdnjs-libraries/1"/>
 </project-shared-configuration>
diff --git a/src/main/java/no/nibio/vips/logic/VIPSLogicApplication.java b/src/main/java/no/nibio/vips/logic/VIPSLogicApplication.java
index a731423e..59995d75 100755
--- a/src/main/java/no/nibio/vips/logic/VIPSLogicApplication.java
+++ b/src/main/java/no/nibio/vips/logic/VIPSLogicApplication.java
@@ -76,6 +76,7 @@ public class VIPSLogicApplication extends Application
         resources.add(no.nibio.vips.logic.modules.barleynetblotch.BarleyNetBlotchModelService.class);
         resources.add(no.nibio.vips.logic.modules.roughage.RoughageService.class);
         resources.add(no.nibio.vips.logic.modules.wheatleafblotch.WheatLeafBlotchModelService.class);
+        resources.add(no.nibio.vips.logic.service.AuthenticationService.class);
         resources.add(no.nibio.vips.logic.service.GrowthStageService.class);
         resources.add(no.nibio.vips.logic.service.JSONBConfig.class);
         resources.add(no.nibio.vips.logic.service.JacksonConfig.class);
diff --git a/src/main/java/no/nibio/vips/logic/controller/session/OrganismBean.java b/src/main/java/no/nibio/vips/logic/controller/session/OrganismBean.java
index 1eb5d6b2..e6707013 100755
--- a/src/main/java/no/nibio/vips/logic/controller/session/OrganismBean.java
+++ b/src/main/java/no/nibio/vips/logic/controller/session/OrganismBean.java
@@ -20,10 +20,13 @@
 package no.nibio.vips.logic.controller.session;
 
 import com.ibm.icu.util.ULocale;
+
+import java.time.Instant;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -36,6 +39,7 @@ import javax.persistence.PersistenceContext;
 import javax.persistence.Query;
 import no.nibio.vips.logic.entity.CropCategory;
 import no.nibio.vips.logic.entity.CropPest;
+import no.nibio.vips.logic.entity.DbUpdate;
 import no.nibio.vips.logic.entity.ExternalResource;
 import no.nibio.vips.logic.entity.ExternalResourceType;
 import no.nibio.vips.logic.entity.HierarchyCategory;
@@ -164,6 +168,7 @@ public class OrganismBean {
             //SessionControllerGetter.getOrganismBean().removeOrganismLocalName(organism, currentLocale);
             this.removeOrganismLocalName(organism, currentLocale);
         }
+        this.notifyUpdateOfOrganisms();
         return organism;
     }
 
@@ -193,6 +198,7 @@ public class OrganismBean {
         {
             Organism organism = em.find(Organism.class, organismId);
             em.remove(organism);
+            this.notifyUpdateOfOrganisms();
             return true;
         }
         else
@@ -399,6 +405,7 @@ public class OrganismBean {
     
     public CropPest storeCropPest(CropPest cropPest)
     {
+    	this.notifyUpdateOfOrganisms();
         return em.merge(cropPest);
     }
 
@@ -480,6 +487,8 @@ public class OrganismBean {
                 cropCategory.removeCropOrganismId(organism.getOrganismId());
             }
         }
+        
+        this.notifyUpdateOfOrganisms();
     }
 
     public CropCategory getCropCategory(Integer cropCategoryId) {
@@ -488,6 +497,7 @@ public class OrganismBean {
 
     public void storeCropCategory(CropCategory cropCategory) {
         em.merge(cropCategory);
+        this.notifyUpdateOfOrganisms();
     }
 
     public List<Organism> findOrganismsByLatinNames(List<String> latinNames) {
@@ -500,4 +510,22 @@ public class OrganismBean {
                 .setParameter("locale", locale)
                 .getResultList();
     }
+    
+    /**
+     * The purpose of this was originally to give information to e.g. the VIPS Observation App
+     * that a synchronization is required
+     */
+    public void notifyUpdateOfOrganisms() {
+    	DbUpdate cropCategoriesAndOrganisms = em.find(DbUpdate.class, DbUpdate.CROP_CATEGORIES_AND_ORGANISMS);
+    	cropCategoriesAndOrganisms.setLastUpdate(new Date());
+    }
+    
+    /**
+     * The purpose of this was originally to give information to e.g. the VIPS Observation App
+     * that a synchronization is required
+     */
+    public Instant getLatestUpdateOfOrganisms() {
+    	DbUpdate cropCategoriesAndOrganisms = em.find(DbUpdate.class, DbUpdate.CROP_CATEGORIES_AND_ORGANISMS);
+    	return cropCategoriesAndOrganisms.getLastUpdate() != null ? cropCategoriesAndOrganisms.getLastUpdate().toInstant() : null;
+    }
 }
diff --git a/src/main/java/no/nibio/vips/logic/entity/DbUpdate.java b/src/main/java/no/nibio/vips/logic/entity/DbUpdate.java
new file mode 100644
index 00000000..d0c10cce
--- /dev/null
+++ b/src/main/java/no/nibio/vips/logic/entity/DbUpdate.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2021 NIBIO <http://www.nibio.no/>. 
+ * 
+ * This file is part of VIPSLogic.
+ * VIPSLogic is free software: you can redistribute it and/or modify
+ * it under the terms of the NIBIO Open Source License as published by 
+ * NIBIO, either version 1 of the License, or (at your option) any
+ * later version.
+ * 
+ * VIPSLogic is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * NIBIO Open Source License for more details.
+ * 
+ * You should have received a copy of the NIBIO Open Source License
+ * along with VIPSLogic.  If not, see <http://www.nibio.no/licenses/>.
+ * 
+ */
+
+package no.nibio.vips.logic.entity;
+
+import java.io.Serializable;
+import java.util.Date;
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * @copyright 2021 <a href="http://www.nibio.no/">NIBIO</a>
+ * @author Tor-Einar Skog <tor-einar.skog@nibio.no>
+ */
+@Entity
+@Table(name = "db_update")
+@XmlRootElement
+@NamedQueries({
+    @NamedQuery(name = "DbUpdate.findAll", query = "SELECT d FROM DbUpdate d"),
+    @NamedQuery(name = "DbUpdate.findByDbUpdateId", query = "SELECT d FROM DbUpdate d WHERE d.dbUpdateId = :dbUpdateId"),
+    @NamedQuery(name = "DbUpdate.findByTitle", query = "SELECT d FROM DbUpdate d WHERE d.title = :title"),
+    @NamedQuery(name = "DbUpdate.findByDescription", query = "SELECT d FROM DbUpdate d WHERE d.description = :description"),
+    @NamedQuery(name = "DbUpdate.findByLastUpdate", query = "SELECT d FROM DbUpdate d WHERE d.lastUpdate = :lastUpdate")})
+public class DbUpdate implements Serializable {
+	
+	public final static int CROP_CATEGORIES_AND_ORGANISMS = 1;
+
+    private static final long serialVersionUID = 1L;
+    @Id
+    @Basic(optional = false)
+    @NotNull
+    @Column(name = "db_update_id")
+    private Integer dbUpdateId;
+    @Size(max = 255)
+    @Column(name = "title")
+    private String title;
+    @Size(max = 2147483647)
+    @Column(name = "description")
+    private String description;
+    @Column(name = "last_update")
+    @Temporal(TemporalType.TIMESTAMP)
+    private Date lastUpdate;
+
+    public DbUpdate() {
+    }
+
+    public DbUpdate(Integer dbUpdateId) {
+        this.dbUpdateId = dbUpdateId;
+    }
+
+    public Integer getDbUpdateId() {
+        return dbUpdateId;
+    }
+
+    public void setDbUpdateId(Integer dbUpdateId) {
+        this.dbUpdateId = dbUpdateId;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public Date getLastUpdate() {
+        return lastUpdate;
+    }
+
+    public void setLastUpdate(Date lastUpdate) {
+        this.lastUpdate = lastUpdate;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 0;
+        hash += (dbUpdateId != null ? dbUpdateId.hashCode() : 0);
+        return hash;
+    }
+
+    @Override
+    public boolean equals(Object object) {
+        // TODO: Warning - this method won't work in the case the id fields are not set
+        if (!(object instanceof DbUpdate)) {
+            return false;
+        }
+        DbUpdate other = (DbUpdate) object;
+        if ((this.dbUpdateId == null && other.dbUpdateId != null) || (this.dbUpdateId != null && !this.dbUpdateId.equals(other.dbUpdateId))) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return "no.nibio.vips.logic.entity.DbUpdate[ dbUpdateId=" + dbUpdateId + " ]";
+    }
+
+}
diff --git a/src/main/java/no/nibio/vips/logic/service/ObservationService.java b/src/main/java/no/nibio/vips/logic/service/ObservationService.java
index 5acd2eee..11a6db46 100755
--- a/src/main/java/no/nibio/vips/logic/service/ObservationService.java
+++ b/src/main/java/no/nibio/vips/logic/service/ObservationService.java
@@ -26,6 +26,8 @@ import java.io.IOException;
 import java.net.URI;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
+import java.time.Instant;
+import java.time.ZoneOffset;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.HashMap;
@@ -451,18 +453,16 @@ public class ObservationService {
     /**
      * When was the last time a change was made in cropCategories or organisms?
      * 
-     * @responseExample application/json {"lastUpdated": "2021-02-08"}
+     * @responseExample application/json {"lastUpdated": "2021-02-08T00:00:00Z"}
      */
     @GET
     @Path("organismsystemupdated")
     @Produces(MediaType.APPLICATION_JSON)
-    
     public Response getDateOfLastOrganismSystemUpdate()
     {
-    	ObjectMapper objectMapper = new ObjectMapper();
-    	ObjectNode result = objectMapper.createObjectNode();
-    	LocalDate lastUpdated = LocalDate.now();
-    	result.put("lastUpdated", lastUpdated.toString());
+    	HashMap<String, Object> result = new HashMap<>();
+    	Instant lastUpdated = SessionControllerGetter.getOrganismBean().getLatestUpdateOfOrganisms();
+    	result.put("lastUpdated", lastUpdated != null ? lastUpdated: "1970-01-01T00:00:00Z");
     	return Response.ok().entity(result).build();
     }
     
diff --git a/src/main/resources/db/migration/V8__db_update_catalog.sql b/src/main/resources/db/migration/V8__db_update_catalog.sql
new file mode 100644
index 00000000..aa28929a
--- /dev/null
+++ b/src/main/resources/db/migration/V8__db_update_catalog.sql
@@ -0,0 +1,9 @@
+CREATE TABLE public.db_update (
+	db_update_id INTEGER PRIMARY KEY,
+	title VARCHAR(255),
+	description TEXT,
+	last_update TIMESTAMP WITH TIME ZONE
+);
+
+INSERT INTO public.db_update(db_update_id, title, description, last_update)
+VALUES(1, 'Crop categories and organisms', 'Changes have occurred in the crop categories and organisms subsystem', NULL);
\ No newline at end of file
-- 
GitLab