diff --git a/CHANGELOG.md b/CHANGELOG.md index dca0904..9becb42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm # Changelog for org.gcube.application.geoportal-logic +## [v1.0.2] - 2020-11-4 + +PublicationReport +Fix style publication [File not found] +Fix getManagerByID + + ## [v1.0.1] - 2020-11-2 SDI publication exception are now non blocking Automatic centroids layer creation diff --git a/pom.xml b/pom.xml index 424f7f0..90294d0 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 org.gcube.application geoportal-logic - 1.0.1 + 1.0.2 Geoportal Logic diff --git a/src/main/java/org/gcube/application/geoportal/managers/AbstractRecordManager.java b/src/main/java/org/gcube/application/geoportal/managers/AbstractRecordManager.java index a3e66a5..656b288 100644 --- a/src/main/java/org/gcube/application/geoportal/managers/AbstractRecordManager.java +++ b/src/main/java/org/gcube/application/geoportal/managers/AbstractRecordManager.java @@ -14,7 +14,6 @@ import java.util.Properties; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.EntityTransaction; -import javax.persistence.Persistence; import javax.persistence.SharedCacheMode; import javax.persistence.ValidationMode; import javax.persistence.spi.ClassTransformer; @@ -22,8 +21,6 @@ import javax.persistence.spi.PersistenceUnitInfo; import javax.persistence.spi.PersistenceUnitTransactionType; import javax.sql.DataSource; -import org.apache.poi.ss.formula.functions.T; -import org.gcube.application.geoportal.managers.AbstractRecordManager.EMFProvider; import org.gcube.application.geoportal.model.Record; import org.gcube.application.geoportal.model.db.DBConstants; import org.gcube.application.geoportal.model.db.DatabaseConnection; @@ -34,6 +31,7 @@ import org.gcube.application.geoportal.model.fault.PersistenceException; import org.gcube.application.geoportal.model.fault.PublishException; import org.gcube.application.geoportal.model.fault.SDIInteractionException; import org.gcube.application.geoportal.model.fault.ValidationException; +import org.gcube.application.geoportal.model.report.PublicationReport; import org.gcube.application.geoportal.model.report.ValidationReport; import org.gcube.application.geoportal.model.report.ValidationReport.ValidationStatus; import org.gcube.application.geoportal.storage.ContentHandler; @@ -48,18 +46,18 @@ import lombok.Synchronized; import lombok.extern.slf4j.Slf4j; @Slf4j public abstract class AbstractRecordManager { - + public static interface EMFProvider { public EntityManagerFactory getFactory(); } - - - - + + + + public static void setDefaultProvider(EMFProvider provider) { defaultProvider=provider; } - + private static EMFProvider defaultProvider=null; private static EntityManagerFactory emf=null; @@ -101,29 +99,38 @@ public abstract class AbstractRecordManager { return emf; } + @Synchronized public static void shutdown() { - EntityManagerFactory emf=getEMF(); - emf.close(); - + if(emf!=null) { + if(emf.isOpen()) emf.close(); + emf=null; + } } public static Record getByID(long id) { EntityManager em=getEMF().createEntityManager(); try { - return em.find(Record.class, id); + log.debug("Looking for record by ID : "+id); + EntityTransaction tr=em.getTransaction(); + tr.begin(); + Record toReturn=em.find(Record.class, id); + log.debug("Loaded Record "+toReturn); + tr.commit(); + return toReturn; }finally { - em.flush(); + if(em.isJoinedToTransaction()) + em.flush(); em.close(); } } - protected T storeInfo() - { - log.debug("Storing Record "+theRecord); - entityManager.persist(theRecord); - return theRecord; - } +// protected T storeInfo() +// { +// log.debug("Storing Record "+theRecord); +// entityManager.persist(theRecord); +// return theRecord; +// } //Transaction management @@ -134,23 +141,30 @@ public abstract class AbstractRecordManager { private T theRecord; - private ContentHandler contentHandler; + private ContentHandler contentHandler; protected AbstractRecordManager(T theRecord){ entityManager=getEMF().createEntityManager(); transaction=entityManager.getTransaction(); transaction.begin(); this.theRecord=theRecord; - storeInfo(); +// log.debug("Storing Record "+theRecord); + if(theRecord.getId()==0) { + log.debug("Passed record ID = 0. Assuming new .."); + entityManager.persist(theRecord); + }else { + log.debug("Passed record ID = "+theRecord.getId()+". Mergeing.."); + entityManager.merge(theRecord); + } - this.contentHandler=new ContentHandler(theRecord); + this.contentHandler=new ContentHandler(theRecord); } + - - protected ContentHandler getContentHandler() { + protected ContentHandler getContentHandler() { return contentHandler; } @@ -191,6 +205,44 @@ public abstract class AbstractRecordManager { } + public PublicationReport commitSafely(boolean publish) { + log.debug("Safely publishing "+theRecord); + PublicationReport toReturn=new PublicationReport("Publication Report"); + toReturn.setTheRecord(getRecord()); + + + ValidationReport validation=theRecord.validate(); + validation.setObjectName("Validation report for "+validation.getObjectName()); + if(validation.getStatus().equals(ValidationStatus.ERROR)) { + toReturn.addMessage(publish?ValidationStatus.ERROR:ValidationStatus.WARNING, "Record not valid."); + } + toReturn.addChild(validation); + + log.debug("Record is valid, storing changed content [Publish is :"+publish+"]"); + try { + toReturn.addChild(contentHandler.storeChanges(publish)); + + if(publish) { + log.debug("Registering centroid of "+theRecord); + registerCentroid(); + toReturn.addMessage(ValidationStatus.PASSED, "Inserito centroide per record "+theRecord.getId()); + } + + } catch (PersistenceException e) { + toReturn.addChild(e.getReport()); + } catch (PublishException e) { + toReturn.addMessage(ValidationStatus.WARNING, "Centroide non registrato"); + } + try { + log.info("Report is "+toReturn.prettyPrint()); + }catch (Exception e) { + log.warn("Unable to pretty print report "+toReturn,e); + } + return toReturn; + + } + + @Override protected void finalize() throws Throwable { if(transaction.isActive()) { @@ -208,7 +260,7 @@ public abstract class AbstractRecordManager { log.debug("Contacting postgis DB .. "); PostgisDBManagerI db=PostgisDBManager.get(); - + PostgisTable centroidsTable=getCentroidsTable(); log.debug("Inserting / updated centroid Row {} ",centroidRow); @@ -220,18 +272,18 @@ public abstract class AbstractRecordManager { centroidsTable.fillCSVPreparedStatament(centroidRow, ps, false); ps.executeUpdate(); db.commit(); - + initCentroidLayer(); - - + + }catch(SQLException e) { log.warn("Unable to publish Centroid for record "+theRecord,e); -// throw new PublishException("Unable to publish centroid.",e, null); + throw new PublishException("Unable to publish centroid.",e, null); }catch(SDIInteractionException e) { log.warn("Unable to publish Centroid Layer for record type "+getRecord().getRecordType(),e); -// throw new PublishException("Unable to publish centroid.",e, null); + throw new PublishException("Unable to publish centroid.",e, null); } - + } protected abstract PostgisTable getCentroidsTable(); diff --git a/src/main/java/org/gcube/application/geoportal/model/fault/PersistenceException.java b/src/main/java/org/gcube/application/geoportal/model/fault/PersistenceException.java index 5ea5cc0..fa8dead 100644 --- a/src/main/java/org/gcube/application/geoportal/model/fault/PersistenceException.java +++ b/src/main/java/org/gcube/application/geoportal/model/fault/PersistenceException.java @@ -1,30 +1,38 @@ package org.gcube.application.geoportal.model.fault; +import org.gcube.application.geoportal.model.report.PublicationReport; + + public class PersistenceException extends Exception { + + /** + * + */ + private static final long serialVersionUID = -6607258789784961416L; + PublicationReport report; - public PersistenceException() { - // TODO Auto-generated constructor stub + public PersistenceException(PublicationReport report) { + super(); + this.report = report; } - public PersistenceException(String message) { + public PersistenceException(String message, PublicationReport report) { super(message); - // TODO Auto-generated constructor stub + this.report = report; } - public PersistenceException(Throwable cause) { - super(cause); - // TODO Auto-generated constructor stub - } - - public PersistenceException(String message, Throwable cause) { + public PersistenceException(String message, Throwable cause, PublicationReport report) { super(message, cause); - // TODO Auto-generated constructor stub + this.report = report; } - public PersistenceException(String message, Throwable cause, boolean enableSuppression, - boolean writableStackTrace) { + public PersistenceException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, + PublicationReport report) { super(message, cause, enableSuppression, writableStackTrace); - // TODO Auto-generated constructor stub + this.report = report; + } + + public PublicationReport getReport() { + return report; } - } diff --git a/src/main/java/org/gcube/application/geoportal/model/report/PublicationReport.java b/src/main/java/org/gcube/application/geoportal/model/report/PublicationReport.java index 23bb779..e466a12 100644 --- a/src/main/java/org/gcube/application/geoportal/model/report/PublicationReport.java +++ b/src/main/java/org/gcube/application/geoportal/model/report/PublicationReport.java @@ -1,15 +1,37 @@ package org.gcube.application.geoportal.model.report; +import java.io.Serializable; + import org.gcube.application.geoportal.model.Record; +import org.gcube.application.geoportal.utils.Serialization; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; +import com.fasterxml.jackson.core.JsonProcessingException; -@RequiredArgsConstructor -public class PublicationReport { +import lombok.Getter; +import lombok.Setter; - @NonNull - private T theRecord; + +public class PublicationReport extends ValidationReport implements Serializable{ + + /** + * + */ + private static final long serialVersionUID = -1422004928222440165L; + @Getter + @Setter + private Record theRecord; + + public PublicationReport(String objectName) { + super(objectName); + } + @Override + public String prettyPrint() throws JsonProcessingException { + Record app=theRecord; + theRecord=null; + String toReturn=Serialization.prettyPrint(this); + theRecord=app; + return toReturn; + } } diff --git a/src/main/java/org/gcube/application/geoportal/model/report/ValidationReport.java b/src/main/java/org/gcube/application/geoportal/model/report/ValidationReport.java index 3b8b33a..a04d751 100644 --- a/src/main/java/org/gcube/application/geoportal/model/report/ValidationReport.java +++ b/src/main/java/org/gcube/application/geoportal/model/report/ValidationReport.java @@ -4,6 +4,10 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.List; +import org.gcube.application.geoportal.utils.Serialization; + +import com.fasterxml.jackson.core.JsonProcessingException; + import lombok.Data; @Data @@ -70,7 +74,9 @@ public class ValidationReport implements Serializable{ - + public String prettyPrint() throws JsonProcessingException { + return Serialization.prettyPrint(this); + } } diff --git a/src/main/java/org/gcube/application/geoportal/storage/ContentHandler.java b/src/main/java/org/gcube/application/geoportal/storage/ContentHandler.java index c907de5..2558baa 100644 --- a/src/main/java/org/gcube/application/geoportal/storage/ContentHandler.java +++ b/src/main/java/org/gcube/application/geoportal/storage/ContentHandler.java @@ -19,7 +19,9 @@ import org.gcube.application.geoportal.model.content.WorkspaceContent; import org.gcube.application.geoportal.model.fault.PersistenceException; import org.gcube.application.geoportal.model.fault.SDIInteractionException; import org.gcube.application.geoportal.model.gis.SDILayerDescriptor; +import org.gcube.application.geoportal.model.report.PublicationReport; import org.gcube.application.geoportal.model.report.ValidationReport; +import org.gcube.application.geoportal.model.report.ValidationReport.ValidationStatus; import org.gcube.application.geoportal.utils.Files; import org.gcube.common.storagehub.client.dsl.FolderContainer; import org.gcube.common.storagehub.model.exceptions.StorageHubException; @@ -28,7 +30,7 @@ import lombok.extern.slf4j.Slf4j; @Slf4j -public class ContentHandler { +public class ContentHandler { private Map> uploadedResources=new HashMap>(); @@ -36,9 +38,9 @@ public class ContentHandler { private ArrayList toDeleteTemps=new ArrayList(); - private Record record; + private T record; - public ContentHandler(Record record) { + public ContentHandler(T record) { this.record=record; } @@ -71,13 +73,14 @@ public class ContentHandler { } - public void storeChanges(Boolean publish) throws PersistenceException { + public PublicationReport storeChanges(Boolean publish) throws PersistenceException { // + log.debug("Starting to persist "+uploadedResources.size()+" resources "+record.getNome()); + PublicationReport toReturn=new PublicationReport("Storage report"); try { - log.debug("Starting to persist "+uploadedResources.size()+" resources "+record.getNome()); - + WorkspaceManager wsManager=new WorkspaceManager(record); SDIManager sdiManager=null; if(publish) @@ -116,7 +119,9 @@ public class ContentHandler { persisted.add(geoserverPersisted); }catch(SDIInteractionException e) { log.warn("Unable to publish layers.",e); + toReturn.addMessage(ValidationStatus.WARNING, "Layer "+content.getTitolo()+" non pubblicato."); } + toReturn.addMessage(ValidationStatus.PASSED, "Pubblicato layer "+content.getTitolo()); } }else throw new Exception("Invalid SDI Content "+content); @@ -129,20 +134,25 @@ public class ContentHandler { log.debug("Actually Storing files to WS folder "+destination.getId()); + for(TempFile theFile : entry.getValue()) { WorkspaceContent wsContent=wsManager.storeToWS(theFile.getTheFile(), destination, theFile.getOriginalFileName(), description); wsContent.setAssociated(content); persisted.add(wsContent); } - + + toReturn.addMessage(ValidationStatus.PASSED, "Registrati "+entry.getValue().size()+" elementi in archivio per : "+content.getTitolo()); + content.setActualContent(persisted); } - + return toReturn; }catch(StorageHubException e) { + toReturn.addMessage(ValidationStatus.ERROR, "Impossibile archiviare."); log.error("Unexpected SGHUB Exception",e); - throw new PersistenceException("Unexpected Exception",e); + throw new PersistenceException("Unexpected Exception",e,toReturn); }catch(Throwable t) { - throw new PersistenceException("Unexpected Exception",t); + toReturn.addMessage(ValidationStatus.ERROR, "Errore inatteso."); + throw new PersistenceException("Unexpected Exception",t,toReturn); } } diff --git a/src/main/java/org/gcube/application/geoportal/storage/SDIManager.java b/src/main/java/org/gcube/application/geoportal/storage/SDIManager.java index 4bc1acf..abc228b 100644 --- a/src/main/java/org/gcube/application/geoportal/storage/SDIManager.java +++ b/src/main/java/org/gcube/application/geoportal/storage/SDIManager.java @@ -198,7 +198,7 @@ public class SDIManager { //Checking store createStoreFromPostgisDB(workspace, storeName); //Checkig layer - publishLayer(Files.getFileFromResources("/styles/clustered_points.sld"),style); + publishLayer(Files.getFileFromResources("styles/clustered_points.sld"),style); if(!gis.getCurrentGeoServer().getPublisher().publishDBLayer(workspace, storeName, fte, layerEncoder)) log.warn("Unable to create layer "+name+". Assuming already exisintg.."); diff --git a/src/main/java/org/gcube/application/geoportal/utils/Serialization.java b/src/main/java/org/gcube/application/geoportal/utils/Serialization.java index 750e0b7..45f6e6d 100644 --- a/src/main/java/org/gcube/application/geoportal/utils/Serialization.java +++ b/src/main/java/org/gcube/application/geoportal/utils/Serialization.java @@ -6,6 +6,7 @@ import java.util.Collection; import org.gcube.application.geoportal.model.Record; +import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; @@ -29,8 +30,9 @@ static private ObjectMapper prettyMapper; prettyMapper=new ObjectMapper(); prettyMapper.configure(SerializationFeature.INDENT_OUTPUT, true); + prettyMapper.setSerializationInclusion(Include.NON_NULL); prettyMapper.configure(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS, false); - mapper.registerModule(new JavaTimeModule()); + prettyMapper.registerModule(new JavaTimeModule()); } diff --git a/src/test/java/org/gcube/application/geoportal/SerializationTests.java b/src/test/java/org/gcube/application/geoportal/SerializationTests.java index becf0c0..2d50d29 100644 --- a/src/test/java/org/gcube/application/geoportal/SerializationTests.java +++ b/src/test/java/org/gcube/application/geoportal/SerializationTests.java @@ -4,12 +4,14 @@ import java.io.IOException; import org.gcube.application.geoportal.model.Record; import org.gcube.application.geoportal.model.concessioni.Concessione; +import org.gcube.application.geoportal.model.report.PublicationReport; import org.gcube.application.geoportal.utils.Serialization; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonMappingException; public class SerializationTests { @@ -21,6 +23,12 @@ public class SerializationTests { concessione=TestModel.prepareConcessione(); } + @Test + public void prettyPrint() throws JsonProcessingException { + PublicationReport rep=new PublicationReport("my report"); + rep.setTheRecord(concessione); + System.out.println(rep.prettyPrint()); + } @Test public void serilalization() throws JsonParseException, JsonMappingException, IOException { diff --git a/src/test/java/org/gcube/application/geoportal/TestSDI.java b/src/test/java/org/gcube/application/geoportal/TestSDI.java index 044bae2..fee6f01 100644 --- a/src/test/java/org/gcube/application/geoportal/TestSDI.java +++ b/src/test/java/org/gcube/application/geoportal/TestSDI.java @@ -27,7 +27,8 @@ public class TestSDI { SDIManager sdiManager=new SDIManager(); - sdiManager.createWorkspace(workspaceName); +// sdiManager.createWorkspace(workspaceName); + sdiManager.configureCentroidLayer("centroids_concessioni", "gna:test", "gna_test_postgis"); // sdiManager.publishShapeFile(workspaceName, file.getPublicLink()); diff --git a/src/test/java/org/gcube/application/geoportal/UseCases.java b/src/test/java/org/gcube/application/geoportal/UseCases.java index 07488f5..5dc969b 100644 --- a/src/test/java/org/gcube/application/geoportal/UseCases.java +++ b/src/test/java/org/gcube/application/geoportal/UseCases.java @@ -1,6 +1,7 @@ package org.gcube.application.geoportal; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; import org.gcube.application.geoportal.managers.ConcessioneManager; @@ -10,10 +11,7 @@ import org.gcube.application.geoportal.model.concessioni.Concessione; import org.gcube.application.geoportal.model.concessioni.LayerConcessione; import org.gcube.application.geoportal.model.concessioni.RelazioneScavo; import org.gcube.application.geoportal.model.content.UploadedImage; -import org.gcube.application.geoportal.model.content.WorkspaceContent; -import org.gcube.application.geoportal.model.fault.PersistenceException; -import org.gcube.application.geoportal.model.fault.PublishException; -import org.gcube.application.geoportal.model.fault.ValidationException; +import org.gcube.application.geoportal.model.report.PublicationReport; import org.gcube.application.geoportal.model.report.ValidationReport; import org.gcube.application.geoportal.model.report.ValidationReport.ValidationStatus; import org.gcube.application.geoportal.utils.Files; @@ -22,19 +20,29 @@ import org.junit.Assert; public class UseCases { - public static void main(String[] args) throws PersistenceException, IOException, ValidationException, PublishException { -// TokenSetter.set("/gcube/devNext/NextNext"); - TokenSetter.set("/pred4s/preprod/preVRE"); - try{ - registerNewConcessione(); - }catch(ValidationException e) { - System.err.println("Errore di validazione "); - System.err.println(Serialization.prettyPrint(e.getReport())); + public static void main(String[] args) throws FileNotFoundException, IOException { + TokenSetter.set("/gcube/devNext/NextNext"); +// TokenSetter.set("/pred4s/preprod/preVRE"); + + try { +// System.out.println("Try to create.."); +// Concessione conc=registerNewConcessione(); + +// long id=conc.getId(); + + long id=48; + System.out.println("Tryint to read by id "+id); + readConcessione(id); + }catch(Throwable t) { + System.err.println("ALERT "+t.getMessage()); + throw t; } + + } - public static void registerNewConcessione() throws PersistenceException, IOException, ValidationException, PublishException{ + public static Concessione registerNewConcessione() throws FileNotFoundException, IOException{ ConcessioneManager manager=null; try { //Preparo l'istanza del modello con i vari campi compilati e senza gli allegati @@ -85,7 +93,7 @@ public class UseCases { Concessione prepared=manager.getRecord(); System.out.println("Object before validation is "+prepared); ValidationReport report=manager.getRecord().validate(); - System.out.println("Report is : "+Serialization.prettyPrint(report)); + System.out.println("Report is : "+report.prettyPrint()); Assert.assertEquals(report.getStatus(),ValidationStatus.PASSED); System.out.println("Object after validation is "+prepared); @@ -94,17 +102,38 @@ public class UseCases { *scrittura sul WS *pubblicazione sull'SDI (boolean publish) *scrittura sul DB di applicazione sia dei meta che dei vari link */ - Concessione registered=manager.commit(publish); + + //Metodo con eccezioni +// Concessione registered=manager.commit(publish); + //Metodo con report + PublicationReport pubReport=manager.commitSafely(publish); + Concessione registered=(Concessione) pubReport.getTheRecord(); + System.out.println("REGISTERED "+registered); - Assert.assertNotNull(((WorkspaceContent)registered.getRelazioneScavo().getActualContent().get(0)).getLink()); - + System.out.println("Report is "+pubReport.prettyPrint()); + Assert.assertFalse(pubReport.getStatus().equals(ValidationStatus.ERROR)); + + + return registered; //--- FINALLY --/ + }finally{ manager.shutdown(); } } + + public static void readConcessione(long id) { + + ConcessioneManager manager=ManagerFactory.getByRecordID(id); + try{ + System.out.println(manager.getRecord()); + }finally { + manager.shutdown(); + } + + } }