diff --git a/CHANGELOG.md b/CHANGELOG.md index a08b31e..8cfa5f7 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.spatial.data.gcube-sdi-suite +## [v1.0.2] - 2021-02-24 +-Introduced module sdi-plugins +-Introduced module notifications-plugins +-Introduced module dataminer-plugins +-Introduced module images-plugins +-Introduced module ckan-plugin + ## [v1.0.1] - 2021-12-07 - Introduced cms-plugin-framework - Introduced concessioni use case diff --git a/README.md b/README.md index 85dd719..1723644 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,27 @@ gCube CMS Suite -------------------------------------------------- -gCube CMS Suite is a set of components designed to manage complex space-temporal Documents defined by metadata Profiles. +gCube CMS Suite is a distributed full stack application for publication management in a gCube Hybrid e-infrastructure. Check wiki [here](https://sublime-and-sphinx-guide.readthedocs.io) + +[](https://www.sphinx-doc.org/en/master/) + + +Rationale : + +Publication involves lots of common features as well as custom behaviour and formats. The service implements the basic common logic, delegating to installed plugin both cutom and configurable functions ranging from validation, data manifestazion, indexing and lifecycle management. +Lifecycle management is itself an extension allowing for both common and complex ad-hoc workflows. +High modularity of plugins allows for the composition of ad hoc use cases with maximized re-usability. + +The suite comes with a set of pre-built plugins and GUIs that communities can easily extend and / or reuse. + + +## Documentation +* [Dedicated Wiki](https://sublime-and-sphinx-guide.readthedocs.io) - TBD Powered by [Sphynx](https://www.sphinx-doc.org/en/master/) +* [Service Interactive API]() -TBD Powered by [Enunciate](http://enunciate.webcohesion.com/) +* [Gcube System Wiki](https://gcube.wiki.gcube-system.org/gcube/GeoPortal). +* [Guide Notebooks](use-cases) - Powered by [Jupyter](https://jupyter.org/) +* [Service Wiki src](use-cases/src/site/suite.rst) + ## Built with * [gCube SmartGears] (https://gcube.wiki.gcube-system.org/gcube/SmartGears) - The gCube SmartGears framework @@ -9,10 +29,8 @@ gCube CMS Suite is a set of components designed to manage complex space-temporal * [JAX-RS](https://github.com/eclipse-ee4j/jaxrs-api) - Java™ API for RESTful Web Services * [Jersey](https://jersey.github.io/) - JAX-RS runtime * [Maven](https://maven.apache.org/) - Dependency Management +* [Enunciate] (http://enunciate.webcohesion.com/) - API Documentation -## Documentation - -Documentation can be found [here](https://gcube.wiki.gcube-system.org/gcube/GeoPortal_Service). ## Change log diff --git a/ckan-plugin/CHANGELOG.md b/ckan-plugin/CHANGELOG.md new file mode 100644 index 0000000..a15bf25 --- /dev/null +++ b/ckan-plugin/CHANGELOG.md @@ -0,0 +1,8 @@ +This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +# Changelog for org.gcube.application.cms.ckan-plugin + +This library contains gcube-cms plugins for ckan materializations + +## [v1.0.0] - 2022-02-24 +- First release diff --git a/ckan-plugin/FUNDING.md b/ckan-plugin/FUNDING.md new file mode 100644 index 0000000..9e48b94 --- /dev/null +++ b/ckan-plugin/FUNDING.md @@ -0,0 +1,26 @@ +# Acknowledgments + +The projects leading to this software have received funding from a series of European Union programmes including: + +- the Sixth Framework Programme for Research and Technological Development + - [DILIGENT](https://cordis.europa.eu/project/id/004260) (grant no. 004260). +- the Seventh Framework Programme for research, technological development and demonstration + - [D4Science](https://cordis.europa.eu/project/id/212488) (grant no. 212488); + - [D4Science-II](https://cordis.europa.eu/project/id/239019) (grant no.239019); + - [ENVRI](https://cordis.europa.eu/project/id/283465) (grant no. 283465); + - [iMarine](https://cordis.europa.eu/project/id/283644) (grant no. 283644); + - [EUBrazilOpenBio](https://cordis.europa.eu/project/id/288754) (grant no. 288754). +- the H2020 research and innovation programme + - [SoBigData](https://cordis.europa.eu/project/id/654024) (grant no. 654024); + - [PARTHENOS](https://cordis.europa.eu/project/id/654119) (grant no. 654119); + - [EGI-Engage](https://cordis.europa.eu/project/id/654142) (grant no. 654142); + - [ENVRI PLUS](https://cordis.europa.eu/project/id/654182) (grant no. 654182); + - [BlueBRIDGE](https://cordis.europa.eu/project/id/675680) (grant no. 675680); + - [PerformFISH](https://cordis.europa.eu/project/id/727610) (grant no. 727610); + - [AGINFRA PLUS](https://cordis.europa.eu/project/id/731001) (grant no. 731001); + - [DESIRA](https://cordis.europa.eu/project/id/818194) (grant no. 818194); + - [ARIADNEplus](https://cordis.europa.eu/project/id/823914) (grant no. 823914); + - [RISIS 2](https://cordis.europa.eu/project/id/824091) (grant no. 824091); + - [EOSC-Pillar](https://cordis.europa.eu/project/id/857650) (grant no. 857650); + - [Blue Cloud](https://cordis.europa.eu/project/id/862409) (grant no. 862409); + - [SoBigData-PlusPlus](https://cordis.europa.eu/project/id/871042) (grant no. 871042); diff --git a/ckan-plugin/LICENSE.md b/ckan-plugin/LICENSE.md new file mode 100644 index 0000000..3af0507 --- /dev/null +++ b/ckan-plugin/LICENSE.md @@ -0,0 +1,312 @@ +# European Union Public Licence V. 1.1 + + +EUPL © the European Community 2007 + + +This European Union Public Licence (the “EUPL”) applies to the Work or Software +(as defined below) which is provided under the terms of this Licence. Any use of +the Work, other than as authorised under this Licence is prohibited (to the +extent such use is covered by a right of the copyright holder of the Work). + +The Original Work is provided under the terms of this Licence when the Licensor +(as defined below) has placed the following notice immediately following the +copyright notice for the Original Work: + +Licensed under the EUPL V.1.1 + +or has expressed by any other mean his willingness to license under the EUPL. + + + +## 1. Definitions + +In this Licence, the following terms have the following meaning: + +- The Licence: this Licence. + +- The Original Work or the Software: the software distributed and/or + communicated by the Licensor under this Licence, available as Source Code and + also as Executable Code as the case may be. + +- Derivative Works: the works or software that could be created by the Licensee, + based upon the Original Work or modifications thereof. This Licence does not + define the extent of modification or dependence on the Original Work required + in order to classify a work as a Derivative Work; this extent is determined by + copyright law applicable in the country mentioned in Article 15. + +- The Work: the Original Work and/or its Derivative Works. + +- The Source Code: the human-readable form of the Work which is the most + convenient for people to study and modify. + +- The Executable Code: any code which has generally been compiled and which is + meant to be interpreted by a computer as a program. + +- The Licensor: the natural or legal person that distributes and/or communicates + the Work under the Licence. + +- Contributor(s): any natural or legal person who modifies the Work under the + Licence, or otherwise contributes to the creation of a Derivative Work. + +- The Licensee or “You”: any natural or legal person who makes any usage of the + Software under the terms of the Licence. + +- Distribution and/or Communication: any act of selling, giving, lending, + renting, distributing, communicating, transmitting, or otherwise making + available, on-line or off-line, copies of the Work or providing access to its + essential functionalities at the disposal of any other natural or legal + person. + + + +## 2. Scope of the rights granted by the Licence + +The Licensor hereby grants You a world-wide, royalty-free, non-exclusive, +sub-licensable licence to do the following, for the duration of copyright vested +in the Original Work: + +- use the Work in any circumstance and for all usage, reproduce the Work, modify +- the Original Work, and make Derivative Works based upon the Work, communicate +- to the public, including the right to make available or display the Work or +- copies thereof to the public and perform publicly, as the case may be, the +- Work, distribute the Work or copies thereof, lend and rent the Work or copies +- thereof, sub-license rights in the Work or copies thereof. + +Those rights can be exercised on any media, supports and formats, whether now +known or later invented, as far as the applicable law permits so. + +In the countries where moral rights apply, the Licensor waives his right to +exercise his moral right to the extent allowed by law in order to make effective +the licence of the economic rights here above listed. + +The Licensor grants to the Licensee royalty-free, non exclusive usage rights to +any patents held by the Licensor, to the extent necessary to make use of the +rights granted on the Work under this Licence. + + + +## 3. Communication of the Source Code + +The Licensor may provide the Work either in its Source Code form, or as +Executable Code. If the Work is provided as Executable Code, the Licensor +provides in addition a machine-readable copy of the Source Code of the Work +along with each copy of the Work that the Licensor distributes or indicates, in +a notice following the copyright notice attached to the Work, a repository where +the Source Code is easily and freely accessible for as long as the Licensor +continues to distribute and/or communicate the Work. + + + +## 4. Limitations on copyright + +Nothing in this Licence is intended to deprive the Licensee of the benefits from +any exception or limitation to the exclusive rights of the rights owners in the +Original Work or Software, of the exhaustion of those rights or of other +applicable limitations thereto. + + + +## 5. Obligations of the Licensee + +The grant of the rights mentioned above is subject to some restrictions and +obligations imposed on the Licensee. Those obligations are the following: + +Attribution right: the Licensee shall keep intact all copyright, patent or +trademarks notices and all notices that refer to the Licence and to the +disclaimer of warranties. The Licensee must include a copy of such notices and a +copy of the Licence with every copy of the Work he/she distributes and/or +communicates. The Licensee must cause any Derivative Work to carry prominent +notices stating that the Work has been modified and the date of modification. + +Copyleft clause: If the Licensee distributes and/or communicates copies of the +Original Works or Derivative Works based upon the Original Work, this +Distribution and/or Communication will be done under the terms of this Licence +or of a later version of this Licence unless the Original Work is expressly +distributed only under this version of the Licence. The Licensee (becoming +Licensor) cannot offer or impose any additional terms or conditions on the Work +or Derivative Work that alter or restrict the terms of the Licence. + +Compatibility clause: If the Licensee Distributes and/or Communicates Derivative +Works or copies thereof based upon both the Original Work and another work +licensed under a Compatible Licence, this Distribution and/or Communication can +be done under the terms of this Compatible Licence. For the sake of this clause, +“Compatible Licence” refers to the licences listed in the appendix attached to +this Licence. Should the Licensee’s obligations under the Compatible Licence +conflict with his/her obligations under this Licence, the obligations of the +Compatible Licence shall prevail. + +Provision of Source Code: When distributing and/or communicating copies of the +Work, the Licensee will provide a machine-readable copy of the Source Code or +indicate a repository where this Source will be easily and freely available for +as long as the Licensee continues to distribute and/or communicate the Work. + +Legal Protection: This Licence does not grant permission to use the trade names, +trademarks, service marks, or names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the copyright notice. + + + +## 6. Chain of Authorship + +The original Licensor warrants that the copyright in the Original Work granted +hereunder is owned by him/her or licensed to him/her and that he/she has the +power and authority to grant the Licence. + +Each Contributor warrants that the copyright in the modifications he/she brings +to the Work are owned by him/her or licensed to him/her and that he/she has the +power and authority to grant the Licence. + +Each time You accept the Licence, the original Licensor and subsequent +Contributors grant You a licence to their contributions to the Work, under the +terms of this Licence. + + + +## 7. Disclaimer of Warranty + +The Work is a work in progress, which is continuously improved by numerous +contributors. It is not a finished work and may therefore contain defects or +“bugs” inherent to this type of software development. + +For the above reason, the Work is provided under the Licence on an “as is” basis +and without warranties of any kind concerning the Work, including without +limitation merchantability, fitness for a particular purpose, absence of defects +or errors, accuracy, non-infringement of intellectual property rights other than +copyright as stated in Article 6 of this Licence. + +This disclaimer of warranty is an essential part of the Licence and a condition +for the grant of any rights to the Work. + + + +## 8. Disclaimer of Liability + +Except in the cases of wilful misconduct or damages directly caused to natural +persons, the Licensor will in no event be liable for any direct or indirect, +material or moral, damages of any kind, arising out of the Licence or of the use +of the Work, including without limitation, damages for loss of goodwill, work +stoppage, computer failure or malfunction, loss of data or any commercial +damage, even if the Licensor has been advised of the possibility of such +damage. However, the Licensor will be liable under statutory product liability +laws as far such laws apply to the Work. + + + +## 9. Additional agreements + +While distributing the Original Work or Derivative Works, You may choose to +conclude an additional agreement to offer, and charge a fee for, acceptance of +support, warranty, indemnity, or other liability obligations and/or services +consistent with this Licence. However, in accepting such obligations, You may +act only on your own behalf and on your sole responsibility, not on behalf of +the original Licensor or any other Contributor, and only if You agree to +indemnify, defend, and hold each Contributor harmless for any liability incurred +by, or claims asserted against such Contributor by the fact You have accepted +any such warranty or additional liability. + + + +## 10. Acceptance of the Licence + +The provisions of this Licence can be accepted by clicking on an icon “I agree” +placed under the bottom of a window displaying the text of this Licence or by +affirming consent in any other similar way, in accordance with the rules of +applicable law. Clicking on that icon indicates your clear and irrevocable +acceptance of this Licence and all of its terms and conditions. + +Similarly, you irrevocably accept this Licence and all of its terms and +conditions by exercising any rights granted to You by Article 2 of this Licence, +such as the use of the Work, the creation by You of a Derivative Work or the +Distribution and/or Communication by You of the Work or copies thereof. + + + +## 11. Information to the public + +In case of any Distribution and/or Communication of the Work by means of +electronic communication by You (for example, by offering to download the Work +from a remote location) the distribution channel or media (for example, a +website) must at least provide to the public the information requested by the +applicable law regarding the Licensor, the Licence and the way it may be +accessible, concluded, stored and reproduced by the Licensee. + + + +## 12. Termination of the Licence + +The Licence and the rights granted hereunder will terminate automatically upon +any breach by the Licensee of the terms of the Licence. + +Such a termination will not terminate the licences of any person who has +received the Work from the Licensee under the Licence, provided such persons +remain in full compliance with the Licence. + + + +## 13. Miscellaneous + +Without prejudice of Article 9 above, the Licence represents the complete +agreement between the Parties as to the Work licensed hereunder. + +If any provision of the Licence is invalid or unenforceable under applicable +law, this will not affect the validity or enforceability of the Licence as a +whole. Such provision will be construed and/or reformed so as necessary to make +it valid and enforceable. + +The European Commission may publish other linguistic versions and/or new +versions of this Licence, so far this is required and reasonable, without +reducing the scope of the rights granted by the Licence. New versions of the +Licence will be published with a unique version number. + +All linguistic versions of this Licence, approved by the European Commission, +have identical value. Parties can take advantage of the linguistic version of +their choice. + + + +## 14. Jurisdiction + +Any litigation resulting from the interpretation of this License, arising +between the European Commission, as a Licensor, and any Licensee, will be +subject to the jurisdiction of the Court of Justice of the European Communities, +as laid down in article 238 of the Treaty establishing the European Community. + +Any litigation arising between Parties, other than the European Commission, and +resulting from the interpretation of this License, will be subject to the +exclusive jurisdiction of the competent court where the Licensor resides or +conducts its primary business. + + + +## 15. Applicable Law + +This Licence shall be governed by the law of the European Union country where +the Licensor resides or has his registered office. + +This licence shall be governed by the Belgian law if: + +- a litigation arises between the European Commission, as a Licensor, and any +- Licensee; the Licensor, other than the European Commission, has no residence +- or registered office inside a European Union country. + + + +## Appendix + + + +“Compatible Licences” according to article 5 EUPL are: + + +- GNU General Public License (GNU GPL) v. 2 + +- Open Software License (OSL) v. 2.1, v. 3.0 + +- Common Public License v. 1.0 + +- Eclipse Public License v. 1.0 + +- Cecill v. 2.0 + diff --git a/ckan-plugin/README.md b/ckan-plugin/README.md new file mode 100644 index 0000000..85dd719 --- /dev/null +++ b/ckan-plugin/README.md @@ -0,0 +1,52 @@ +gCube CMS Suite +-------------------------------------------------- + +gCube CMS Suite is a set of components designed to manage complex space-temporal Documents defined by metadata Profiles. + +## Built with +* [gCube SmartGears] (https://gcube.wiki.gcube-system.org/gcube/SmartGears) - The gCube SmartGears framework +* [OpenJDK](https://openjdk.java.net/) - The JDK used +* [JAX-RS](https://github.com/eclipse-ee4j/jaxrs-api) - Java™ API for RESTful Web Services +* [Jersey](https://jersey.github.io/) - JAX-RS runtime +* [Maven](https://maven.apache.org/) - Dependency Management + +## Documentation + +Documentation can be found [here](https://gcube.wiki.gcube-system.org/gcube/GeoPortal_Service). + +## Change log + +See [CHANGELOG.md](CHANGELOG.md). + +## License + +This project is licensed under the EUPL V.1.1 License - see the [LICENSE.md](LICENSE.md) file for details. + +## About the gCube Framework +This software is part of the [gCubeFramework](https://www.gcube-system.org/ "gCubeFramework"): an +open-source software toolkit used for building and operating Hybrid Data +Infrastructures enabling the dynamic deployment of Virtual Research Environments +by favouring the realisation of reuse oriented policies. + +The projects leading to this software have received funding from a series of European Union programmes including: + +- the Sixth Framework Programme for Research and Technological Development + - DILIGENT (grant no. 004260). +- the Seventh Framework Programme for research, technological development and demonstration + - D4Science (grant no. 212488); + - D4Science-II (grant no.239019); + - ENVRI (grant no. 283465); + - iMarine(grant no. 283644); + - EUBrazilOpenBio (grant no. 288754). +- the H2020 research and innovation programme + - SoBigData (grant no. 654024); + - PARTHENOS (grant no. 654119); + - EGIEngage (grant no. 654142); + - ENVRIplus (grant no. 654182); + - BlueBRIDGE (grant no. 675680); + - PerformFish (grant no. 727610); + - AGINFRAplus (grant no. 731001); + - DESIRA (grant no. 818194); + - ARIADNEplus (grant no. 823914); + - RISIS2 (grant no. 824091); + diff --git a/ckan-plugin/pom.xml b/ckan-plugin/pom.xml new file mode 100644 index 0000000..dce9b2a --- /dev/null +++ b/ckan-plugin/pom.xml @@ -0,0 +1,85 @@ + + + 4.0.0 + + ckan-plugins + 1.0.0 + gCube CMS - CKAN Plugins + + + + org.gcube.application.cms + gcube-cms-suite + 1.0.2 + + + + https://code-repo.d4science.org/gCubeSystem + + + + + + scm:git:${gitBaseUrl}/gcube-cms-suite + scm:git:${gitBaseUrl}/gcube-cms-suite + ${gitBaseUrl}/gcube-cms-suite + + + + + + org.gcube.distribution + gcube-smartgears-bom + ${gcube-smartgears-bom-version} + pom + import + + + org.gcube.application.cms + cms-plugin-framework + ${plugin-framework-version} + pom + import + + + + + + + + org.gcube.application.cms + cms-plugin-framework + + + + org.gcube.application.cms + cms-test-commons + test + + + + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + make-uberjar + package + + + make-servicearchive + package + + + + + + + diff --git a/ckan-plugin/src/main/java/CkanPlugin.java b/ckan-plugin/src/main/java/CkanPlugin.java new file mode 100644 index 0000000..4c8c029 --- /dev/null +++ b/ckan-plugin/src/main/java/CkanPlugin.java @@ -0,0 +1,2 @@ +public class CkanPlugin { +} diff --git a/cms-plugin-framework/CHANGELOG.md b/cms-plugin-framework/CHANGELOG.md index 7e9289e..09183da 100644 --- a/cms-plugin-framework/CHANGELOG.md +++ b/cms-plugin-framework/CHANGELOG.md @@ -2,5 +2,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm # Changelog for org.gcube.application.cms-plugin-framework +## [v1.0.1] 2022-01-17 +- Serialization Features + ## [v1.0.0] 2021-09-20 - First release \ No newline at end of file diff --git a/cms-plugin-framework/pom.xml b/cms-plugin-framework/pom.xml index 99f0dd0..03e6f12 100644 --- a/cms-plugin-framework/pom.xml +++ b/cms-plugin-framework/pom.xml @@ -4,19 +4,18 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 cms-plugin-framework - 1.0.0 + 1.0.1 org.gcube.application.cms gcube-cms-suite - 1.0.1 + 1.0.2 https://code-repo.d4science.org/gCubeSystem 1.0 - @@ -28,16 +27,92 @@ + + + + org.gcube.distribution + gcube-smartgears-bom + ${gcube-smartgears-bom-version} + pom + import + + + + + + + + net.postgis + postgis-jdbc + 2.5.0 + + + + + org.gcube.spatial.data + gis-interface + [2.4.6,3.0.0-SNAPSHOT) + + + + + + org.gcube.data.transfer + data-transfer-library + [1.2.1,2.0.0-SNAPSHOT) + + + + + + org.gcube.application.cms geoportal-common + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + + + + + org.gcube.common + storagehub-client-library + + + + + + de.grundid.opendatalab + geojson-jackson + 1.14 + + + + + org.slf4j + slf4j-api + + org.projectlombok lombok + + + org.reflections + reflections + + + + javax.xml.bind + jaxb-api + + + \ No newline at end of file diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/caches/AbstractScopedMap.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/caches/AbstractScopedMap.java new file mode 100644 index 0000000..1a1a8cd --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/caches/AbstractScopedMap.java @@ -0,0 +1,40 @@ +package org.gcube.application.cms.caches; + +import lombok.NonNull; +import lombok.extern.slf4j.Slf4j; +import org.gcube.application.geoportal.common.model.rest.ConfigurationException; +import org.gcube.application.geoportal.common.utils.ContextUtils; + +@Slf4j +/** + * TTL Map Context -> T + * + */ +public abstract class AbstractScopedMap extends TimedMap implements Engine{ + + public AbstractScopedMap(@NonNull String name) { + super(name); + } + + @Override + public T getObject() throws ConfigurationException { + return get(ContextUtils.getCurrentScope()); + } + + + @Override + public void init() {} + + @Override + public void shutdown() { + log.warn(name + ": shutting down"); + scopeMap.forEach((String s,TTLObject o)->{ + try{if(o!=null&&o.getTheObject()!=null) + dispose(o.getTheObject()); + }catch(Throwable t) { + log.warn(name +": unable to dispose ",t); + } + }); + } + +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/caches/Cache.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/caches/Cache.java new file mode 100644 index 0000000..2da1918 --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/caches/Cache.java @@ -0,0 +1,8 @@ +package org.gcube.application.cms.caches; + +import org.gcube.application.geoportal.common.model.rest.ConfigurationException; + +public interface Cache{ + + public V get(K key) throws ConfigurationException; +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/caches/Engine.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/caches/Engine.java new file mode 100644 index 0000000..d31f1e9 --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/caches/Engine.java @@ -0,0 +1,12 @@ +package org.gcube.application.cms.caches; + +import org.gcube.application.geoportal.common.model.rest.ConfigurationException; + + +public interface Engine { + + public void init(); + public void shutdown(); + + public T getObject() throws ConfigurationException; +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/caches/ObjectManager.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/caches/ObjectManager.java new file mode 100644 index 0000000..8beb55a --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/caches/ObjectManager.java @@ -0,0 +1,8 @@ +package org.gcube.application.cms.caches; + +import org.gcube.application.geoportal.common.model.rest.ConfigurationException; + +public interface ObjectManager{ + + public T insert(T object) throws ConfigurationException; +} diff --git a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/providers/TTLObject.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/caches/TTLObject.java similarity index 78% rename from geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/providers/TTLObject.java rename to cms-plugin-framework/src/main/java/org/gcube/application/cms/caches/TTLObject.java index db226d5..a8f2105 100644 --- a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/providers/TTLObject.java +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/caches/TTLObject.java @@ -1,4 +1,4 @@ -package org.gcube.application.geoportal.service.engine.providers; +package org.gcube.application.cms.caches; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/caches/TimedMap.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/caches/TimedMap.java new file mode 100644 index 0000000..fdc0e66 --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/caches/TimedMap.java @@ -0,0 +1,55 @@ +package org.gcube.application.cms.caches; + +import lombok.Getter; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.gcube.application.geoportal.common.model.rest.ConfigurationException; + +import java.time.LocalDateTime; +import java.time.temporal.TemporalAmount; +import java.util.concurrent.ConcurrentHashMap; + +@Slf4j +@RequiredArgsConstructor +public abstract class TimedMap implements Cache { + + protected ConcurrentHashMap> scopeMap=new ConcurrentHashMap>(); + + @Setter + @Getter + protected TemporalAmount TTL=null; + + @NonNull + protected String name; + + @Override + public V get(K key) throws ConfigurationException { + log.trace(name+" : obtaining object by "+key); + + TTLObject found=scopeMap.get(key); + + if(found== null){ + log.debug(name+" : init object for key "+key); + TTLObject toPut=new TTLObject(LocalDateTime.now(),retrieveObject(key)); + scopeMap.put(key, toPut); + return toPut.getTheObject(); + } + + if(getTTL()!=null) { + if(found.getCreationTime().plus(getTTL()).isBefore(LocalDateTime.now())) { + log.debug(name+" : elapsed TTL, disposing.."); + dispose(found.getTheObject()); + TTLObject newer=new TTLObject(LocalDateTime.now(),retrieveObject(key)); + scopeMap.put(key, newer); + found=scopeMap.get(key); + } + }else {log.trace(name+" : TTL is null, never disposing..");} + log.trace(name+"Returning {} ",found); + return found.getTheObject(); + } + + protected abstract V retrieveObject(K key) throws ConfigurationException; + protected void dispose(V toDispose){}; +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/DefaultISProvider.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/DefaultISProvider.java new file mode 100644 index 0000000..c400dea --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/DefaultISProvider.java @@ -0,0 +1,61 @@ +package org.gcube.application.cms.implementations; + +import org.gcube.application.cms.caches.Engine; +import org.gcube.application.geoportal.common.model.rest.ConfigurationException; +import org.gcube.application.geoportal.common.model.rest.DatabaseConnection; +import org.gcube.application.geoportal.common.utils.ISUtils; +import org.gcube.common.resources.gcore.GenericResource; +import org.gcube.common.resources.gcore.ServiceEndpoint; + +import java.util.List; + +public class DefaultISProvider implements ISInterface, Engine { + + + @Override + public DatabaseConnection queryForDatabase(String category, String platform, String flagName, String flagValue) throws ConfigurationException { + return ISUtils.performQueryForDB(category, platform, flagName, flagValue); + } + + @Override + public List performGetAP(String category, String platform, String flagName, String flagValue) { + return ISUtils.performGetAP(category, platform, flagName, flagValue); + } + + @Override + public String decryptString(String toDecrypt) { + return ISUtils.decryptString(toDecrypt); + } + + @Override + public String encryptString(String toEncrypt) { + return ISUtils.encryptString(toEncrypt); + } + + @Override + public List getGenericResource(String secondaryType,String name) { + return ISUtils.getGenericResources(secondaryType,name); + } + + @Override + public GenericResource createUpdateGR(GenericResource resource) { + return ISUtils.writeGR(resource); + } + + // ** ENGINE + + @Override + public void init() { + + } + + @Override + public void shutdown() { + + } + + @Override + public ISInterface getObject() throws ConfigurationException { + return this; + } +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/ISInterface.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/ISInterface.java new file mode 100644 index 0000000..b2ea604 --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/ISInterface.java @@ -0,0 +1,21 @@ +package org.gcube.application.cms.implementations; + +import org.gcube.application.geoportal.common.model.rest.ConfigurationException; +import org.gcube.application.geoportal.common.model.rest.DatabaseConnection; +import org.gcube.common.resources.gcore.GenericResource; +import org.gcube.common.resources.gcore.ServiceEndpoint; + +import java.util.List; + +public interface ISInterface { + + public DatabaseConnection queryForDatabase(String category, String platform,String flagName, String flagValue) throws ConfigurationException; + public List performGetAP(String category, String platform, String flagName, String flagValue); + public String decryptString(String toDecrypt); + public String encryptString(String toEncrypt); + + public List getGenericResource(String secondaryType,String name); + + + public GenericResource createUpdateGR(GenericResource res); +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/ImplementationProvider.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/ImplementationProvider.java new file mode 100644 index 0000000..bd63cc1 --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/ImplementationProvider.java @@ -0,0 +1,101 @@ +package org.gcube.application.cms.implementations; + + +import lombok.Synchronized; +import lombok.extern.slf4j.Slf4j; +import org.gcube.application.cms.caches.Engine; +import org.gcube.application.geoportal.common.model.rest.ConfigurationException; +import org.gcube.common.storagehub.client.dsl.StorageHubClient; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +@Slf4j +public class ImplementationProvider { + + private static ImplementationProvider instance=null; + + @Synchronized + public static ImplementationProvider get() { + if(instance==null) { + instance=new ImplementationProvider(); + } + return instance; + } + + + public T getProvidedObjectByClass(Class clazz) throws ConfigurationException { + return (T) implementationsRegistry.get(clazz).getObject(); + } + + public Engine getEngineByManagedClass(Class clazz) throws ConfigurationException { + return implementationsRegistry.get(clazz); + } + + private ConcurrentHashMap implementationsRegistry=new ConcurrentHashMap<>(); + + public void setEngine(Engine engine, Class clazz){ + implementationsRegistry.put(clazz,engine); + } + + private ImplementationProvider(){ + //Defaults + setEngine(new DefaultISProvider(),ISInterface.class); + setEngine(new StorageHubProvider(), StorageHubClient.class); + } + public Map getManagerList(){ + HashMap toReturn=new HashMap<>(); + implementationsRegistry.forEach( + (aClass, engine) -> {toReturn.put(engine.getClass(),aClass.getCanonicalName());} + ); + return toReturn; + } + + private boolean isInit=false; + + @Synchronized + public void initEngines(){ + if(!isInit) { + log.info("INITIALIZING ENGINES. Size : {} ", implementationsRegistry.size()); + HashSet failed = new HashSet<>(); + implementationsRegistry.forEach((aClass, engine) -> { + log.info("Init : {} -> {}", engine.getClass().toGenericString(), aClass.getCanonicalName()); + try { + engine.init(); + } catch (Throwable t) { + failed.add(engine.getClass()); + log.error("Unable to start engine {} ", engine.getClass(), t); + } + }); + if (failed.isEmpty()) + log.info("INIT OK"); + else { + log.warn("!!!!! Following Engines FAILED INIT :"); + failed.forEach(aClass -> log.warn(String.valueOf(aClass))); + } + isInit = true; + }else log.info("Received Init request but Engines already started"); + } + + public void shutdownEngines(){ + log.info("SHUTTING DOWN ENGINES. Size : {} ",implementationsRegistry.size()); + HashSet failed= new HashSet<>(); + implementationsRegistry.forEach((aClass, engine) -> { + log.info("ShotDown : {} -> {}",engine.getClass().toGenericString(),aClass.getCanonicalName()); + try{ + engine.shutdown(); + }catch (Throwable t){ + failed.add(engine.getClass()); + log.error("Unable to shutdown engine {} ",engine.getClass(),t); + } + }); + if(failed.isEmpty()) + log.info("SHUTDOWN OK"); + else { + log.warn("!!!!! Following Engines FAILED SHUTDOWN :"); + failed.forEach(aClass->log.warn(String.valueOf(aClass))); + } + } +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/ProjectAccess.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/ProjectAccess.java new file mode 100644 index 0000000..e163ed9 --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/ProjectAccess.java @@ -0,0 +1,23 @@ +package org.gcube.application.cms.implementations; + +import org.bson.Document; +import org.gcube.application.cms.implementations.faults.InvalidUserRoleException; +import org.gcube.application.cms.implementations.faults.ProjectNotFoundException; +import org.gcube.application.cms.implementations.faults.RegistrationException; +import org.gcube.application.cms.implementations.faults.UnauthorizedAccess; +import org.gcube.application.geoportal.common.model.document.Project; +import org.gcube.application.geoportal.common.model.document.relationships.RelationshipNavigationObject; +import org.gcube.application.geoportal.common.model.rest.ConfigurationException; +import org.gcube.application.geoportal.common.model.rest.QueryRequest; + +import java.util.List; + +public interface ProjectAccess { + + + public Project getById(String ucid,String id) throws RegistrationException, ConfigurationException, InvalidUserRoleException, ProjectNotFoundException, UnauthorizedAccess; + + public Iterable query(String ucid, QueryRequest query) throws RegistrationException, ConfigurationException, InvalidUserRoleException; + + public List getRelations(String ucid, String id, String relation,Boolean deep) throws InvalidUserRoleException, RegistrationException, ProjectNotFoundException, ConfigurationException, UnauthorizedAccess; +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/StorageHubProvider.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/StorageHubProvider.java new file mode 100644 index 0000000..ac32917 --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/StorageHubProvider.java @@ -0,0 +1,20 @@ +package org.gcube.application.cms.implementations; + +import org.gcube.application.cms.caches.Engine; +import org.gcube.application.geoportal.common.model.rest.ConfigurationException; +import org.gcube.common.storagehub.client.dsl.StorageHubClient; + +public class StorageHubProvider implements Engine { + + + @Override + public StorageHubClient getObject() throws ConfigurationException { + return new StorageHubClient(); + } + + @Override + public void init() {} + @Override + public void shutdown() { } + +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/WSInterface.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/WSInterface.java new file mode 100644 index 0000000..b1b4e53 --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/WSInterface.java @@ -0,0 +1,4 @@ +package org.gcube.application.cms.implementations; + +public interface WSInterface { +} diff --git a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/WorkspaceManager.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/WorkspaceManager.java similarity index 60% rename from geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/WorkspaceManager.java rename to cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/WorkspaceManager.java index 4e1bf75..d10a27c 100644 --- a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/WorkspaceManager.java +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/WorkspaceManager.java @@ -1,18 +1,16 @@ -package org.gcube.application.geoportal.service.engine; +package org.gcube.application.cms.implementations; import lombok.*; import lombok.extern.slf4j.Slf4j; -import org.gcube.application.geoportal.common.faults.PathException; -import org.gcube.application.geoportal.common.model.legacy.WorkspaceContent; +import org.gcube.application.geoportal.common.model.configuration.Archive; +import org.gcube.application.geoportal.common.model.document.filesets.RegisteredFile; +import org.gcube.application.geoportal.common.model.rest.ConfigurationException; import org.gcube.application.geoportal.common.utils.Files; -import org.gcube.application.geoportal.service.model.internal.faults.ConfigurationException; import org.gcube.common.storagehub.client.dsl.FileContainer; import org.gcube.common.storagehub.client.dsl.FolderContainer; import org.gcube.common.storagehub.client.dsl.StorageHubClient; import org.gcube.common.storagehub.model.exceptions.StorageHubException; -import javax.validation.constraints.NotNull; -import java.io.FileNotFoundException; import java.io.InputStream; @Slf4j @@ -22,6 +20,7 @@ public class WorkspaceManager { private StorageHubClient sgClient=null; + @Getter private FolderContainer appBase=null; @Getter @@ -29,7 +28,7 @@ public class WorkspaceManager { @AllArgsConstructor @RequiredArgsConstructor public static class FolderOptions{ - @NotNull + @NonNull private String folderName; private String folderDescription; private FolderContainer parent; @@ -40,7 +39,7 @@ public class WorkspaceManager { @AllArgsConstructor @RequiredArgsConstructor public static class FileOptions{ - @NotNull + @NonNull private String fileName; @NonNull private InputStream is; @@ -50,9 +49,14 @@ public class WorkspaceManager { } + public Archive getConfiguration(){ + Archive toReturn = new Archive("W-STORAGE"); + toReturn.put("folder_id",appBase.getId()); + return toReturn; + } public WorkspaceManager() throws ConfigurationException, StorageHubException { - sgClient= ImplementationProvider.get().getSHubProvider().getObject(); + sgClient= ImplementationProvider.get().getProvidedObjectByClass(StorageHubClient.class); appBase=getApplicationBaseFolder(sgClient); } @@ -74,10 +78,23 @@ public class WorkspaceManager { sgClient.open(id).asFolder().delete(); } - public FolderContainer getSubFolder(FolderContainer parentFolder,String path) throws StorageHubException { + public FolderContainer getSubFolder(FolderContainer parentFolder,String path) throws StorageHubException { + return getSubFolder(parentFolder,path,""); + } + + + /** + * Returns sub folder. Creates it if missing + * + * @param parentFolder + * @param path + * @return + * @throws StorageHubException + */ + public FolderContainer getSubFolder(FolderContainer parentFolder,String path, String description) throws StorageHubException { try{ return parentFolder.openByRelativePath(path).asFolder(); - }catch(StorageHubException e) { + }catch(StorageHubException e) { log.debug("Missing subPath "+path); FolderContainer targetParent=parentFolder; String targetName=path; @@ -87,29 +104,50 @@ public class WorkspaceManager { targetParent=getSubFolder(parentFolder,parent); targetName=path.substring(path.lastIndexOf("/")+1); } - log.debug("Creating "+targetName); - return createFolder(new FolderOptions(targetName,"",targetParent)); + FolderOptions opts = new FolderOptions(targetName,description,targetParent); + log.debug("Creating FOLDER {}", opts); + return createFolder(opts); } } - public WorkspaceContent storeToWS(FileOptions opts) throws FileNotFoundException, StorageHubException { +// public WorkspaceContent storeToWS(FileOptions opts) throws FileNotFoundException, StorageHubException { +// FileContainer item=createFileRoutine(opts); +// item=sgClient.open(item.getId()).asFile(); +// +// WorkspaceContent content=new WorkspaceContent(); +// content.setLink(item.getPublicLink().toString()); +// content.setMimetype(item.get().getContent().getMimeType()); +// content.setStorageID(item.getId()); +// content.setName(item.get().getName()); +// return content; +// +// } + + public RegisteredFile registerFile(FileOptions opts) throws StorageHubException { FileContainer item=createFileRoutine(opts); item=sgClient.open(item.getId()).asFile(); - WorkspaceContent content=new WorkspaceContent(); - content.setLink(item.getPublicLink().toString()); - content.setMimetype(item.get().getContent().getMimeType()); - content.setStorageID(item.getId()); - content.setName(item.get().getName()); - return content; + RegisteredFile file=new RegisteredFile(); + + + file.setLink(item.getPublicLink().toString()); + file.setMimetype(item.get().getContent().getMimeType()); + file.setStorageID(item.getId()); + file.setName(item.get().getName()); + return file; } - - public void deleteFromWS(WorkspaceContent toDelete) throws StorageHubException { - sgClient.open(toDelete.getStorageID()).asFile().forceDelete(); - } + +// public void deleteFromWS(WorkspaceContent toDelete) throws StorageHubException { +// sgClient.open(toDelete.getStorageID()).asFile().forceDelete(); +// } + + public void deleteItem(String itemId)throws StorageHubException{ + sgClient.open(itemId).asItem().forceDelete(); + } + // STATIC SYNCH METHODS @Synchronized diff --git a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/model/internal/faults/DataParsingException.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/faults/DataParsingException.java similarity index 92% rename from geoportal-service/src/main/java/org/gcube/application/geoportal/service/model/internal/faults/DataParsingException.java rename to cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/faults/DataParsingException.java index f91a9a2..4495115 100644 --- a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/model/internal/faults/DataParsingException.java +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/faults/DataParsingException.java @@ -1,4 +1,4 @@ -package org.gcube.application.geoportal.service.model.internal.faults; +package org.gcube.application.cms.implementations.faults; public class DataParsingException extends Exception { diff --git a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/model/internal/faults/DeletionException.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/faults/DeletionException.java similarity index 88% rename from geoportal-service/src/main/java/org/gcube/application/geoportal/service/model/internal/faults/DeletionException.java rename to cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/faults/DeletionException.java index bb121e7..d41cfa3 100644 --- a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/model/internal/faults/DeletionException.java +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/faults/DeletionException.java @@ -1,4 +1,4 @@ -package org.gcube.application.geoportal.service.model.internal.faults; +package org.gcube.application.cms.implementations.faults; public class DeletionException extends Exception { diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/faults/InvalidLockException.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/faults/InvalidLockException.java new file mode 100644 index 0000000..13f9c02 --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/faults/InvalidLockException.java @@ -0,0 +1,22 @@ +package org.gcube.application.cms.implementations.faults; + +public class InvalidLockException extends Exception{ + public InvalidLockException() { + } + + public InvalidLockException(String message) { + super(message); + } + + public InvalidLockException(String message, Throwable cause) { + super(message, cause); + } + + public InvalidLockException(Throwable cause) { + super(cause); + } + + public InvalidLockException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/model/internal/faults/InvalidStateException.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/faults/InvalidStateException.java similarity index 92% rename from geoportal-service/src/main/java/org/gcube/application/geoportal/service/model/internal/faults/InvalidStateException.java rename to cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/faults/InvalidStateException.java index f2f39fa..18762b3 100644 --- a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/model/internal/faults/InvalidStateException.java +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/faults/InvalidStateException.java @@ -1,4 +1,4 @@ -package org.gcube.application.geoportal.service.model.internal.faults; +package org.gcube.application.cms.implementations.faults; public class InvalidStateException extends Exception { diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/faults/InvalidUserRoleException.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/faults/InvalidUserRoleException.java new file mode 100644 index 0000000..1a6de3f --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/faults/InvalidUserRoleException.java @@ -0,0 +1,23 @@ +package org.gcube.application.cms.implementations.faults; + +public class InvalidUserRoleException extends Exception { + + public InvalidUserRoleException() { + } + + public InvalidUserRoleException(String message) { + super(message); + } + + public InvalidUserRoleException(String message, Throwable cause) { + super(message, cause); + } + + public InvalidUserRoleException(Throwable cause) { + super(cause); + } + + public InvalidUserRoleException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/faults/ProjectLockedException.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/faults/ProjectLockedException.java new file mode 100644 index 0000000..07b9c32 --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/faults/ProjectLockedException.java @@ -0,0 +1,22 @@ +package org.gcube.application.cms.implementations.faults; + +public class ProjectLockedException extends Exception{ + public ProjectLockedException() { + } + + public ProjectLockedException(String message) { + super(message); + } + + public ProjectLockedException(String message, Throwable cause) { + super(message, cause); + } + + public ProjectLockedException(Throwable cause) { + super(cause); + } + + public ProjectLockedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/faults/ProjectNotFoundException.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/faults/ProjectNotFoundException.java new file mode 100644 index 0000000..9bb9f90 --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/faults/ProjectNotFoundException.java @@ -0,0 +1,22 @@ +package org.gcube.application.cms.implementations.faults; + +public class ProjectNotFoundException extends Exception { + public ProjectNotFoundException() { + } + + public ProjectNotFoundException(String message) { + super(message); + } + + public ProjectNotFoundException(String message, Throwable cause) { + super(message, cause); + } + + public ProjectNotFoundException(Throwable cause) { + super(cause); + } + + public ProjectNotFoundException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/faults/RegistrationException.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/faults/RegistrationException.java new file mode 100644 index 0000000..a2e59bc --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/faults/RegistrationException.java @@ -0,0 +1,23 @@ +package org.gcube.application.cms.implementations.faults; + +public class RegistrationException extends Exception { + + public RegistrationException() { + } + + public RegistrationException(String message) { + super(message); + } + + public RegistrationException(String message, Throwable cause) { + super(message, cause); + } + + public RegistrationException(Throwable cause) { + super(cause); + } + + public RegistrationException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/faults/UnauthorizedAccess.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/faults/UnauthorizedAccess.java new file mode 100644 index 0000000..3bb5572 --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/faults/UnauthorizedAccess.java @@ -0,0 +1,23 @@ +package org.gcube.application.cms.implementations.faults; + +public class UnauthorizedAccess extends Exception { + + public UnauthorizedAccess() { + } + + public UnauthorizedAccess(String message) { + super(message); + } + + public UnauthorizedAccess(String message, Throwable cause) { + super(message, cause); + } + + public UnauthorizedAccess(Throwable cause) { + super(cause); + } + + public UnauthorizedAccess(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/IndexerPluginInterface.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/IndexerPluginInterface.java new file mode 100644 index 0000000..60ee76b --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/IndexerPluginInterface.java @@ -0,0 +1,19 @@ +package org.gcube.application.cms.plugins; + +import org.gcube.application.cms.plugins.faults.InvalidPluginRequestException; +import org.gcube.application.cms.plugins.reports.IndexDocumentReport; +import org.gcube.application.cms.plugins.requests.BaseRequest; +import org.gcube.application.cms.plugins.requests.IndexDocumentRequest; +import org.gcube.application.geoportal.common.model.configuration.Index; +import org.gcube.application.geoportal.common.model.rest.ConfigurationException; + +public interface IndexerPluginInterface extends InitializablePlugin{ + + public IndexDocumentReport index(IndexDocumentRequest request) throws InvalidPluginRequestException; + public IndexDocumentReport deindex(IndexDocumentRequest request) throws InvalidPluginRequestException; + + public Index getIndex(BaseRequest request) throws ConfigurationException; + + + +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/LifecycleManager.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/LifecycleManager.java index ad59b66..44a068e 100644 --- a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/LifecycleManager.java +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/LifecycleManager.java @@ -1,14 +1,24 @@ package org.gcube.application.cms.plugins; -import org.gcube.application.cms.plugins.faults.StepException; -import org.gcube.application.cms.plugins.reports.ExecutionReport; +import org.gcube.application.cms.plugins.faults.*; +import org.gcube.application.cms.plugins.reports.EventExecutionReport; +import org.gcube.application.cms.plugins.reports.StepExecutionReport; +import org.gcube.application.cms.plugins.requests.BaseRequest; +import org.gcube.application.cms.plugins.requests.EventExecutionRequest; import org.gcube.application.cms.plugins.requests.StepExecutionRequest; -import org.gcube.application.geoportal.common.model.document.ProfiledDocument; +import org.gcube.application.geoportal.common.model.configuration.Configuration; +import org.gcube.application.geoportal.common.model.rest.ConfigurationException; + public interface LifecycleManager extends InitializablePlugin{ // Lifecycle operations - public ExecutionReport performStep(StepExecutionRequest request)throws StepException; + public StepExecutionReport performStep(StepExecutionRequest request) throws StepException, InvalidPluginRequestException, InvalidProfileException, ConfigurationException, InsufficientPrivileges; + public Configuration getCurrentConfiguration(BaseRequest request) throws ConfigurationException; + + public EventExecutionReport onEvent(EventExecutionRequest request) throws EventException, InvalidPluginRequestException; + + public void setPluginManager(PluginManagerInterface manager); } diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/MaterializationPlugin.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/MaterializationPlugin.java new file mode 100644 index 0000000..d1e796c --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/MaterializationPlugin.java @@ -0,0 +1,14 @@ +package org.gcube.application.cms.plugins; + +import org.gcube.application.cms.plugins.faults.InvalidPluginRequestException; +import org.gcube.application.cms.plugins.faults.MaterializationException; +import org.gcube.application.cms.plugins.reports.MaterializationReport; +import org.gcube.application.cms.plugins.requests.MaterializationRequest; + +public interface MaterializationPlugin extends InitializablePlugin{ + + public MaterializationReport materialize(MaterializationRequest request) throws MaterializationException, InvalidPluginRequestException; + + public MaterializationReport dematerialize(MaterializationRequest request) throws MaterializationException, InvalidPluginRequestException; + +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/Plugin.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/Plugin.java index cac99a9..57636af 100644 --- a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/Plugin.java +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/Plugin.java @@ -1,6 +1,6 @@ package org.gcube.application.cms.plugins; -import org.gcube.application.cms.plugins.model.PluginDescriptor; +import org.gcube.application.geoportal.common.model.plugins.PluginDescriptor; public interface Plugin { diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/PluginManagerInterface.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/PluginManagerInterface.java new file mode 100644 index 0000000..4560093 --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/PluginManagerInterface.java @@ -0,0 +1,11 @@ +package org.gcube.application.cms.plugins; + +import org.gcube.application.geoportal.common.model.rest.ConfigurationException; + +import java.util.Map; + +public interface PluginManagerInterface { + + public Plugin getById(String pluginID) throws ConfigurationException; + public Map getByType(String type) throws ConfigurationException; +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/PluginsReflections.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/PluginsReflections.java new file mode 100644 index 0000000..15e944d --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/PluginsReflections.java @@ -0,0 +1,46 @@ +package org.gcube.application.cms.plugins; + +import lombok.extern.slf4j.Slf4j; +import org.reflections.Reflections; +import org.reflections.util.ConfigurationBuilder; +import org.reflections.util.FilterBuilder; + +import java.lang.reflect.Modifier; +import java.util.HashMap; +import java.util.Map; + +@Slf4j +public class PluginsReflections { + + /** Loads Plugin implementation classes. It should only be accessed once by Plugin Manager + * Plugins shouldn't access this class unless for testing purposes. + * @return + */ + public static Map load(){ + Map toReturn=new HashMap<>(); + log.warn("WARNING!! LOADING PLUGIN CLASSES : THIS SHOULD HAPPEN ONLY ONCE"); + Reflections reflections = new Reflections( + new ConfigurationBuilder() + .forPackage("org.gcube.application.cms") + .filterInputsBy(new FilterBuilder().includePackage("org.gcube.application.cms"))); + + reflections.getSubTypesOf(Plugin.class).iterator().forEachRemaining(pluginClass->{ + log.trace("Evaluating class {}",pluginClass); + if(!pluginClass.isInterface() && !Modifier.isAbstract(pluginClass.getModifiers())){ + try { + log.debug("Found implementation {} ",pluginClass); + Plugin plugin = pluginClass.newInstance(); + log.debug("Loading {} description : {}", plugin, plugin.getDescriptor()); + + toReturn.put(plugin.getDescriptor().getId(), plugin); + + + }catch (Throwable t){ + log.warn("Unable to instantiate Plugin "+pluginClass,t); + } + } + + }); + return toReturn; + } +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/EventException.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/EventException.java new file mode 100644 index 0000000..cc89b52 --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/EventException.java @@ -0,0 +1,23 @@ +package org.gcube.application.cms.plugins.faults; + +public class EventException extends PluginExecutionException{ + + public EventException() { + } + + public EventException(String message) { + super(message); + } + + public EventException(String message, Throwable cause) { + super(message, cause); + } + + public EventException(Throwable cause) { + super(cause); + } + + public EventException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/IndexingException.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/IndexingException.java new file mode 100644 index 0000000..e49cc34 --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/IndexingException.java @@ -0,0 +1,22 @@ +package org.gcube.application.cms.plugins.faults; + +public class IndexingException extends PluginExecutionException{ + public IndexingException() { + } + + public IndexingException(String message) { + super(message); + } + + public IndexingException(String message, Throwable cause) { + super(message, cause); + } + + public IndexingException(Throwable cause) { + super(cause); + } + + public IndexingException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/InitializationException.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/InitializationException.java index 177e5d6..131c23e 100644 --- a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/InitializationException.java +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/InitializationException.java @@ -1,6 +1,6 @@ package org.gcube.application.cms.plugins.faults; -public class InitializationException extends Exception{ +public class InitializationException extends PluginExecutionException{ public InitializationException() { } diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/InsufficientPrivileges.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/InsufficientPrivileges.java new file mode 100644 index 0000000..c33a332 --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/InsufficientPrivileges.java @@ -0,0 +1,22 @@ +package org.gcube.application.cms.plugins.faults; + +public class InsufficientPrivileges extends Exception { + public InsufficientPrivileges() { + } + + public InsufficientPrivileges(String message) { + super(message); + } + + public InsufficientPrivileges(String message, Throwable cause) { + super(message, cause); + } + + public InsufficientPrivileges(Throwable cause) { + super(cause); + } + + public InsufficientPrivileges(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/InvalidPluginRequestException.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/InvalidPluginRequestException.java new file mode 100644 index 0000000..0d65159 --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/InvalidPluginRequestException.java @@ -0,0 +1,22 @@ +package org.gcube.application.cms.plugins.faults; + +public class InvalidPluginRequestException extends PluginExecutionException { + public InvalidPluginRequestException() { + } + + public InvalidPluginRequestException(String message) { + super(message); + } + + public InvalidPluginRequestException(String message, Throwable cause) { + super(message, cause); + } + + public InvalidPluginRequestException(Throwable cause) { + super(cause); + } + + public InvalidPluginRequestException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/InvalidProfileException.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/InvalidProfileException.java new file mode 100644 index 0000000..1fe0b00 --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/InvalidProfileException.java @@ -0,0 +1,22 @@ +package org.gcube.application.cms.plugins.faults; + +public class InvalidProfileException extends Exception { + public InvalidProfileException() { + } + + public InvalidProfileException(String message) { + super(message); + } + + public InvalidProfileException(String message, Throwable cause) { + super(message, cause); + } + + public InvalidProfileException(Throwable cause) { + super(cause); + } + + public InvalidProfileException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/MaterializationException.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/MaterializationException.java new file mode 100644 index 0000000..35760af --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/MaterializationException.java @@ -0,0 +1,23 @@ +package org.gcube.application.cms.plugins.faults; + +public class MaterializationException extends PluginExecutionException { + + public MaterializationException() { + } + + public MaterializationException(String message) { + super(message); + } + + public MaterializationException(String message, Throwable cause) { + super(message, cause); + } + + public MaterializationException(Throwable cause) { + super(cause); + } + + public MaterializationException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/PluginExecutionException.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/PluginExecutionException.java new file mode 100644 index 0000000..7078cb6 --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/PluginExecutionException.java @@ -0,0 +1,22 @@ +package org.gcube.application.cms.plugins.faults; + +public class PluginExecutionException extends Exception{ + public PluginExecutionException() { + } + + public PluginExecutionException(String message) { + super(message); + } + + public PluginExecutionException(String message, Throwable cause) { + super(message, cause); + } + + public PluginExecutionException(Throwable cause) { + super(cause); + } + + public PluginExecutionException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/StepException.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/StepException.java index 39e5302..893e5ee 100644 --- a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/StepException.java +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/StepException.java @@ -1,6 +1,6 @@ package org.gcube.application.cms.plugins.faults; -public class StepException extends Exception { +public class StepException extends PluginExecutionException { public StepException() { } diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/UnrecognizedEventException.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/UnrecognizedEventException.java new file mode 100644 index 0000000..1586575 --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/UnrecognizedEventException.java @@ -0,0 +1,22 @@ +package org.gcube.application.cms.plugins.faults; + +public class UnrecognizedEventException extends EventException{ + public UnrecognizedEventException() { + } + + public UnrecognizedEventException(String message) { + super(message); + } + + public UnrecognizedEventException(String message, Throwable cause) { + super(message, cause); + } + + public UnrecognizedEventException(Throwable cause) { + super(cause); + } + + public UnrecognizedEventException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/UnrecognizedStepException.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/UnrecognizedStepException.java new file mode 100644 index 0000000..8dd57db --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/faults/UnrecognizedStepException.java @@ -0,0 +1,22 @@ +package org.gcube.application.cms.plugins.faults; + +public class UnrecognizedStepException extends StepException{ + public UnrecognizedStepException() { + } + + public UnrecognizedStepException(String message) { + super(message); + } + + public UnrecognizedStepException(String message, Throwable cause) { + super(message, cause); + } + + public UnrecognizedStepException(Throwable cause) { + super(cause); + } + + public UnrecognizedStepException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/AbstractLifeCycleManager.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/AbstractLifeCycleManager.java new file mode 100644 index 0000000..e718042 --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/AbstractLifeCycleManager.java @@ -0,0 +1,246 @@ +package org.gcube.application.cms.plugins.implementations; + +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.gcube.application.cms.implementations.ProjectAccess; +import org.gcube.application.cms.plugins.LifecycleManager; +import org.gcube.application.cms.plugins.PluginManagerInterface; +import org.gcube.application.cms.plugins.faults.*; +import org.gcube.application.cms.plugins.implementations.executions.GuardedEventManager; +import org.gcube.application.cms.plugins.implementations.executions.GuardedStepExecution; +import org.gcube.application.cms.plugins.reports.EventExecutionReport; +import org.gcube.application.cms.plugins.reports.InitializationReport; +import org.gcube.application.cms.plugins.reports.Report; +import org.gcube.application.cms.plugins.reports.StepExecutionReport; +import org.gcube.application.cms.plugins.requests.BaseRequest; +import org.gcube.application.cms.plugins.requests.EventExecutionRequest; +import org.gcube.application.cms.plugins.requests.StepExecutionRequest; +import org.gcube.application.geoportal.common.model.configuration.Configuration; +import org.gcube.application.geoportal.common.model.document.accounting.User; +import org.gcube.application.geoportal.common.model.document.lifecycle.LifecycleInformation; +import org.gcube.application.geoportal.common.model.document.lifecycle.TriggeredEvents; +import org.gcube.application.geoportal.common.model.plugins.LifecycleManagerDescriptor; +import org.gcube.application.geoportal.common.model.plugins.OperationDescriptor; +import org.gcube.application.geoportal.common.model.plugins.PluginDescriptor; +import org.gcube.application.geoportal.common.model.rest.ConfigurationException; +import org.gcube.application.geoportal.common.model.useCaseDescriptor.HandlerDeclaration; +import org.gcube.application.geoportal.common.utils.ContextUtils; + +import java.util.HashMap; +import java.util.Map; + +@Slf4j +public abstract class AbstractLifeCycleManager extends AbstractPlugin implements LifecycleManager { + + protected static class Events{ + public static final OperationDescriptor INIT=new OperationDescriptor(EventExecutionRequest.Events.ON_INIT_DOCUMENT,"Sets defaults and validate"); + public static final OperationDescriptor UPDATE=new OperationDescriptor(EventExecutionRequest.Events.ON_UPDATE_DOCUMENT,"Sets defaults and validate"); + public static final OperationDescriptor DELETE=new OperationDescriptor(EventExecutionRequest.Events.ON_DELETE_DOCUMENT,"No op"); + public static final OperationDescriptor DELETE_FS=new OperationDescriptor(EventExecutionRequest.Events.ON_DELETE_FILESET,"No op"); + } + + @Setter + protected PluginManagerInterface pluginManager; + + @Setter + protected ProjectAccess projectAccess; + + + private Map registeredSteps=new HashMap<>(); + private Map registeredEvent=new HashMap<>(); + + + protected void setEvent(GuardedEventManager m){ + OperationDescriptor op= m.getOp(); + DESCRIPTOR.getSupportedEvents().put(op.getId(),op); + registeredEvent.put(op.getId(),m); + } + protected void setStep(GuardedStepExecution e){ + OperationDescriptor op= e.getOp(); + DESCRIPTOR.getSupportedSteps().put(op.getId(),op); + registeredSteps.put(op.getId(),e); + } + + public AbstractLifeCycleManager() { + DESCRIPTOR.setSupportedSteps(new HashMap<>()); + DESCRIPTOR.setSupportedEvents(new HashMap<>()); + registerEvents(); + registerSteps(); + } + + protected EventExecutionReport onDeleteDocument(EventExecutionReport report) throws ConfigurationException, InvalidPluginRequestException, MaterializationException, EventException {return report;} + protected EventExecutionReport onDeleteFileSet(EventExecutionReport report) throws ConfigurationException, InvalidPluginRequestException, MaterializationException, EventException {return report;} + protected EventExecutionReport onUpdateDocument(EventExecutionReport report){ + report = validate(report); + report = setDefault(report); + return report; + } + protected EventExecutionReport onInitDocument(EventExecutionReport report) throws InvalidPluginRequestException { + report = validate(report); + report = setDefault(report); + return report; + } + + + + protected void registerEvents(){ + setEvent(new GuardedEventManager(Events.INIT) { + @Override + protected EventExecutionReport run() throws Exception { + return onInitDocument(theReport); + } + }); + setEvent(new GuardedEventManager(Events.UPDATE) { + @Override + protected EventExecutionReport run() throws Exception { + return onUpdateDocument(theReport); + } + }); + setEvent(new GuardedEventManager(Events.DELETE) { + @Override + protected EventExecutionReport run() throws Exception { + return onDeleteDocument(theReport); + } + }); + setEvent(new GuardedEventManager(Events.DELETE_FS) { + @Override + protected EventExecutionReport run() throws Exception { + return onDeleteFileSet(theReport); + } + }); + } + protected void registerSteps(){} + + + protected LifecycleManagerDescriptor DESCRIPTOR=new LifecycleManagerDescriptor(";;;"); + + + @Override + public StepExecutionReport performStep(StepExecutionRequest request) throws StepException, InvalidPluginRequestException, InvalidProfileException, ConfigurationException, InsufficientPrivileges { + log.info("Serving Request {}",request); + + log.debug("Checking is STEP {} is supported by {}",request.getStep(),DESCRIPTOR.getId()); + if(!registeredSteps.containsKey(request.getStep())) + throw new UnrecognizedStepException(("Invalid Step " + request.getStep())); + + HandlerDeclaration handlerDeclaration= getConfigurationFromProfile(request.getUseCaseDescriptor()); + log.debug("Checking user role {} against config {} ",request.getCaller(),handlerDeclaration); + if(!canInvokeStep(request.getStep(),request.getCaller(), handlerDeclaration)) + throw new InsufficientPrivileges("User is not allowed to invoke "+request.getStep()); + + StepExecutionReport report=new StepExecutionReport(request); + LifecycleInformation info=report.getToSetLifecycleInformation(); + report.setStatus(Report.Status.OK); + info.setLastOperationStatus(LifecycleInformation.Status.OK); + info.setLastInvokedStep(request.getStep()); + + try { + GuardedStepExecution exec=registeredSteps.get(request.getStep()); + exec.setTheReport(report); + exec.setHandlerConfiguration(handlerDeclaration); + log.debug("Actually executing Step with {} ",exec); + return exec.execute(); + }catch (StepException | InvalidPluginRequestException e){ + throw e; + }catch (Throwable t) { + log.error("Unable to perform step " + request.getStep(), t); + String msg = "Unable to execute Step " + request.getStep() + ". Error was " + t.getMessage(); + report.setStatus(Report.Status.ERROR); + report.putMessage(msg); + info.setLastOperationStatus(LifecycleInformation.Status.ERROR); + info.addErrorMessage(msg); + } + return report; + } + + protected boolean canInvokeStep(String stepID, User u, HandlerDeclaration config) throws ConfigurationException { + return new RoleManager(config).canInvokeStep(stepID,u); + } + + + @Override + public InitializationReport initInContext() throws InitializationException { + InitializationReport report = new InitializationReport(); + try{ + report.setStatus(Report.Status.OK); + } catch (Throwable e) { + log.error("Unable to initialize plugins in {} ", ContextUtils.getCurrentScope(),e); + report.setStatus(Report.Status.WARNING); + report.putMessage("Unable to initialize plugins in "+ ContextUtils.getCurrentScope()+" : "+e.getMessage()); + } + return report; + } + + @Override + public InitializationReport init() throws InitializationException { + InitializationReport report = new InitializationReport(); + try{ + report.setStatus(Report.Status.OK); + + } catch (Throwable e) { + log.error("Unable to initialize plugins ",e); + report.setStatus(Report.Status.WARNING); + report.putMessage("Unable to initialize plugins : "+e.getMessage()); + } + return report; + } + + + + @Override + public PluginDescriptor getDescriptor() { + return DESCRIPTOR; + } + + @Override + public EventExecutionReport onEvent(EventExecutionRequest request) throws EventException, InvalidPluginRequestException { + log.info("Executing Event {}",request); + EventExecutionReport report=new EventExecutionReport(request); + report.getToSetLifecycleInformation().addEventReport(new TriggeredEvents()); + TriggeredEvents info = report.getToSetLifecycleInformation().getLastEvent(); + info.setLastOperationStatus(LifecycleInformation.Status.OK); + info.setEvent(request.getEvent()); + try { + if(!registeredEvent.containsKey(request.getEvent())) + throw new UnrecognizedEventException("Unexpected Event "+request.getEvent()); + + return registeredEvent.get(request.getEvent()).setTheReport(report).execute(); + + }catch (EventException e){ + throw e; + }catch (Throwable t){ + log.error("Unable to execute on event "+request.getEvent(),t); + String msg = "Unable to execute on event "+request.getEvent()+". Error was "+t.getMessage(); + info.setLastOperationStatus(LifecycleInformation.Status.ERROR); + info.addErrorMessage(msg); + report.setStatus(Report.Status.ERROR); + report.putMessage(msg); + } + return report; + } + + + /** + * Override this method for programmatic default values management + * + * @param currentReport + * @return + */ + public EventExecutionReport setDefault(EventExecutionReport currentReport){ + // Default implementation is no op + return currentReport; + } + + public EventExecutionReport validate(EventExecutionReport currentReport){ + // Default implementation is no op + return currentReport; + } + + @Override + public void shutdown() throws ShutDownException {} + + @Override + public Configuration getCurrentConfiguration(BaseRequest request) throws ConfigurationException { + return new Configuration(); + } +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/AbstractPlugin.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/AbstractPlugin.java new file mode 100644 index 0000000..c0fe6d7 --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/AbstractPlugin.java @@ -0,0 +1,30 @@ +package org.gcube.application.cms.plugins.implementations; + +import org.gcube.application.cms.plugins.Plugin; +import org.gcube.application.cms.plugins.faults.InvalidProfileException; +import org.gcube.application.geoportal.common.model.useCaseDescriptor.HandlerDeclaration; +import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor; + +import java.util.List; +import java.util.Map; + +public abstract class AbstractPlugin implements Plugin { + + + + + + protected HandlerDeclaration getConfigurationFromProfile(UseCaseDescriptor useCaseDescriptor) throws InvalidProfileException{ + return getMultipleDeclarationsFromProfile(useCaseDescriptor).get(0); + } + + protected List getMultipleDeclarationsFromProfile(UseCaseDescriptor p)throws InvalidProfileException { + Map> map = p.getHandlersMapByID(); + if(map.containsKey(getDescriptor().getId())) + return map.get(getDescriptor().getId()); + else throw new InvalidProfileException("No Configuration found for "+getDescriptor().getId()+" in "+p.getId()); + } + + + +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/Default3PhaseManager.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/Default3PhaseManager.java new file mode 100644 index 0000000..b1a81eb --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/Default3PhaseManager.java @@ -0,0 +1,169 @@ +package org.gcube.application.cms.plugins.implementations; + +import com.vdurmont.semver4j.Semver; +import lombok.extern.slf4j.Slf4j; +import org.bson.Document; +import org.gcube.application.cms.plugins.IndexerPluginInterface; +import org.gcube.application.cms.plugins.LifecycleManager; +import org.gcube.application.cms.plugins.MaterializationPlugin; +import org.gcube.application.cms.plugins.faults.EventException; +import org.gcube.application.cms.plugins.faults.InvalidPluginRequestException; +import org.gcube.application.cms.plugins.faults.MaterializationException; +import org.gcube.application.cms.plugins.implementations.executions.GuardedStepExecution; +import org.gcube.application.cms.plugins.reports.DocumentHandlingReport; +import org.gcube.application.cms.plugins.reports.EventExecutionReport; +import org.gcube.application.cms.plugins.reports.StepExecutionReport; +import org.gcube.application.cms.plugins.requests.BaseRequest; +import org.gcube.application.cms.plugins.requests.StepExecutionRequest; +import org.gcube.application.geoportal.common.model.configuration.Configuration; +import org.gcube.application.geoportal.common.model.configuration.Index; +import org.gcube.application.geoportal.common.model.document.lifecycle.LifecycleInformation; +import org.gcube.application.geoportal.common.model.plugins.OperationDescriptor; +import org.gcube.application.geoportal.common.model.rest.ConfigurationException; +import org.gcube.application.geoportal.common.utils.Files; + +import java.util.Collections; + +@Slf4j +public class Default3PhaseManager extends SimpleLifeCycleManager implements LifecycleManager { + + protected static class Phases { + public static final String PENDING_APPROVAL="Pending Approval"; + public static final String PUBLISHED="Published"; + + } + + protected static class STEPS{ + public static final OperationDescriptor SUBMIT=new OperationDescriptor("SUBMIT-FOR-REVIEW","Submits the Draft for reviewing"); + public static final OperationDescriptor REJECT=new OperationDescriptor("REJECT-DRAFT","Rejects the submitted Draft"); + public static final OperationDescriptor APPROVE=new OperationDescriptor("APPROVE-SUBMITTED","Approves the submitted Draft"); + + static { + SUBMIT.setAppliableToPhases(Collections.singletonList(LifecycleInformation.CommonPhases.DRAFT_PHASE)); + REJECT.setAppliableToPhases(Collections.singletonList(Phases.PENDING_APPROVAL)); + APPROVE.setAppliableToPhases(Collections.singletonList(Phases.PENDING_APPROVAL)); + } + } + + private static class PARAMETERS{ + public static final String NOTES="notes"; + } + + + @Override + protected EventExecutionReport onDeleteDocument(EventExecutionReport report) throws ConfigurationException, InvalidPluginRequestException, MaterializationException, EventException { + report = super.onDeleteDocument(report); + for(IndexerPluginInterface indexer : getIndexers(report.getTheRequest())) + report= deIndex(report,indexer,getInternalIndexParams(report.getTheRequest())); + return report; + } + + @Override + protected EventExecutionReport onDeleteFileSet(EventExecutionReport theReport) throws ConfigurationException, InvalidPluginRequestException, MaterializationException, EventException { + theReport = super.onDeleteFileSet(theReport); + String phase = theReport.getTheRequest().getDocument().getLifecycleInformation().getPhase(); + Document parameters = null; + if(phase.equals(Phases.PENDING_APPROVAL)) + parameters =getInternalIndexParams(theReport.getTheRequest()); + if(phase.equals(Phases.PUBLISHED)) + parameters = getPublicIndexParams(theReport.getTheRequest()); + if(parameters!= null) + for(IndexerPluginInterface indexer : getIndexers(theReport.getTheRequest())) + theReport = index(theReport,indexer,getPublicIndexParams(theReport.getTheRequest())); + return theReport; + } + + @Override + protected void registerSteps() { + // register steps + setStep(new GuardedStepExecution(STEPS.SUBMIT) { + @Override + protected StepExecutionReport run() throws Exception { + return executeSubmit(theReport); + } + }); + setStep(new GuardedStepExecution(STEPS.APPROVE) { + @Override + protected StepExecutionReport run() throws Exception { + return executeApprove(theReport); + } + }); + setStep(new GuardedStepExecution(STEPS.REJECT) { + @Override + protected StepExecutionReport run() throws Exception { + return executeReject(theReport); + } + }); + } + + public Default3PhaseManager() { + DESCRIPTOR.setId("DEFAULT-3PHASE"); + DESCRIPTOR.setDescription("Default 3-phase lifecycle manager. This plugin supports a simple moderated publication lifecycle."); + DESCRIPTOR.setVersion(new Semver("1.0.0")); + DESCRIPTOR.setLabel("Default 3-Phase"); + } + + + @Override + public Configuration getCurrentConfiguration(BaseRequest req) throws ConfigurationException { + Configuration toReturn = super.getCurrentConfiguration(req); + + IndexerPluginInterface indexerPlugin; + indexerPlugin = (IndexerPluginInterface) pluginManager.getById("SDI-Indexer-Plugin"); + BaseRequest indexRequest = new BaseRequest(req.getUseCaseDescriptor(),req.getCaller(),req.getContext()); + + // Info on internal_index + try { + indexRequest.setCallParameters(getInternalIndexParams(req)); + Index internalIndex = indexerPlugin.getIndex(indexRequest); + internalIndex.put("flag", "internal"); + toReturn.getIndexes().add(internalIndex); + }catch(ConfigurationException e){ + toReturn.addErrorMessage("Unable to gather information on internal GIS Centroids Index : "+e.getMessage()); + log.error("Unable to gather information on internal GIS Centroids Index",e); + } + return toReturn; + } + + protected Document getInternalIndexParams(BaseRequest req){ + Document callParameters = new Document(); + + callParameters.put("workspace", Files.fixFilename(req.getUseCaseDescriptor().getId()+"_internal_"+req.getContext().getName())); + callParameters.put("indexName",Files.fixFilename(req.getUseCaseDescriptor().getId()+"_internal_"+req.getContext().getName()+"_centroids")); + return callParameters; + } + + protected StepExecutionReport executeSubmit(StepExecutionReport theReport) throws Exception { + // Materialize + + for(MaterializationPlugin mat : getMaterializers(theReport.getTheRequest())) + theReport = materializeDocument(theReport,mat,getMaterializationParameters(theReport.getTheRequest())); + if(theReport.getToSetLifecycleInformation().getLastOperationStatus().equals(LifecycleInformation.Status.OK)){ + // Index + for(IndexerPluginInterface indexer : getIndexers(theReport.getTheRequest())) + theReport = index(theReport,indexer,getInternalIndexParams(theReport.getTheRequest())); + // setPhase + if(theReport.getToSetLifecycleInformation().getLastOperationStatus().equals(LifecycleInformation.Status.OK)) + theReport.getToSetLifecycleInformation().setPhase(Phases.PENDING_APPROVAL); + } + return theReport; + } + + protected StepExecutionReport executeApprove(StepExecutionReport theReport) throws Exception { + // Index + for(IndexerPluginInterface indexer : getIndexers(theReport.getTheRequest())) + theReport = index(theReport,indexer,getPublicIndexParams(theReport.getTheRequest())); + // setPhase + if(theReport.getToSetLifecycleInformation().getLastOperationStatus().equals(LifecycleInformation.Status.OK)) + theReport.getToSetLifecycleInformation().setPhase(Phases.PUBLISHED); + return theReport; + } + + protected StepExecutionReport executeReject(StepExecutionReport theReport) throws Exception { + if(theReport.getToSetLifecycleInformation().getLastOperationStatus().equals(LifecycleInformation.Status.OK)) + theReport.getToSetLifecycleInformation().setPhase(LifecycleInformation.CommonPhases.DRAFT_PHASE); + return theReport; + } + + +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/RoleManager.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/RoleManager.java new file mode 100644 index 0000000..ad5db3f --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/RoleManager.java @@ -0,0 +1,64 @@ +package org.gcube.application.cms.plugins.implementations; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.*; +import lombok.extern.slf4j.Slf4j; +import org.gcube.application.cms.serialization.Serialization; +import org.gcube.application.geoportal.common.model.document.accounting.User; +import org.gcube.application.geoportal.common.model.rest.ConfigurationException; +import org.gcube.application.geoportal.common.model.useCaseDescriptor.HandlerDeclaration; + +import javax.xml.bind.annotation.XmlRootElement; +import java.util.HashMap; +import java.util.List; + +@Slf4j +@ToString +public class RoleManager { + + HashMap accessMap=new HashMap<>(); + + + public RoleManager(HandlerDeclaration config) throws ConfigurationException { + log.debug("Instantiating for configuration {}",config); + List l =config.getConfiguration().get("step_access", List.class); + if(l==null|| l.isEmpty()) throw new ConfigurationException("Missing Role management in UCD"); + for (Object o : l) { + StepAccess a= Serialization.convert(o, StepAccess.class); + accessMap.put(a.getStepId(),a); + } + log.debug("Access Map is {}",accessMap); + } + + public boolean canInvokeStep(String stepID,User u) throws ConfigurationException { + if(!accessMap.containsKey(stepID)) throw new ConfigurationException("Missing step "+stepID+" access definition"); + + List roles=accessMap.get(stepID).getRoles(); + if(roles.isEmpty()) return true; + + for (String role : roles) + if (u.getRoles().contains(role)) + return true; + + return false; + } + + @XmlRootElement + @NoArgsConstructor + @AllArgsConstructor + @Getter + @Setter + @ToString(callSuper = true) + public static class StepAccess { + + public static final String STEP="STEP"; + public static final String ROLES="roles"; + + + @JsonProperty(STEP) + private String stepId; + + @JsonProperty(ROLES) + private List roles; + } +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/SimpleLifeCycleManager.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/SimpleLifeCycleManager.java new file mode 100644 index 0000000..2409646 --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/SimpleLifeCycleManager.java @@ -0,0 +1,307 @@ +package org.gcube.application.cms.plugins.implementations; + +import lombok.extern.slf4j.Slf4j; +import org.bson.Document; +import org.gcube.application.cms.implementations.faults.InvalidUserRoleException; +import org.gcube.application.cms.implementations.faults.ProjectNotFoundException; +import org.gcube.application.cms.implementations.faults.RegistrationException; +import org.gcube.application.cms.implementations.faults.UnauthorizedAccess; +import org.gcube.application.cms.plugins.IndexerPluginInterface; +import org.gcube.application.cms.plugins.LifecycleManager; +import org.gcube.application.cms.plugins.MaterializationPlugin; +import org.gcube.application.cms.plugins.faults.EventException; +import org.gcube.application.cms.plugins.faults.IndexingException; +import org.gcube.application.cms.plugins.faults.InvalidPluginRequestException; +import org.gcube.application.cms.plugins.faults.MaterializationException; +import org.gcube.application.cms.plugins.implementations.executions.GuardedStepExecution; +import org.gcube.application.cms.plugins.reports.*; +import org.gcube.application.cms.plugins.requests.BaseExecutionRequest; +import org.gcube.application.cms.plugins.requests.BaseRequest; +import org.gcube.application.cms.plugins.requests.IndexDocumentRequest; +import org.gcube.application.cms.plugins.requests.MaterializationRequest; +import org.gcube.application.geoportal.common.model.JSONPathWrapper; +import org.gcube.application.geoportal.common.model.configuration.Configuration; +import org.gcube.application.geoportal.common.model.configuration.Index; +import org.gcube.application.geoportal.common.model.document.filesets.RegisteredFileSet; +import org.gcube.application.geoportal.common.model.document.lifecycle.LifecycleInformation; +import org.gcube.application.geoportal.common.model.plugins.IndexerPluginDescriptor; +import org.gcube.application.geoportal.common.model.plugins.MaterializerPluginDescriptor; +import org.gcube.application.geoportal.common.model.plugins.OperationDescriptor; +import org.gcube.application.geoportal.common.model.rest.ConfigurationException; +import org.gcube.application.geoportal.common.model.useCaseDescriptor.HandlerDeclaration; +import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor; +import org.gcube.application.geoportal.common.utils.Files; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +@Slf4j +public class SimpleLifeCycleManager extends AbstractLifeCycleManager implements LifecycleManager { + + public static final String PLUGIN_ID="DEFAULT-SINGLE-STEP"; + + + public SimpleLifeCycleManager() { + DESCRIPTOR.setId(PLUGIN_ID); + } + + + + private static class Steps { + public static final OperationDescriptor PUBLISH = new OperationDescriptor("PUBLISH","Materialize & index project"); + + static{ + PUBLISH.setAppliableToPhases(Collections.singletonList(LifecycleInformation.CommonPhases.DRAFT_PHASE)); + } + } + + + @Override + public Configuration getCurrentConfiguration(BaseRequest req) throws ConfigurationException { + Configuration toReturn = super.getCurrentConfiguration(req); + toReturn.setIndexes(new ArrayList<>()); + + IndexerPluginInterface indexerPlugin; + indexerPlugin = (IndexerPluginInterface) pluginManager.getById("SDI-Indexer-Plugin"); + BaseRequest indexRequest = new BaseRequest(req.getUseCaseDescriptor(),req.getCaller(),req.getContext()); + + // Info on Public index + try { + indexRequest.setCallParameters(getPublicIndexParams(req)); + Index publicIndex = indexerPlugin.getIndex(indexRequest); + publicIndex.put("flag", "public"); + toReturn.getIndexes().add(publicIndex); + }catch(ConfigurationException e){ + toReturn.addErrorMessage("Unable to gather information on public GIS Centroids Index : "+e.getMessage()); + log.error("Unable to gather information on public GIS Centroids Index",e); + } + + return toReturn; + } + + + protected Document getPublicIndexParams(BaseRequest req){ + Document callParameters = new Document(); + callParameters.put("workspace",Files.fixFilename(req.getUseCaseDescriptor().getId()+req.getContext().getName())); + callParameters.put("indexName",Files.fixFilename(req.getUseCaseDescriptor().getId()+req.getContext().getName()+"_centroids")); + return callParameters; + } + + + protected Document getMaterializationParameters(BaseRequest request){ + Document params = new Document(); + String workspace = request.getUseCaseDescriptor().getId() + request.getContext().getId(); + params.put("workspace", Files.fixFilename(workspace)); + return params; + } + + + @Override + protected void registerSteps() { + setStep(new GuardedStepExecution(Steps.PUBLISH) { + @Override + protected StepExecutionReport run() throws Exception { + //Check Performed by Guarded Step Execution +// if(!theReport.getTheRequest().getDocument().getLifecycleInformation().getPhase().equals(LifecycleInformation.CommonPhases.DRAFT_PHASE)) +// throw new StepException("Document is not in "+LifecycleInformation.CommonPhases.DRAFT_PHASE+" phase"); + + // Materialize + for(MaterializationPlugin mat : getMaterializers(theReport.getTheRequest())) + theReport = materializeDocument(theReport, mat, getMaterializationParameters(theReport.getTheRequest())); + + if(theReport.getToSetLifecycleInformation().getLastOperationStatus().equals(LifecycleInformation.Status.OK)){ + // Index + for(IndexerPluginInterface indexer : getIndexers(theReport.getTheRequest())) + theReport = index(theReport,indexer,getPublicIndexParams(theReport.getTheRequest())); + // setPhase + if(theReport.getToSetLifecycleInformation().getLastOperationStatus().equals(LifecycleInformation.Status.OK)) + theReport.getToSetLifecycleInformation().setPhase("PUBLISHED"); + } + return theReport; + } + }); + } + + protected void blockNonDraft(EventExecutionReport report) throws InvalidPluginRequestException { + Boolean force = false; + try { + force = Boolean.parseBoolean(report.getTheRequest().getCallParameters().get("force").toString()); + }catch(Throwable t){} + + if(!report.getTheRequest().getDocument().getLifecycleInformation().getPhase().equals(LifecycleInformation.CommonPhases.DRAFT_PHASE) && ! force) + throw new InvalidPluginRequestException("Document is not in "+LifecycleInformation.CommonPhases.DRAFT_PHASE+" phase"); + } + + @Override + protected EventExecutionReport onInitDocument(EventExecutionReport report) throws InvalidPluginRequestException { + blockNonDraft(report); + return super.onInitDocument(report); + } + + @Override + protected EventExecutionReport onUpdateDocument(EventExecutionReport report) { + return super.onUpdateDocument(report); + } + + @Override + protected EventExecutionReport onDeleteDocument(EventExecutionReport report) throws ConfigurationException, InvalidPluginRequestException, MaterializationException, EventException { + // Block non draft only if not force + Boolean force=Boolean.parseBoolean(report.getTheRequest().getWithDefault("force","false")); + log.debug("ON DELETE for {} : force is {}",report.getTheRequest().getDocument().getId(),force); + if(!force) blockNonDraft(report); + // dematerialize all + JSONPathWrapper wrapper = new JSONPathWrapper(report.getTheRequest().getDocument().getTheDocument().toJson()); + for (String s : wrapper.getMatchingPaths("$..[?(@." + RegisteredFileSet.PAYLOADS + ")]")){ + log.info("Requesting dematerialization for {} ",s); + for(MaterializationPlugin mat : getMaterializers(report.getTheRequest())) + report = deMaterialize(report,mat,new Document("fileSetPath",s)); + if(!report.getToSetLifecycleInformation().getLastOperationStatus().equals(LifecycleInformation.Status.OK)) + break; + } + if(report.getToSetLifecycleInformation().getLastOperationStatus().equals(LifecycleInformation.Status.OK)) { + for(IndexerPluginInterface indexer : getIndexers(report.getTheRequest())) + report = deIndex(report,indexer,getPublicIndexParams(report.getTheRequest())); + } + return report; + } + + @Override + protected EventExecutionReport onDeleteFileSet(EventExecutionReport theReport) throws ConfigurationException, InvalidPluginRequestException, MaterializationException, EventException { + // dematerialize selected + blockNonDraft(theReport); + for(MaterializationPlugin mat : getMaterializers(theReport.getTheRequest())) + deMaterialize(theReport,mat, + theReport.getTheRequest().getCallParameters()); + // de index + for(IndexerPluginInterface indexer : getIndexers(theReport.getTheRequest())) + if(theReport.getToSetLifecycleInformation().getLastOperationStatus().equals(LifecycleInformation.Status.OK)) + deIndex(theReport,indexer,getPublicIndexParams(theReport.getTheRequest())); + return theReport; + } + + + @Override + protected void registerEvents() { + super.registerEvents(); + } + + + protected List getIndexers(BaseRequest request) throws ConfigurationException { + log.trace("Looking for Indexers for {}",request); + ArrayList toReturn=new ArrayList<>(); + UseCaseDescriptor desc = request.getUseCaseDescriptor(); + List indexers = desc.getHandlersByType(IndexerPluginDescriptor.INDEXER); + log.debug("Found UCD [{}] Indexers : {}",desc.getId(),indexers.size()); + for (HandlerDeclaration handlerDeclaration : indexers) + toReturn.add((IndexerPluginInterface) pluginManager.getById(handlerDeclaration.getId())); + return toReturn; + } + + protected List getMaterializers(BaseRequest request) throws ConfigurationException { + log.trace("Looking for materializers for {}",request); + ArrayList toReturn=new ArrayList<>(); + UseCaseDescriptor desc = request.getUseCaseDescriptor(); + List materializers = desc.getHandlersByType(MaterializerPluginDescriptor.MATERIALIZER); + log.debug("Found UCD [{}] Materializers : {}",desc.getId(),materializers.size()); + for (HandlerDeclaration handlerDeclaration : materializers) { + toReturn.add((MaterializationPlugin) pluginManager.getById(handlerDeclaration.getId())); + } + return toReturn; + } + + protected T deIndex(T report, IndexerPluginInterface indexer, Document parameters) throws InvalidPluginRequestException { + BaseExecutionRequest request = report.getTheRequest(); + IndexDocumentRequest indexRequest = new IndexDocumentRequest( + request.getUseCaseDescriptor(),request.getCaller(), request.getContext(),request.getDocument()); + + indexRequest.setCallParameters(parameters); + IndexDocumentReport indexReport = indexer.deindex(indexRequest); + + return handleReport(indexReport,report); + + } + + protected T deMaterialize(T report, MaterializationPlugin plugin, Document parameters) throws InvalidPluginRequestException, MaterializationException { + BaseExecutionRequest request = report.getTheRequest(); + MaterializationRequest matReq = + new MaterializationRequest(request.getUseCaseDescriptor(),request.getCaller(), request.getContext(), request.getDocument()); + + Document params = new Document(); + String workspace = request.getUseCaseDescriptor().getId() + request.getContext().getId(); + params.put("workspace", Files.fixFilename(workspace)); + + matReq.setCallParameters(params); + MaterializationReport matRep = plugin.dematerialize(matReq); + + return handleReport(matRep,report); + } + + protected T index(T report, IndexerPluginInterface indexer, Document parameters) throws InvalidPluginRequestException { + BaseExecutionRequest request = report.getTheRequest(); + IndexDocumentRequest indexRequest = new IndexDocumentRequest( + request.getUseCaseDescriptor(),request.getCaller(), request.getContext(),request.getDocument()); + + indexRequest.setCallParameters(parameters); + + IndexDocumentReport indexReport = null; + try { + indexRequest.setCallParameters(evaluateAdditionalIndexParameters(indexRequest)); + indexReport = indexer.index(indexRequest); + }catch (IndexingException e){ + log.error("Unable to serve index request.",e); + indexReport = new IndexDocumentReport(indexRequest); + indexReport.setStatus(Report.Status.ERROR); + indexReport.setMessages(new ArrayList<>()); + indexReport.getMessages().add("Unable to evaluate centroids : "+e.getMessage()); + } + return handleReport(indexReport,report); + + } + + protected Document evaluateAdditionalIndexParameters(IndexDocumentRequest request) throws IndexingException {return request.getCallParameters();} + + + protected T materializeDocument(T report,MaterializationPlugin plugin,Document parameters) throws InvalidPluginRequestException, MaterializationException { + BaseExecutionRequest request = report.getTheRequest(); + MaterializationRequest matReq = + new MaterializationRequest(request.getUseCaseDescriptor(),request.getCaller(), request.getContext(), request.getDocument()); + + matReq.setCallParameters(parameters); + MaterializationReport matRep = plugin.materialize(matReq); + + return handleReport(matRep,report); + } + + + private T handleReport(DocumentHandlingReport toHandle, T toUpdate){ + toUpdate.setResultingDocument(toHandle.getResultingDocument()); + LifecycleInformation info = toUpdate.getToSetLifecycleInformation(); + switch(toHandle.getStatus()){ + case OK : { + info.setLastOperationStatus(LifecycleInformation.Status.OK); + if(toHandle instanceof IndexDocumentReport) + toUpdate.setToSetIdentificationReferences(((IndexDocumentReport)toHandle).getToSetIdentificationReferences()); + // Propagate changes for further processings + toUpdate.getTheRequest().getDocument().setTheDocument(toHandle.getResultingDocument()); + toUpdate.setToSetLifecycleInformation(toHandle.getToSetLifecycleInformation()); + +// if(toHandle instanceof MaterializationReport) +// toUpdate.setToSetSpatialReference(((IndexDocumentReport)toHandle).getToSetSpatialReference()); + break; + } + case ERROR : { + info.setLastOperationStatus(LifecycleInformation.Status.ERROR); + toHandle.getMessages().forEach(s -> info.addErrorMessage(s)); + break; + } + case WARNING : { + info.setLastOperationStatus(LifecycleInformation.Status.WARNING); + toHandle.getMessages().forEach(s -> info.addWarningMessage(s)); + break; + } + } + return toUpdate; + } + +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/executions/GuardedEventManager.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/executions/GuardedEventManager.java new file mode 100644 index 0000000..eabc58c --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/executions/GuardedEventManager.java @@ -0,0 +1,16 @@ +package org.gcube.application.cms.plugins.implementations.executions; + +import lombok.NonNull; +import lombok.extern.slf4j.Slf4j; +import org.gcube.application.cms.plugins.reports.EventExecutionReport; +import org.gcube.application.cms.plugins.requests.EventExecutionRequest; +import org.gcube.application.geoportal.common.model.plugins.OperationDescriptor; + +@Slf4j +public abstract class GuardedEventManager extends GuardedExecution{ + + + public GuardedEventManager(@NonNull OperationDescriptor op) { + super(op); + } +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/executions/GuardedExecution.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/executions/GuardedExecution.java new file mode 100644 index 0000000..6d73209 --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/executions/GuardedExecution.java @@ -0,0 +1,68 @@ +package org.gcube.application.cms.plugins.implementations.executions; + +import lombok.Getter; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.gcube.application.cms.plugins.faults.InsufficientPrivileges; +import org.gcube.application.cms.plugins.faults.StepException; +import org.gcube.application.cms.plugins.reports.DocumentHandlingReport; +import org.gcube.application.cms.plugins.requests.BaseExecutionRequest; +import org.gcube.application.geoportal.common.model.plugins.OperationDescriptor; +import org.gcube.application.geoportal.common.model.rest.ConfigurationException; +import org.gcube.application.geoportal.common.model.useCaseDescriptor.HandlerDeclaration; + + +@Slf4j +@RequiredArgsConstructor +public abstract class GuardedExecution { + + @Getter + protected T result = null; + + + @NonNull + @Getter + private OperationDescriptor op; + + + protected T theReport; + + protected void checks() throws ConfigurationException, InsufficientPrivileges { + if(theReport.getTheRequest()==null) throw new RuntimeException("Unexpected state : request cannot be null"); + + // Check document phase + if(op.getAppliableToPhases()!=null&&!op.getAppliableToPhases().isEmpty()) { + String currentPhase = theReport.getTheRequest().getDocument().getLifecycleInformation().getPhase(); + if(!op.getAppliableToPhases().contains(currentPhase)) + new StepException("Document must be in one of the following phases : "+ op.getAppliableToPhases()); + } + } + + + public T execute() throws Exception { + log.trace("Executing {} ",theReport.getTheRequest()); + + checks(); + + result = run(); + log.trace("Report is {} ",theReport); + return result; + } + + public T getResult() { + return result; + } + protected abstract T run() throws Exception; + + public GuardedExecution setTheReport(T theReport) { + this.theReport = theReport; + return this; + } + + protected HandlerDeclaration config=null; + + public void setHandlerConfiguration(HandlerDeclaration config){ + this.config=config; + } +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/executions/GuardedStepExecution.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/executions/GuardedStepExecution.java new file mode 100644 index 0000000..208c9e0 --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/executions/GuardedStepExecution.java @@ -0,0 +1,26 @@ +package org.gcube.application.cms.plugins.implementations.executions; + +import lombok.NonNull; +import org.gcube.application.cms.plugins.faults.InsufficientPrivileges; +import org.gcube.application.cms.plugins.implementations.RoleManager; +import org.gcube.application.cms.plugins.reports.StepExecutionReport; +import org.gcube.application.cms.plugins.requests.StepExecutionRequest; +import org.gcube.application.geoportal.common.model.plugins.OperationDescriptor; +import org.gcube.application.geoportal.common.model.rest.ConfigurationException; + +public abstract class GuardedStepExecution extends GuardedExecution{ + + + public GuardedStepExecution(@NonNull OperationDescriptor op) { + super(op); + } + + @Override + protected void checks() throws ConfigurationException, InsufficientPrivileges { + super.checks(); + RoleManager r = new RoleManager(config); + if(!r.canInvokeStep(theReport.getTheRequest().getStep(),theReport.getTheRequest().getCaller())) + throw new InsufficientPrivileges("User is not allowed to execute "+theReport.getTheRequest().getStep()); + + } +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/ComparableVersion.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/model/ComparableVersion.java similarity index 98% rename from geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/ComparableVersion.java rename to cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/model/ComparableVersion.java index 56a340d..9682bd1 100644 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/ComparableVersion.java +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/model/ComparableVersion.java @@ -1,4 +1,4 @@ -package org.gcube.application.geoportal.common.model.document; +package org.gcube.application.cms.plugins.model; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -22,14 +22,7 @@ package org.gcube.application.geoportal.common.model.document; import lombok.*; import java.math.BigInteger; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Deque; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Properties; +import java.util.*; /** *

diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/model/PluginDescriptor.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/model/PluginDescriptor.java deleted file mode 100644 index b05ef30..0000000 --- a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/model/PluginDescriptor.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.gcube.application.cms.plugins.model; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; -import org.gcube.application.geoportal.common.model.document.ComparableVersion; - -@Data -@RequiredArgsConstructor -@AllArgsConstructor -public class PluginDescriptor { - - public static class BaseTypes{ - public static final String LIFECYCLE_MANAGER="LifecycleManagement"; - } - - @NonNull - private String id; - @NonNull - private String type; - private String label; - private String description; - private ComparableVersion version; - -} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/reports/DocumentHandlingReport.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/reports/DocumentHandlingReport.java new file mode 100644 index 0000000..6f1945a --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/reports/DocumentHandlingReport.java @@ -0,0 +1,91 @@ +package org.gcube.application.cms.plugins.reports; + +import com.fasterxml.jackson.core.JsonProcessingException; +import lombok.Data; +import lombok.NonNull; +import lombok.extern.slf4j.Slf4j; +import org.bson.Document; +import org.gcube.application.cms.plugins.faults.InvalidPluginRequestException; +import org.gcube.application.cms.plugins.faults.PluginExecutionException; +import org.gcube.application.cms.plugins.requests.BaseExecutionRequest; +import org.gcube.application.geoportal.common.model.document.Project; +import org.gcube.application.geoportal.common.model.document.identification.IdentificationReference; +import org.gcube.application.geoportal.common.model.document.lifecycle.LifecycleInformation; + +import java.util.ArrayList; +import java.util.List; + + +@Data + +@Slf4j +public class DocumentHandlingReport extends Report{ + + @NonNull + T theRequest; + Document resultingDocument; + LifecycleInformation toSetLifecycleInformation; + + protected List toSetIdentificationReferences=null; + + public DocumentHandlingReport addIdentificationReference(IdentificationReference toAdd){ + if(toSetIdentificationReferences == null) toSetIdentificationReferences = new ArrayList<>(); + toSetIdentificationReferences.add(toAdd); + return this; + } + + + public DocumentHandlingReport(@NonNull T theRequest) throws InvalidPluginRequestException { + theRequest.validate(); + this.theRequest = theRequest; + this.setStatus(Status.OK); + toSetLifecycleInformation=theRequest.getDocument().getLifecycleInformation(); + resultingDocument = theRequest.getDocument().getTheDocument(); + } + + @Override + public void validate() throws PluginExecutionException { + super.validate(); + if (resultingDocument==null) { + log.warn("NULL resulting document in report {} ", this); + throw new PluginExecutionException("Invalid report : Resulting document cannot be null"); + } + if(toSetLifecycleInformation == null) { + log.warn("NULL lifecycleinformation in report {} ",this); + throw new PluginExecutionException("Invalid report : Lifecycle information cannot be null"); + } + } + + public Project prepareResult() throws JsonProcessingException, PluginExecutionException { + log.trace("Preparing document ID {} from report ... ",theRequest.getDocument().getId()); + this.validate(); + + Project toReturn = theRequest.getDocument(); + toReturn.setTheDocument(resultingDocument); + toReturn.setLifecycleInformation(toSetLifecycleInformation); + + // Force Report status into info + log.trace("Report status is {} ",getStatus()); + LifecycleInformation info = toReturn.getLifecycleInformation(); + switch (getStatus()){ + case ERROR: { + info.setLastOperationStatus(LifecycleInformation.Status.ERROR); + this.getMessages().forEach(s -> info.addErrorMessage(s)); + break; + } + case WARNING:{ + info.setLastOperationStatus(LifecycleInformation.Status.WARNING); + this.getMessages().forEach(s -> info.addWarningMessage(s)); + break; + } + case OK: { + if(info.getLastOperationStatus()==null) + info.setLastOperationStatus(LifecycleInformation.Status.OK); + break; + } + } + if(toSetIdentificationReferences!=null) + toReturn.setIdentificationReferences(toSetIdentificationReferences); + return toReturn; + } +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/reports/EventExecutionReport.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/reports/EventExecutionReport.java new file mode 100644 index 0000000..421ac03 --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/reports/EventExecutionReport.java @@ -0,0 +1,34 @@ +package org.gcube.application.cms.plugins.reports; + +import lombok.ToString; +import lombok.extern.slf4j.Slf4j; +import org.gcube.application.cms.plugins.faults.InvalidPluginRequestException; +import org.gcube.application.cms.plugins.requests.EventExecutionRequest; +import org.gcube.application.geoportal.common.model.document.lifecycle.LifecycleInformation; + +@ToString(callSuper = true) +@Slf4j +public class EventExecutionReport extends DocumentHandlingReport{ + + public EventExecutionReport(EventExecutionRequest req) throws InvalidPluginRequestException { + super(req); + try{ + if(theRequest.getDocument().getLifecycleInformation()!=null) + this.setToSetLifecycleInformation(theRequest.getDocument().getLifecycleInformation().cleanState()); + else theRequest.getDocument().setLifecycleInformation(new LifecycleInformation().cleanState()); + }catch(Throwable t){ + log.warn("Cannot to clean state for lifecycle information {} in {} : {}", + theRequest.getDocument().getLifecycleInformation(), + theRequest.getDocument().getProfileID(), + theRequest.getDocument().getId(), + t); + } + this.getToSetLifecycleInformation().setLastOperationStatus(LifecycleInformation.Status.OK); + } + + + @Override + public void setToSetLifecycleInformation(LifecycleInformation toSetLifecycleInformation) { + } + +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/reports/ExecutionReport.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/reports/ExecutionReport.java deleted file mode 100644 index ea0d69e..0000000 --- a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/reports/ExecutionReport.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.gcube.application.cms.plugins.reports; - -import lombok.Data; -import org.gcube.application.cms.plugins.requests.StepExecutionRequest; -import org.gcube.application.geoportal.common.model.document.ProfiledDocument; - -@Data -public class ExecutionReport extends Report{ - - StepExecutionRequest request; - - ProfiledDocument result; -} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/reports/IndexDocumentReport.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/reports/IndexDocumentReport.java new file mode 100644 index 0000000..b8c680f --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/reports/IndexDocumentReport.java @@ -0,0 +1,27 @@ +package org.gcube.application.cms.plugins.reports; + +import lombok.Getter; +import lombok.NonNull; +import lombok.Setter; +import org.gcube.application.cms.plugins.faults.InvalidPluginRequestException; +import org.gcube.application.cms.plugins.requests.IndexDocumentRequest; + +@Getter +@Setter +public class IndexDocumentReport extends DocumentHandlingReport { + +// protected List toSetIndexReferences=new ArrayList<>(); + + + public IndexDocumentReport(@NonNull IndexDocumentRequest theRequest) throws InvalidPluginRequestException { + super(theRequest); + } + +// @Override +// public Project prepareResult() throws JsonProcessingException, PluginExecutionException { +// Project toReturn= super.prepareResult(); +// if(toSetSpatialReference != null) toReturn.setSpatialReference(toSetSpatialReference); +// if(toSetTemporalReference != null) toReturn.setTemporalReference(toSetTemporalReference); +// return toReturn; +// } +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/reports/InitializationReport.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/reports/InitializationReport.java index 58638ae..f4f86f5 100644 --- a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/reports/InitializationReport.java +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/reports/InitializationReport.java @@ -1,6 +1,11 @@ package org.gcube.application.cms.plugins.reports; -public class InitializationReport { +import lombok.NoArgsConstructor; +@NoArgsConstructor +public class InitializationReport extends Report{ + public InitializationReport(Status status, String... messages) { + super(status, messages); + } } diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/reports/MaterializationReport.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/reports/MaterializationReport.java new file mode 100644 index 0000000..d712617 --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/reports/MaterializationReport.java @@ -0,0 +1,13 @@ +package org.gcube.application.cms.plugins.reports; + +import lombok.NonNull; +import org.gcube.application.cms.plugins.faults.InvalidPluginRequestException; +import org.gcube.application.cms.plugins.requests.MaterializationRequest; + + +public class MaterializationReport extends DocumentHandlingReport{ + + public MaterializationReport(@NonNull MaterializationRequest theRequest) throws InvalidPluginRequestException { + super(theRequest); + } +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/reports/Report.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/reports/Report.java index 58b9755..16b3f74 100644 --- a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/reports/Report.java +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/reports/Report.java @@ -1,10 +1,16 @@ package org.gcube.application.cms.plugins.reports; -import lombok.Data; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.gcube.application.cms.plugins.faults.PluginExecutionException; +import java.util.ArrayList; import java.util.List; -@Data +@Getter +@Setter +@NoArgsConstructor public class Report { public static enum Status { @@ -13,4 +19,24 @@ public class Report { private Status status; private List messages; + + public Report(Status status,String ... messages) { + this.status = status; + this.messages=new ArrayList<>(); + for (String s : messages) + this.messages.add(s); + } + + public Report putMessage(String msg){ + if(messages==null)messages=new ArrayList<>(); + messages.add(msg); + return this; + } + + public void validate()throws PluginExecutionException { + if(status == null) throw new PluginExecutionException("Status is null"); + if(!status.equals(Status.OK)) + if(messages==null || messages.isEmpty()) throw new PluginExecutionException("Messages are mandatory for status != OK "); + } + } diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/reports/StepExecutionReport.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/reports/StepExecutionReport.java new file mode 100644 index 0000000..38cd2c5 --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/reports/StepExecutionReport.java @@ -0,0 +1,55 @@ +package org.gcube.application.cms.plugins.reports; + +import com.fasterxml.jackson.core.JsonProcessingException; +import lombok.Getter; +import lombok.NonNull; +import lombok.Setter; +import lombok.ToString; +import org.gcube.application.cms.plugins.faults.InvalidPluginRequestException; +import org.gcube.application.cms.plugins.faults.PluginExecutionException; +import org.gcube.application.cms.plugins.requests.EventExecutionRequest; +import org.gcube.application.cms.plugins.requests.StepExecutionRequest; +import org.gcube.application.geoportal.common.model.document.Project; + +import java.util.ArrayList; +import java.util.List; + +@Getter +@Setter +@ToString +public class StepExecutionReport extends DocumentHandlingReport{ + + public StepExecutionReport(@NonNull StepExecutionRequest theRequest) throws InvalidPluginRequestException { + + super(theRequest); + this.getToSetLifecycleInformation().cleanState(); + this.getToSetLifecycleInformation().setLastInvokedStep(theRequest.getStep()); + } + + List toTriggerEvents; + + List cascadeSteps; + + + + + public StepExecutionReport addToTriggerEvent(EventExecutionRequest req){ + if(toTriggerEvents==null) toTriggerEvents = new ArrayList<>(); + toTriggerEvents.add(req); + return this; + } + + + public StepExecutionReport addCascadeStep(StepExecutionRequest req){ + if(cascadeSteps == null ) cascadeSteps = new ArrayList<>(); + cascadeSteps.add(req); + return this; + } + + @Override + public Project prepareResult() throws JsonProcessingException, PluginExecutionException { + Project toReturn= super.prepareResult(); + + return toReturn; + } +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/requests/BaseExecutionRequest.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/requests/BaseExecutionRequest.java new file mode 100644 index 0000000..dfcf190 --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/requests/BaseExecutionRequest.java @@ -0,0 +1,31 @@ +package org.gcube.application.cms.plugins.requests; + +import lombok.Getter; +import lombok.NonNull; +import lombok.Setter; +import lombok.ToString; +import org.gcube.application.cms.plugins.faults.InvalidPluginRequestException; +import org.gcube.application.geoportal.common.model.document.Project; +import org.gcube.application.geoportal.common.model.document.accounting.Context; +import org.gcube.application.geoportal.common.model.document.accounting.User; +import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor; + +@Getter +@Setter +@ToString(callSuper = true) +public class BaseExecutionRequest extends BaseRequest{ + + + Project document; + + public BaseExecutionRequest(@NonNull UseCaseDescriptor useCaseDescriptor, @NonNull User caller, @NonNull Context context, Project document) { + super(useCaseDescriptor, caller, context); + this.document = document; + } + + public BaseExecutionRequest validate() throws InvalidPluginRequestException { + super.validate(); + if(document==null) throw new InvalidPluginRequestException("Document cannot be null"); + return this; + } +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/requests/BaseRequest.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/requests/BaseRequest.java new file mode 100644 index 0000000..1e2191d --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/requests/BaseRequest.java @@ -0,0 +1,54 @@ +package org.gcube.application.cms.plugins.requests; + +import lombok.*; +import org.bson.Document; +import org.gcube.application.cms.plugins.faults.InvalidPluginRequestException; +import org.gcube.application.cms.serialization.Serialization; +import org.gcube.application.geoportal.common.model.document.accounting.Context; +import org.gcube.application.geoportal.common.model.document.accounting.User; +import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor; + +@Getter +@Setter +@ToString(callSuper = true) +@RequiredArgsConstructor +public class BaseRequest { + + @NonNull + UseCaseDescriptor useCaseDescriptor; + @NonNull + User caller; + @NonNull + Context context; + + + Document callParameters; + + public final String getMandatory(String param) throws InvalidPluginRequestException { + return getMandatory(param,callParameters); + } + + public final String getWithDefault(String param,String defaultValue) { + try{ + return getMandatory(param,callParameters); + }catch (InvalidPluginRequestException e){ + return defaultValue; + } + } + + public static final String getMandatory(String param,Document params) throws InvalidPluginRequestException { + if(params==null || params.isEmpty()|| !params.containsKey(param)) throw new InvalidPluginRequestException("Missing mandatory parameter "+param); + return Serialization.convert(params.get(param),String.class); + } + + public BaseRequest validate() throws InvalidPluginRequestException { + if(useCaseDescriptor ==null)throw new InvalidPluginRequestException("UseCaseDescriptor cannot be null "); + return this; + } + + public BaseRequest setParameter(String key,Object value){ + if(callParameters==null) callParameters=new Document(); + callParameters.put(key, value); + return this; + } +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/requests/EventExecutionRequest.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/requests/EventExecutionRequest.java new file mode 100644 index 0000000..25ec153 --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/requests/EventExecutionRequest.java @@ -0,0 +1,32 @@ +package org.gcube.application.cms.plugins.requests; + +import lombok.Getter; +import lombok.NonNull; +import lombok.Setter; +import lombok.ToString; +import org.gcube.application.geoportal.common.model.document.Project; +import org.gcube.application.geoportal.common.model.document.accounting.Context; +import org.gcube.application.geoportal.common.model.document.accounting.User; +import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor; + +@Getter +@Setter +@ToString(callSuper = true) +public class EventExecutionRequest extends BaseExecutionRequest{ + + public static class Events{ + public static final String ON_INIT_DOCUMENT="INIT_DOCUMENT"; + public static final String ON_UPDATE_DOCUMENT="UPDATE_DOCUMENT"; + public static final String ON_DELETE_DOCUMENT="DELETE_DOCUMENT"; + public static final String ON_DELETE_FILESET="DELETE_FILESET"; + } + + public EventExecutionRequest(@NonNull UseCaseDescriptor useCaseDescriptor, @NonNull User caller, @NonNull Context context, Project document, String event) { + super(useCaseDescriptor, caller, context, document); + this.event = event; + } + + String event; + + +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/requests/IndexDocumentRequest.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/requests/IndexDocumentRequest.java new file mode 100644 index 0000000..4321c41 --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/requests/IndexDocumentRequest.java @@ -0,0 +1,15 @@ +package org.gcube.application.cms.plugins.requests; + +import lombok.NonNull; +import lombok.ToString; +import org.gcube.application.geoportal.common.model.document.Project; +import org.gcube.application.geoportal.common.model.document.accounting.Context; +import org.gcube.application.geoportal.common.model.document.accounting.User; +import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor; + +@ToString(callSuper = true) +public class IndexDocumentRequest extends BaseExecutionRequest{ + public IndexDocumentRequest(@NonNull UseCaseDescriptor useCaseDescriptor, @NonNull User caller, @NonNull Context context, Project document) { + super(useCaseDescriptor, caller, context, document); + } +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/requests/MaterializationRequest.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/requests/MaterializationRequest.java new file mode 100644 index 0000000..42c1f3c --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/requests/MaterializationRequest.java @@ -0,0 +1,15 @@ +package org.gcube.application.cms.plugins.requests; + +import lombok.NonNull; +import lombok.ToString; +import org.gcube.application.geoportal.common.model.document.Project; +import org.gcube.application.geoportal.common.model.document.accounting.Context; +import org.gcube.application.geoportal.common.model.document.accounting.User; +import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor; + +@ToString(callSuper = true) +public class MaterializationRequest extends BaseExecutionRequest{ + public MaterializationRequest(@NonNull UseCaseDescriptor useCaseDescriptor, @NonNull User caller, @NonNull Context context, Project document) { + super(useCaseDescriptor, caller, context, document); + } +} diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/requests/StepExecutionRequest.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/requests/StepExecutionRequest.java index 41fef59..6cf8376 100644 --- a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/requests/StepExecutionRequest.java +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/requests/StepExecutionRequest.java @@ -1,28 +1,25 @@ package org.gcube.application.cms.plugins.requests; -import lombok.Data; -import org.bson.Document; -import org.gcube.application.geoportal.common.model.document.ProfiledDocument; -import org.gcube.application.geoportal.common.model.profile.Profile; +import lombok.Getter; +import lombok.NonNull; +import lombok.Setter; +import lombok.ToString; +import org.gcube.application.geoportal.common.model.document.Project; +import org.gcube.application.geoportal.common.model.document.accounting.Context; +import org.gcube.application.geoportal.common.model.document.accounting.User; +import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor; -@Data -public class StepExecutionRequest { +@Getter +@Setter +@ToString(callSuper = true) +public class StepExecutionRequest extends BaseExecutionRequest{ - public static class Steps{ - public static final String ON_INIT_DOCUMENT="@@@INIT_DOCUMENT@@"; - public static final String ON_UPDATE_DOCUMENT="@@@UPDATE_DOCUMENT@@"; - public static final String ON_DELETE_DOCUMENT="@@@DELETE_DOCUMENT@@"; - - public static final String ON_MATERIALIZE_DOCUMENT="@@@MATERIALIZE_DOCUMENT@@"; - public static final String ON_DEMATERIALIZE_DOCUMENT="@@@DEMATERIALIZE_DOCUMENT@@"; - - public static final String ON_INDEX_DOCUMENT="@@@INDEX_DOCUMENT@@"; - public static final String ON_DEINDEX_DOCUMENT="@@@DEINDEX_DOCUMENT@@"; + public StepExecutionRequest(@NonNull UseCaseDescriptor useCaseDescriptor, @NonNull User caller, @NonNull Context context, Project document, String step) { + super(useCaseDescriptor, caller, context, document); + this.step = step; } - - Profile profile; - ProfiledDocument document; String step; - Document callParameters; + + } diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/serialization/JacksonProvider.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/serialization/JacksonProvider.java new file mode 100644 index 0000000..7e74818 --- /dev/null +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/serialization/JacksonProvider.java @@ -0,0 +1,39 @@ +package org.gcube.application.cms.serialization; + +import com.jayway.jsonpath.Configuration; +import com.jayway.jsonpath.Option; +import com.jayway.jsonpath.spi.json.JacksonJsonProvider; +import com.jayway.jsonpath.spi.json.JsonProvider; +import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider; +import com.jayway.jsonpath.spi.mapper.MappingProvider; +import org.gcube.application.geoportal.common.JSONSerializationProvider; + +import java.util.EnumSet; +import java.util.Set; + +public class JacksonProvider implements JSONSerializationProvider { + + + @Override + public void setJSONWrapperDefaults() { + Configuration.setDefaults(new Configuration.Defaults() { + private JsonProvider jacksonProvider = new JacksonJsonProvider(Serialization.mapper); + + private final MappingProvider mappingProvider = new JacksonMappingProvider(Serialization.mapper); + @Override + public JsonProvider jsonProvider() { + return jacksonProvider; + } + + @Override + public Set

ProxyBuilder> + customModel(String profileID, Class

customModel ) { + ProjectsInterfacePlugin plugin=new ProjectsInterfacePlugin(profileID); + plugin.setProfiledModel(customModel); + return new ProxyBuilderImpl>(plugin); + } + + public static

> ProxyBuilder + customModel(String profileID, Class

customModel , Class customClient) { + ProjectsInterfacePlugin plugin=new ProjectsInterfacePlugin(profileID); + plugin.setProfiledModel(customModel); + plugin.setCustomClientImplementation(customClient); + return new ProxyBuilderImpl(plugin); } - @Override public Exception convert(Exception fault, ProxyConfig config) { @@ -68,5 +76,31 @@ public abstract class GeoportalAbstractPlugin implements Plugin{ } - + + + //******** LEGACY + public static ProxyBuilder concessioni() { + return new ProxyBuilderImpl(concessioni_plugin); + } + + public static ProxyBuilder mongoConcessioni(){ + return new ProxyBuilderImpl(mongo_concessioni_plugin); + } + + public static ProxyBuilder statefulMongoConcessioni(){ + return new ProxyBuilderImpl(stateful_mongo_concessioni_plugin); + } + + //** LEGACY + + @Deprecated + private static ConcessioniPlugin concessioni_plugin=new ConcessioniPlugin(); + @Deprecated + private static MongoConcessioniPlugin mongo_concessioni_plugin=new MongoConcessioniPlugin(); + @Deprecated + private static StatefulMongoConcessioniPlugin stateful_mongo_concessioni_plugin=new StatefulMongoConcessioniPlugin(); + + + + } diff --git a/geoportal-client/src/main/java/org/gcube/application/geoportal/client/plugins/ProjectsInterfacePlugin.java b/geoportal-client/src/main/java/org/gcube/application/geoportal/client/plugins/ProjectsInterfacePlugin.java new file mode 100644 index 0000000..9e99fde --- /dev/null +++ b/geoportal-client/src/main/java/org/gcube/application/geoportal/client/plugins/ProjectsInterfacePlugin.java @@ -0,0 +1,68 @@ +package org.gcube.application.geoportal.client.plugins; + +import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.gcube.application.geoportal.client.DefaultDocumentsClient; +import org.gcube.application.geoportal.client.utils.Serialization; +import org.gcube.application.geoportal.common.model.document.Project; +import org.gcube.application.geoportal.common.rest.InterfaceConstants; +import org.gcube.application.geoportal.common.rest.Projects; +import org.gcube.common.calls.jaxrs.GcubeService; +import org.gcube.common.calls.jaxrs.TargetFactory; +import org.gcube.common.clients.config.ProxyConfig; +import org.gcube.common.clients.delegates.ProxyDelegate; +import org.w3c.dom.Node; + +import javax.ws.rs.client.WebTarget; +import javax.xml.namespace.QName; +import javax.xml.transform.dom.DOMResult; +import javax.xml.ws.EndpointReference; + +@Slf4j +@RequiredArgsConstructor +public class ProjectsInterfacePlugin extends GeoportalAbstractPlugin>{ + + @NonNull + private String profileID; + + @Setter + private Class customClientImplementation= (Class) DefaultDocumentsClient.class; + + @Setter + private Class

profiledModel= (Class

) Project.class; + + @Override + public Exception convert(Exception fault, ProxyConfig config) { + return fault; + } + + @SneakyThrows //no such constructor + @Override + public Projects

newProxy(ProxyDelegate delegate) { + return customClientImplementation.getConstructor(ProxyDelegate.class,String.class,Class.class). + newInstance(delegate,profileID,profiledModel); + } + + @Override + public WebTarget resolve(EndpointReference address, ProxyConfig config) throws Exception { + DOMResult result = new DOMResult(); + address.writeTo(result); + Node node =result.getNode(); + Node child=node.getFirstChild(); + String addressString = child.getTextContent(); + GcubeService service = GcubeService.service(). + withName(new QName(InterfaceConstants.NAMESPACE,InterfaceConstants.Methods.PROJECTS)). + andPath(InterfaceConstants.Methods.PROJECTS); + WebTarget target = TargetFactory.stubFor(service).at(addressString); + //Registering provider + JacksonJaxbJsonProvider provider = new JacksonJaxbJsonProvider(); + provider.setMapper(Serialization.mapper); + target.register(provider); + + return target; + } +} diff --git a/geoportal-client/src/main/java/org/gcube/application/geoportal/client/plugins/UCDPlugin.java b/geoportal-client/src/main/java/org/gcube/application/geoportal/client/plugins/UCDPlugin.java new file mode 100644 index 0000000..c75b214 --- /dev/null +++ b/geoportal-client/src/main/java/org/gcube/application/geoportal/client/plugins/UCDPlugin.java @@ -0,0 +1,41 @@ +package org.gcube.application.geoportal.client.plugins; + +import org.gcube.application.geoportal.client.UseCaseDescriptors; +import org.gcube.application.geoportal.common.rest.InterfaceConstants; +import org.gcube.application.geoportal.common.rest.UseCaseDescriptorsI; +import org.gcube.common.calls.jaxrs.GcubeService; +import org.gcube.common.calls.jaxrs.TargetFactory; +import org.gcube.common.clients.config.ProxyConfig; +import org.gcube.common.clients.delegates.ProxyDelegate; +import org.w3c.dom.Node; + +import javax.ws.rs.client.WebTarget; +import javax.xml.namespace.QName; +import javax.xml.transform.dom.DOMResult; +import javax.xml.ws.EndpointReference; + +public class UCDPlugin extends GeoportalAbstractPlugin{ + + @Override + public Exception convert(Exception fault, ProxyConfig config) { + return super.convert(fault, config); + } + + @Override + public UseCaseDescriptorsI newProxy(ProxyDelegate proxyDelegate) { + return new UseCaseDescriptors(proxyDelegate); + } + + @Override + public WebTarget resolve(EndpointReference endpointReference, ProxyConfig proxyConfig) throws Exception { + DOMResult result = new DOMResult(); + endpointReference.writeTo(result); + Node node =result.getNode(); + Node child=node.getFirstChild(); + String addressString = child.getTextContent(); + GcubeService service = GcubeService.service(). + withName(new QName(InterfaceConstants.NAMESPACE,InterfaceConstants.Methods.UCD)). + andPath(InterfaceConstants.Methods.UCD); + return TargetFactory.stubFor(service).at(addressString); + } +} diff --git a/geoportal-client/src/main/java/org/gcube/application/geoportal/client/utils/ConcessioniUtils.java b/geoportal-client/src/main/java/org/gcube/application/geoportal/client/utils/ConcessioniUtils.java index 8a8c951..c21353e 100644 --- a/geoportal-client/src/main/java/org/gcube/application/geoportal/client/utils/ConcessioniUtils.java +++ b/geoportal-client/src/main/java/org/gcube/application/geoportal/client/utils/ConcessioniUtils.java @@ -1,15 +1,12 @@ package org.gcube.application.geoportal.client.utils; -import com.sun.corba.se.spi.orbutil.threadpool.Work; import lombok.extern.slf4j.Slf4j; import org.gcube.application.geoportal.common.model.legacy.*; import org.gcube.application.geoportal.common.model.rest.AddSectionToConcessioneRequest; import org.gcube.application.geoportal.common.rest.MongoConcessioni; -import org.gcube.application.geoportal.common.rest.TempFile; import org.gcube.application.geoportal.common.utils.StorageUtils; import java.io.IOException; -import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; diff --git a/geoportal-client/src/main/java/org/gcube/application/geoportal/client/utils/Serialization.java b/geoportal-client/src/main/java/org/gcube/application/geoportal/client/utils/Serialization.java index e4f45ef..481ab7c 100644 --- a/geoportal-client/src/main/java/org/gcube/application/geoportal/client/utils/Serialization.java +++ b/geoportal-client/src/main/java/org/gcube/application/geoportal/client/utils/Serialization.java @@ -1,41 +1,127 @@ package org.gcube.application.geoportal.client.utils; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.*; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.vdurmont.semver4j.Semver; +import org.bson.Document; +import org.bson.types.ObjectId; + import java.io.IOException; import java.io.InputStream; import java.time.format.DateTimeFormatter; import java.util.Iterator; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; - public class Serialization { -public static final DateTimeFormatter FULL_FORMATTER=DateTimeFormatter.ofPattern("uuuuMMdd_HH-mm-ss"); - - public static ObjectMapper mapper; - - static { - mapper=new ObjectMapper(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false); - mapper.registerModule(new JavaTimeModule()); - } - - public static T read(String jsonString,Class clazz) throws JsonProcessingException, IOException { - return mapper.readerFor(clazz).readValue(jsonString); - } - - - public static String write(Object obj) throws JsonProcessingException, IOException { - return mapper.writeValueAsString(obj); - } + public static final DateTimeFormatter FULL_FORMATTER=DateTimeFormatter.ofPattern("uuuuMMdd_HH-mm-ss"); + + public static ObjectMapper mapper; + + static { + mapper=new ObjectMapper(); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false); + mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); + mapper.registerModule(new JavaTimeModule()); + + SimpleModule s=new SimpleModule(); + s.addDeserializer(ObjectId.class,new ObjectIdDeserializer()); + s.addSerializer(ObjectId.class,new ObjectIdSerializer()); + + s.addDeserializer(Semver.class,new SemverDeserializer()); + s.addSerializer(Semver.class,new SemverSerializer()); + + + mapper.registerModule(s); + } + + public static T read(String jsonString,Class clazz) throws JsonProcessingException, IOException { + return mapper.readerFor(clazz).readValue(jsonString); + } + + public static Iterator readCollection(String jsonString, Class clazz) throws IOException { + return mapper.readerFor(clazz).readValues(jsonString); + } - public static Iterator readCollection(String jsonString, Class clazz) throws IOException { - return mapper.readerFor(clazz).readValues(jsonString); - } public static Iterator readCollection(InputStream is, Class clazz) throws IOException { return mapper.readerFor(clazz).readValues(is); } + + public static String write(Object toWrite) throws JsonProcessingException { + String toReturn= mapper.writeValueAsString(toWrite); + return toReturn; + } + + //**** PROFILED DOCUMENTS + + public static final T convert(Object d,Class clazz){ + return mapper.convertValue(d,clazz); + } + + public static final Document asDocument(Object obj) throws JsonProcessingException { + return Document.parse(mapper.writeValueAsString(obj)); + } + + + // ***** Serialization Exceptions + + // OBJECT ID + private static class ObjectIdSerializer extends JsonSerializer { + @Override + public void serialize(ObjectId objectId, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException { + if (objectId == null) jsonGenerator.writeNull(); + else jsonGenerator.writeString(objectId.toString()); + } + + @Override + public Class handledType() { + return ObjectId.class; + } + } + private static class ObjectIdDeserializer extends JsonDeserializer { + + @Override + public ObjectId deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { + String value=jsonParser.getValueAsString(); + if(value==null || value.isEmpty() || value.equals("null")) + return null; + else return new ObjectId(value); + } + @Override + public Class handledType() { + return ObjectId.class; + } + } + + //Sem Version + private static class SemverSerializer extends JsonSerializer { + @Override + public void serialize(Semver semver, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException { + if (semver == null) jsonGenerator.writeNull(); + else jsonGenerator.writeString(semver.getValue()); + } + + @Override + public Class handledType() { + return Semver.class; + } + } + private static class SemverDeserializer extends JsonDeserializer { + + @Override + public Semver deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { + String value=jsonParser.getValueAsString(); + if(value==null || value.isEmpty() || value.equals("null")) + return null; + else return new Semver(value); + } + @Override + public Class handledType() { + return Semver.class; + } + } } diff --git a/geoportal-client/src/test/java/org/gcube/application/geoportal/StorageTests.java b/geoportal-client/src/test/java/org/gcube/application/geoportal/StorageTests.java index 87f4801..0343578 100644 --- a/geoportal-client/src/test/java/org/gcube/application/geoportal/StorageTests.java +++ b/geoportal-client/src/test/java/org/gcube/application/geoportal/StorageTests.java @@ -1,19 +1,9 @@ package org.gcube.application.geoportal; -import org.apache.commons.io.IOUtils; import org.gcube.application.cms.tests.TokenSetter; - -import org.gcube.application.geoportal.common.rest.TempFile; -import org.gcube.application.geoportal.common.utils.Files; import org.gcube.application.geoportal.common.utils.StorageUtils; -import org.gcube.common.storagehub.client.dsl.StorageHubClient; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; public class StorageTests { diff --git a/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/BasicVreTests.java b/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/BasicVreTests.java index a780e2d..cacdbdb 100644 --- a/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/BasicVreTests.java +++ b/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/BasicVreTests.java @@ -1,15 +1,19 @@ package org.gcube.application.geoportal.clients; import org.gcube.application.cms.tests.TokenSetter; +import org.gcube.application.geoportal.common.utils.tests.GCubeTest; import org.junit.BeforeClass; -public class BasicVreTests { +import static org.junit.Assume.assumeTrue; + +public class BasicVreTests extends GCubeTest { @BeforeClass public static void setScope(){ - TokenSetter.set("/pred4s/preprod/preVRE"); + assumeTrue(isTestInfrastructureEnabled()); +// TokenSetter.set("/pred4s/preprod/preVRE"); // TokenSetter.set("/d4science.research-infrastructures.eu/D4OS/GeoNA-Prototype"); -// TokenSetter.set("/gcube/devsec/devVRE"); + TokenSetter.set(GCubeTest.getContext()); } diff --git a/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/GenericUseCases.java b/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/GenericUseCases.java new file mode 100644 index 0000000..0a23f67 --- /dev/null +++ b/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/GenericUseCases.java @@ -0,0 +1,67 @@ +package org.gcube.application.geoportal.clients; + +import com.fasterxml.jackson.core.JsonProcessingException; +import org.bson.Document; +import org.gcube.application.cms.tests.Tests; +import org.gcube.application.geoportal.client.utils.Serialization; +import org.gcube.application.geoportal.common.faults.InvalidRequestException; +import org.gcube.application.geoportal.common.model.document.Project; +import org.gcube.application.geoportal.common.model.rest.RegisterFileSetRequest; +import org.gcube.application.geoportal.common.rest.Projects; +import org.gcube.application.geoportal.common.utils.FileSets; +import org.gcube.application.geoportal.common.utils.StorageUtils; +import org.junit.Test; + +import java.io.File; +import java.io.FileNotFoundException; +import java.rmi.RemoteException; + +import static org.gcube.application.geoportal.client.plugins.GeoportalAbstractPlugin.projects; + +public abstract class GenericUseCases extends BasicVreTests{ + + protected String getUCID(){ return "basic";} + + protected Projects getClient(String profileID){ + return projects(profileID).build(); + } + + + + protected Projects getClient(){ + return getClient(getUCID()); + } + + @Test + public void createNew () throws RemoteException, FileNotFoundException, JsonProcessingException, InvalidRequestException { + Projects client = getClient(); + + // Create project + Project project = client.createNew(getNewDocument()); + + project = prepareWithFileSet(project); + + System.out.println("Resulting Project : "+project); + System.out.println("JSON Reprepsentation : "+ Serialization.write(project)); + } + + protected Document getNewDocument(){ + Document myDocument= new Document(); + myDocument.put("section",new Document("title","myTitle")); + return myDocument; + } + + protected Project prepareWithFileSet(Project project) throws FileNotFoundException, InvalidRequestException, RemoteException { + String parentPath = "$.section"; + String fieldName = "fileset"; + String fieldDefinition = "$.section._children[?(@.fileset)]"; + + // Prepare request + RegisterFileSetRequest fsRequest = FileSets. + prepareRequest(new StorageUtils(), + parentPath,fieldName,fieldDefinition, new File(Tests.FOLDER_CONCESSIONI,"pos.shp")); + + + return getClient().registerFileSet(project.getId(),fsRequest); + } +} diff --git a/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/ProfiledConcessioniTest.java b/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/ProfiledConcessioniTest.java new file mode 100644 index 0000000..8af8aae --- /dev/null +++ b/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/ProfiledConcessioniTest.java @@ -0,0 +1,129 @@ +package org.gcube.application.geoportal.clients; + +import com.fasterxml.jackson.core.JsonProcessingException; +import lombok.Data; +import org.bson.Document; +import org.gcube.application.cms.tests.TestDocuments; +import org.gcube.application.cms.tests.Tests; +import org.gcube.application.geoportal.client.utils.Serialization; +import org.gcube.application.geoportal.common.faults.InvalidRequestException; +import org.gcube.application.geoportal.common.model.document.Project; +import org.gcube.application.geoportal.common.model.rest.RegisterFileSetRequest; +import org.gcube.application.geoportal.common.model.rest.StepExecutionRequest; +import org.gcube.application.geoportal.common.model.useCaseDescriptor.Field; +import org.gcube.application.geoportal.common.model.useCaseDescriptor.HandlerDeclaration; +import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor; +import org.gcube.application.geoportal.common.rest.Projects; +import org.gcube.application.geoportal.common.utils.FileSets; +import org.gcube.application.geoportal.common.utils.Files; +import org.gcube.application.geoportal.common.utils.StorageUtils; +import org.junit.Test; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.charset.Charset; +import java.rmi.RemoteException; + +public class ProfiledConcessioniTest extends ProfiledDocumentsTest{ + + @Data + private static class MyClass { + private String field; + } + + @Override + protected String getUCID() { + return "profiledConcessioni"; + } + + public void test(){ + + UseCaseDescriptor p=null; + + HandlerDeclaration h = p.getHandlersMapByID().get("MyID").get(0); + + Document doc = h.getConfiguration(); + + System.out.println(Serialization.convert(doc, MyClass.class)); + } + + @Test + public void performSubmit() throws RemoteException, JsonProcessingException, FileNotFoundException, InvalidRequestException { + + Projects client = getClient(); + Project p=client.createNew(getNewDocument()); + + p=prepareWithFileSet(p); + + p = getClient().performStep(p.getId(), new StepExecutionRequest("SUBMIT-FOR-REVIEW",new Document())); + System.out.println("Result is "+Serialization.write(p)); + } + + + @Override + protected Document getNewDocument() { + try { + String json = Files.readFileAsString(TestDocuments.BASE_FOLDER + "/basicConcessioneDocument.json", Charset.defaultCharset()); + return Document.parse(json); + }catch (Throwable t){ + throw new RuntimeException(t); + } + } + + @Override + protected Project prepareWithFileSet(Project project) throws FileNotFoundException, InvalidRequestException, RemoteException { + + Projects client = getClient(); + + // Set relazione + + client.registerFileSet(project.getId(), FileSets. + prepareRequest(new StorageUtils(), + "$.relazioneScavo","fileset", + "$.relazioneScavo."+Field.CHILDREN+"[?(@.fileset)]", + new File(Tests.FOLDER_CONCESSIONI,"relazione.pdf"))); + + // Set Abstract + + client.registerFileSet(project.getId(), FileSets. + prepareRequest(new StorageUtils(), + "$.abstractRelazione","filesetIta", + "$.abstractRelazione."+Field.CHILDREN+"[?(@.filesetIta)]", + new File(Tests.FOLDER_CONCESSIONI,"relazione.pdf"))); + + + // Set pos + + client.registerFileSet(project.getId(), FileSets. + prepareRequest(new StorageUtils(), + "$.posizionamentoScavo","fileset", + "$.posizionamentoScavo."+Field.CHILDREN+"[?(@.fileset)]", + new File(Tests.FOLDER_CONCESSIONI,"pos.shp"), + new File(Tests.FOLDER_CONCESSIONI,"pos.shx"))); + + + // Add 2 imgs + + for(int i=0;i<2;i++){ + client.registerFileSet(project.getId(), FileSets. + prepareRequest(new StorageUtils(), + "$.immaginiRappresentative["+i+"]","fileset", + "$.immaginiRappresentative."+Field.CHILDREN+"[?(@.fileset)]", + new File(Tests.FOLDER_CONCESSIONI,"immagine"+(i+1)+".png"))); + } + + + // Add 2 piante + for(int i=0;i<2;i++){ + client.registerFileSet(project.getId(), FileSets. + prepareRequest(new StorageUtils(), + "$.pianteFineScavo["+i+"]","fileset", + "$.pianteFineScavo."+Field.CHILDREN+"[?(@.fileset)]", + new File(Tests.FOLDER_CONCESSIONI,"pianta.shp"), + new File(Tests.FOLDER_CONCESSIONI,"pianta.shx"))); + } + + return client.getById(project.getId()); + } +} diff --git a/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/ProfiledDocumentsTest.java b/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/ProfiledDocumentsTest.java new file mode 100644 index 0000000..5296118 --- /dev/null +++ b/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/ProfiledDocumentsTest.java @@ -0,0 +1,126 @@ +package org.gcube.application.geoportal.clients; + +import com.fasterxml.jackson.core.JsonProcessingException; +import lombok.extern.slf4j.Slf4j; +import org.bson.Document; +import org.gcube.application.geoportal.common.model.configuration.Configuration; +import org.gcube.application.geoportal.common.model.document.Project; +import org.gcube.application.geoportal.common.model.document.relationships.RelationshipNavigationObject; +import org.gcube.application.geoportal.common.model.rest.CreateRelationshipRequest; +import org.gcube.application.geoportal.common.model.rest.DeleteRelationshipRequest; +import org.gcube.application.geoportal.common.model.rest.QueryRequest; +import org.gcube.application.geoportal.common.rest.Projects; +import org.gcube.application.geoportal.common.utils.tests.GCubeTest; +import org.junit.Test; + +import java.rmi.RemoteException; +import java.time.LocalDateTime; +import java.util.Iterator; +import java.util.concurrent.atomic.AtomicLong; + +import static org.gcube.application.geoportal.client.utils.Serialization.write; +import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeTrue; + +@Slf4j +public class ProfiledDocumentsTest> extends GenericUseCases { + +// protected String getProfileID(){return "basic";} + +// protected C getClient(){ +// return (C) customModel(getProfileID(), Project.class, DefaultDocumentsClient.class).build(); +// } + + + @Test + public void registerNew() throws RemoteException, JsonProcessingException { + assumeTrue(GCubeTest.isTestInfrastructureEnabled()); + Projects client = (Projects) getClient(); + + Document theDoc= Document.parse("{\n" + + "\"posizionamentoScavo\" :{\n" + + "\t\"titolo\" : \"mio titolo\"}}"); + + theDoc.put("startTime", LocalDateTime.now()); + + Project p =client.createNew(theDoc); + + log.debug("Registered project (AS JSON) : {}", write(p)); + } + + @Test + public void getConfiguration() throws Exception { + assumeTrue(GCubeTest.isTestInfrastructureEnabled()); + Projects client = (Projects) getClient(); + Configuration config=client.getConfiguration(); + System.out.println("Configuration is "+ config); + } + + + @Test + public void list() throws Exception { + assumeTrue(GCubeTest.isTestInfrastructureEnabled()); + Projects client = (Projects) getClient(); + AtomicLong counter=new AtomicLong(0); + client.query(new QueryRequest()).forEachRemaining( M -> counter.incrementAndGet()); + System.out.println("Found "+counter.get()+" elements"); + System.out.println("Getting JSON "); + System.out.println(client.queryForJSON(new QueryRequest())); + } + + @Test + public void scanStatusByID() throws Exception { + assumeTrue(GCubeTest.isTestInfrastructureEnabled()); + Projects client = (Projects) getClient(); + AtomicLong counter=new AtomicLong(0); + client.query(new QueryRequest()).forEachRemaining( m -> { + System.out.print(counter.incrementAndGet()+ ", ID : "+m.getId()); + try { + M proj=client.getById(m.getId()); + System.out.println("... OK.. STATUS : "+proj.getLifecycleInformation()); + } catch (RemoteException e) { + System.err.println(" Error with "+m.getId()); + System.err.println(e); + System.out.println("... ERRR !!!!"); + } + }); + } + + @Test + public void testRelationships() throws Exception{ + assumeTrue(GCubeTest.isTestInfrastructureEnabled()); + Projects client = (Projects) getClient(); + Project source = client.createNew(new Document().append("field","value")); + Project target = client.createNew(new Document().append("field2","value")); + + String relId="follows"; + + + Project linkedSource = client.setRelation( + new CreateRelationshipRequest(source.getId(),relId, + target.getId(), null)); + + assertTrue(linkedSource.getRelationships()!=null); + assertTrue(!linkedSource.getRelationships().isEmpty()); + assertTrue(linkedSource.getRelationships().get(0).getRelationshipName().equals(relId)); + assertTrue(linkedSource.getRelationships().get(0).getTargetID().equals(target.getId())); + assertTrue(linkedSource.getRelationships().get(0).getTargetUCD().equals(target.getProfileID())); + + Iterator it = client.getRelationshipChain(source.getId(),relId,true); + System.out.println("Scanning rel .."); + it.forEachRemaining(r -> { + System.out.println(r.getTarget().getId()); + System.out.println("Children size : "+r.getChildren().size()); + }); + + + Project unLinkedSource = client.deleteRelation( + new DeleteRelationshipRequest(source.getId(),relId, + target.getId(),null)); + + + assertTrue(unLinkedSource.getRelationships()==null || unLinkedSource.getRelationships().isEmpty()); + + } + +} diff --git a/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/StatefulClientTests.java b/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/StatefulClientTests.java deleted file mode 100644 index f8e861b..0000000 --- a/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/StatefulClientTests.java +++ /dev/null @@ -1,128 +0,0 @@ -package org.gcube.application.geoportal.clients; - -import static org.gcube.application.geoportal.client.GeoportalAbstractPlugin.statefulMongoConcessioni; -import static org.junit.Assert.*; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; - - -import org.gcube.application.cms.tests.model.concessioni.TestConcessioniModel; -import org.gcube.application.geoportal.client.legacy.ConcessioniManagerI; -import org.gcube.application.geoportal.client.utils.Serialization; -import org.gcube.application.geoportal.common.model.legacy.*; -import org.gcube.application.geoportal.common.model.legacy.report.ValidationReport.ValidationStatus; -import org.gcube.application.geoportal.common.rest.TempFile; -import org.gcube.application.geoportal.common.utils.Files; -import org.gcube.application.geoportal.common.utils.StorageUtils; -import org.gcube.contentmanagement.blobstorage.transport.backend.RemoteBackendException; -import org.junit.Test; - - -public class StatefulClientTests extends BasicVreTests{ - - - - private Concessione publishNew() throws Exception { - ConcessioniManagerI manager=statefulMongoConcessioni().build(); - StorageUtils storage=new StorageUtils(); - - - Concessione toRegister= TestConcessioniModel.prepareEmptyConcessione(); - toRegister.setNome("Mock module"); - manager.createNew(toRegister); - - - - - Concessione source=TestConcessioniModel.prepareConcessione(); - - - UploadedImage toRegisterImg= source.getImmaginiRappresentative().get(0); - - // TEMP Files are hosted in INFRASTRUCTURE's VOLATILE AREA - TempFile toUpload=storage.putOntoStorage( - new File(TestConcessioniModel.getBaseFolder(),"immagine1.png"), "immagine.png"); - - manager.addImmagineRappresentativa(toRegisterImg, toUpload); - - - //Alternative Method - InputStreamDescriptor isDesc= - new InputStreamDescriptor(new FileInputStream(new File(TestConcessioniModel.getBaseFolder(), - "immagine1.png")), "San Mauro_drone totale.JPG"); - manager.addImmagineRappresentativa(toRegisterImg, isDesc); - - source.getRelazioneScavo().setPolicy(AccessPolicy.EMBARGOED); - assertEquals(AccessPolicy.EMBARGOED,source.getRelazioneScavo().getPolicy()); - - //Relazione - manager.setRelazioneScavo(source.getRelazioneScavo(), - storage.putOntoStorage(new File(TestConcessioniModel.getBaseFolder(),"relazione.pdf"), "relazione_it.pdf"), - storage.putOntoStorage(new File(TestConcessioniModel.getBaseFolder(),"relazione.pdf"), "relazione_en.pdf")); - assertEquals(AccessPolicy.EMBARGOED,manager.getCurrent().getRelazioneScavo().getPolicy()); - - //Abstract - manager.setAbstractRelazioneScavo( - source.getAbstractRelazione(), - storage.putOntoStorage(new File(TestConcessioniModel.getBaseFolder(),"relazione.pdf"), "abstract_relazione_it.pdf"), - storage.putOntoStorage(new File(TestConcessioniModel.getBaseFolder(),"relazione.pdf"), "abstract_relazione_en.pdf")); - - - - // Posizionamento scavo - - manager.setPosizionamento(source.getPosizionamentoScavo(), - storage.putOntoStorage( - new File(TestConcessioniModel.getBaseFolder(),"pos.shp"),"pos.shp")); - - // Piante - manager.addPiantaFineScavo(source.getPianteFineScavo().get(0), - storage.putOntoStorage( - new File(TestConcessioniModel.getBaseFolder(),"pianta.shp"),"pianta.shp")); -// new File("/Users/fabioisti/Documents/invio_08_05/Montalto di Castro (VT)_Vulci_Indagini non invasive_Doc. paragr._Va/CONSEGNA_WGS84") -// .listFiles((file,name)->{return name.startsWith("Mag_anomalies_WGS84");}))); - - - - Concessione toReturn=manager.publish(); - assertEquals(AccessPolicy.EMBARGOED,toReturn.getRelazioneScavo().getPolicy()); - return toReturn; - } - - - - @Test - public void testRegisterNew() throws RemoteBackendException, FileNotFoundException, Exception { - Concessione published=publishNew(); - - - // VARIOUS CHECKS - assertNotNull(published.getReport()); - assertEquals(published.getReport().getStatus(),ValidationStatus.PASSED); - - assertEquals(published.getImmaginiRappresentative().size(),2); - assertEquals(published.getPianteFineScavo().size(),1); - assertNotNull(published.getPosizionamentoScavo().getWmsLink()); - for(LayerConcessione l : published.getPianteFineScavo()) - assertNotNull(l.getWmsLink()); - assertNotNull(published.getCentroidLat()); - assertNotNull(published.getCentroidLong()); - - System.out.println(Serialization.write(published)); - System.out.println(Serialization.write(published.getReport())); - } - - @Test - public void delete() throws Exception { - ConcessioniManagerI manager=statefulMongoConcessioni().build(); - StorageUtils storage=new StorageUtils(); - - manager.createNew(TestConcessioniModel.prepareEmptyConcessione()); - - manager.delete(); - } - - -} diff --git a/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/StatelessClientTests.java b/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/StatelessClientTests.java deleted file mode 100644 index a9f9f0b..0000000 --- a/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/StatelessClientTests.java +++ /dev/null @@ -1,281 +0,0 @@ -package org.gcube.application.geoportal.clients; - -import static org.gcube.application.geoportal.client.GeoportalAbstractPlugin.mongoConcessioni; -import static org.junit.Assert.*; -import static org.junit.Assume.assumeTrue; - -import java.io.File; -import java.io.FileInputStream; -import java.nio.charset.Charset; -import java.util.Collections; -import java.util.Iterator; -import java.util.concurrent.atomic.AtomicLong; -import java.util.stream.Collectors; - -import com.sun.corba.se.spi.orbutil.threadpool.Work; -import org.bson.Document; -import org.gcube.application.cms.tests.model.concessioni.TestConcessioniFilters; -import org.gcube.application.cms.tests.model.concessioni.TestConcessioniModel; -import org.gcube.application.cms.tests.model.concessioni.TestConcessioniQueries; -import org.gcube.application.geoportal.client.utils.ConcessioniUtils; -import org.gcube.application.geoportal.client.utils.Queries; -import org.gcube.application.geoportal.client.utils.Serialization; -import org.gcube.application.geoportal.common.model.legacy.*; -import org.gcube.application.geoportal.common.model.legacy.Concessione.Paths; -import org.gcube.application.geoportal.common.model.legacy.report.ValidationReport.ValidationStatus; -import org.gcube.application.geoportal.common.model.rest.AddSectionToConcessioneRequest; -import org.gcube.application.geoportal.common.model.rest.QueryRequest; -import org.gcube.application.geoportal.common.rest.MongoConcessioni; -import org.gcube.application.geoportal.common.utils.FileSets; -import org.gcube.application.geoportal.common.utils.Files; -import org.gcube.application.geoportal.common.utils.StorageUtils; -import org.junit.Test; - -public class StatelessClientTests extends BasicVreTests{ - - - private MongoConcessioni client=mongoConcessioni().build(); - - @Test - public void getConfiguration() throws Exception { - System.out.println(client.getCurrentConfiguration()); - } - - @Test - public void searches() throws Exception { - TestConcessioniFilters.filters.forEach((k, v)->{ - try { - System.out.println("Count for " + k + "\t" + count(client.search(v))); - }catch (Exception e){ - throw new RuntimeException(e); - } - }); - - - } - - - @Test - public void query() throws Exception { - - System.out.println("FRA "+ count(client.query( - Queries.parse(TestConcessioniQueries.queries.get("emptyresult.json"))))); - - // No Transformation - System.out.print("First Registered \t"); - Iterator queriedDocuments=client.query( - Queries.parse(TestConcessioniQueries.queries.get("firstRegistered.json"))); - // Expected one result - assertTrue(count(queriedDocuments)==1); - - - - System.out.print("Last Registered \t"); - // Expected one result - queriedDocuments=client.query( - Queries.parse(TestConcessioniQueries.queries.get("lastRegistered.json"))); - assertTrue(count(queriedDocuments)==1); - - queriedDocuments.forEachRemaining((Concessione c)->{System.out.println(c.getNome());}); - - - // Transformations - System.out.println( - client.queryForJSON( - Queries.parse(TestConcessioniQueries.queries.get("lastNameRegisteredByFabio.json")))); - - System.out.println( - client.queryForJSON( - Queries.parse(TestConcessioniQueries.queries.get("publicationWarningMessages.json")))); - -// String query=Files.readFileAsString(filterFile.getAbsolutePath(), Charset.defaultCharset()); -// System.out.println("Count for "+filterFile.getName()+"\t"+ count(client.search(query))); -// } - } - - @Test - public void testList() throws Exception { - final AtomicLong counter=new AtomicLong(); - long before=System.currentTimeMillis(); - client.getList().forEachRemaining((Concessione c)-> {counter.addAndGet(1);}); - System.out.println("Loaded "+counter+" in "+(System.currentTimeMillis()-before)+" ms"); - } - - @Test - public void testCreateNew() throws Exception { - Concessione c= client.createNew(TestConcessioniModel.prepareEmptyConcessione()); - assertNotNull(c); - assertNotNull(c.getMongo_id()); - } - - - - @Test - public void testClone() throws Exception { - Concessione c= prepare(); - Concessione copied = ConcessioniUtils.clone(client,c.getMongo_id()); - assertEquals(copied.getNome(),c.getNome()); - checkCopied(copied.getRelazioneScavo(),c.getRelazioneScavo()); - checkCopied(copied.getAbstractRelazione(),c.getAbstractRelazione()); - checkCopied(copied.getPosizionamentoScavo(),c.getPosizionamentoScavo()); - assertEquals(copied.getPianteFineScavo().size(),c.getPianteFineScavo().size()); - for(int i=0;i persistedContent instanceof WorkspaceContent). - collect(Collectors.toList()).size(); - - assertEquals(copied.getActualContent().size(),oriringalCount); - } - } - - - - @Test - public void testReplace() throws Exception { - Concessione testObject= client.createNew(TestConcessioniModel.prepareEmptyConcessione()); - String title="My new shiny Title"; - testObject.setNome(title); - Concessione c1=client.replace(testObject); - assertEquals(title, c1.getNome()); - } - - @Test - public void testUploadFileSet() throws Exception { - Concessione testObject= client.createNew(TestConcessioniModel.prepareConcessione()); - AddSectionToConcessioneRequest request= -// FileSets.prepareRequest(new StorageUtils(),Paths.RELAZIONE,new File(TestConcessioniModel.getBaseFolder(),"relazione.pdf")); - FileSets.build(Paths.ABSTRACT_RELAZIONE).add( - new StorageUtils().putOntoStorage(new File(TestConcessioniModel.getBaseFolder(),"relazione.pdf"),"San Mauro_drone totale.JPG")) - .getTheRequest(); - - testObject= client.registerFileSet(testObject.getMongo_id(), request); - - assertNotNull(testObject.getContentByPath(Paths.ABSTRACT_RELAZIONE).getActualContent()); - assertNotNull(testObject.getContentByPath(Paths.ABSTRACT_RELAZIONE).getActualContent().get(0)); - } - - - - @Test - public void testDeleteById() throws Exception { - Concessione c= client.createNew(TestConcessioniModel.prepareEmptyConcessione()); - client.deleteById(c.getMongo_id()); - } - - - @Test - public void testPublish() throws Exception { - Concessione c=prepare(); - - assertTrue(c.getReport().getStatus().equals(ValidationStatus.PASSED)); - - - } - - @Test - public void testCleanFileSet() throws Exception { - - Concessione testObject=prepare(); - System.out.println("Object is "+testObject.getPosizionamentoScavo()); - //Precheck to be sure - assertFalse(testObject.getPosizionamentoScavo().getActualContent().isEmpty()); - assertFalse(testObject.getPianteFineScavo().get(0).getActualContent().isEmpty()); - - client.unPublish(testObject.getMongo_id()); - - // check unpublish - testObject= client.getById(testObject.getMongo_id()); - for(LayerConcessione l:testObject.getPianteFineScavo()) - for(PersistedContent pc: l.getActualContent()) - if(pc instanceof GeoServerContent) throw new Exception ("Concessione not properly unpublished"); - - for(PersistedContent pc: testObject.getPosizionamentoScavo().getActualContent()) - if(pc instanceof GeoServerContent) throw new Exception ("Concessione not properly unpublished"); - - - //Clear pos - testObject=client.cleanFileSet(testObject.getMongo_id(),Paths.POSIZIONAMENTO); - assertTrue(testObject.getPosizionamentoScavo().getActualContent().isEmpty()); - - //Clear pianta [0] - testObject =client.cleanFileSet(testObject.getMongo_id(),Paths.piantaByIndex(0)); - assertTrue(testObject.getPianteFineScavo().get(0).getActualContent().isEmpty()); - } - - - private Concessione prepare() throws Exception { - int numImgs=1; - Concessione c= client.createNew(TestConcessioniModel.prepareConcessione(1,numImgs)); - StorageUtils storage = new StorageUtils(); - - c.getRelazioneScavo().setPolicy(AccessPolicy.EMBARGOED); - String mongoId=c.getMongo_id(); - c=client.update(mongoId, Serialization.write(c)); - - assertEquals(AccessPolicy.EMBARGOED,c.getRelazioneScavo().getPolicy()); - - c=client.registerFileSet(mongoId, - FileSets.prepareRequest(storage,Paths.RELAZIONE,new File(TestConcessioniModel.getBaseFolder(),"relazione.pdf"))); - - assertEquals(AccessPolicy.EMBARGOED,c.getRelazioneScavo().getPolicy()); - - c=client.registerFileSet(mongoId, - FileSets.prepareRequest(storage,Paths.ABSTRACT_RELAZIONE,new File(TestConcessioniModel.getBaseFolder(),"relazione.pdf"))); - - assertEquals(AccessPolicy.EMBARGOED,c.getRelazioneScavo().getPolicy()); - - for(int i=0;i iterator){ - AtomicLong l=new AtomicLong(0); - iterator.forEachRemaining(el->{l.incrementAndGet();}); - return l.get(); - } - - -} diff --git a/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/UCDTests.java b/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/UCDTests.java new file mode 100644 index 0000000..5e9d949 --- /dev/null +++ b/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/UCDTests.java @@ -0,0 +1,64 @@ +package org.gcube.application.geoportal.clients; + +import org.bson.Document; +import org.gcube.application.cms.tests.TokenSetter; +import org.gcube.application.geoportal.common.model.rest.QueryRequest; +import org.gcube.application.geoportal.common.rest.UseCaseDescriptorsI; +import org.gcube.application.geoportal.common.utils.tests.GCubeTest; +import org.junit.Assert; +import org.junit.Test; + +import java.util.concurrent.atomic.AtomicLong; + +import static org.gcube.application.geoportal.client.plugins.GeoportalAbstractPlugin.useCaseDescriptors; +import static org.junit.Assume.assumeTrue; + +public class UCDTests{ + + + + + public UseCaseDescriptorsI getClient(){ + assumeTrue(GCubeTest.isTestInfrastructureEnabled()); + TokenSetter.set(GCubeTest.getContext()); + return useCaseDescriptors().build(); + } + + @Test + public void query() throws Exception { + UseCaseDescriptorsI client =getClient(); + QueryRequest request = new QueryRequest(); + // All + AtomicLong counter = new AtomicLong(0l); + client.query(request).forEachRemaining(u ->counter.incrementAndGet()); + + // Filter by presence of handler Id + request.setFilter(Document.parse("{\"_handlers._id\" : {\"$eq\" : \"org.gcube....geoportal-data-entry-portlet\"}}")); + + System.out.println("Count : "+counter.get()); + } + + @Test + public void getByIdAll() throws Exception { + UseCaseDescriptorsI client =getClient(); + + QueryRequest request = new QueryRequest(); + // All + + client.query(request).forEachRemaining(u -> { + try { + System.out.println("Obtained "+client.getById(u.getId()).getId()); + } catch (Exception e) { + e.printStackTrace(System.err); + Assert.fail("Unable to get "+u.getId()); + } + }); + } + + @Test + public void getById() throws Exception { + UseCaseDescriptorsI client =getClient(); + + System.out.println(client.getById("profiledConcessioni")); + } +} diff --git a/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/legacy/ConcessioniTests.java b/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/legacy/ConcessioniTests.java deleted file mode 100644 index dd79a64..0000000 --- a/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/legacy/ConcessioniTests.java +++ /dev/null @@ -1,81 +0,0 @@ -package org.gcube.application.geoportal.clients.legacy; - -import java.util.ArrayList; -import java.util.concurrent.atomic.AtomicLong; - -import org.gcube.application.geoportal.client.legacy.ConcessioniManager; -import org.gcube.application.geoportal.clients.BasicVreTests; -import org.gcube.application.geoportal.common.model.legacy.Concessione; -import org.gcube.application.geoportal.common.model.legacy.GeoServerContent; -import org.gcube.application.geoportal.common.model.legacy.LayerConcessione; -import org.gcube.application.geoportal.common.model.legacy.PersistedContent; -import org.gcube.application.geoportal.common.model.legacy.report.ValidationReport.ValidationStatus; -import org.junit.Test; - -public class ConcessioniTests extends BasicVreTests { - - static boolean STOP_ON_FAIL=true; - - - - // NB LEGACY - public void readAll() throws Exception { - ConcessioniManager manager=new ConcessioniManager(); - ArrayList found=manager.getList(); - System.out.println("Found "+found.size()+" elements."); - final AtomicLong byId=new AtomicLong(0); - - final ArrayList validIDs=new ArrayList<>(); - - final ArrayList imgs=new ArrayList(); - final AtomicLong error=new AtomicLong(0); - - final ArrayList piante=new ArrayList(); - final ArrayList pos=new ArrayList(); - final ArrayList wmsLink=new ArrayList(); - - found.forEach((Concessione c )->{ - try { - manager.getById(c.getId()+""); - byId.incrementAndGet(); - if(c.validate().getStatus().equals(ValidationStatus.PASSED)) - validIDs.add(c.getId()); - if(c.getImmaginiRappresentative()!=null&&c.getImmaginiRappresentative().size()>0) - imgs.add(c.getId()); - if(c.getPianteFineScavo()!=null) - c.getPianteFineScavo().forEach((LayerConcessione l)->{ - if(l.getActualContent()!=null) - l.getActualContent().forEach((PersistedContent p)->{ - if(p instanceof GeoServerContent) piante.add(c.getId()); - }); - if(l.getWmsLink()!=null) wmsLink.add(c.getId()); - }); - - if(c.getPosizionamentoScavo()!=null) { - LayerConcessione l=c.getPosizionamentoScavo(); - l.getActualContent().forEach((PersistedContent p)->{ - if(p instanceof GeoServerContent) pos.add(c.getId()); - }); - if(l.getWmsLink()!=null) wmsLink.add(c.getId()); - } - }catch(Throwable t) { - error.incrementAndGet(); - if(STOP_ON_FAIL) { - throw new RuntimeException(t); - }else t.printStackTrace(System.err); - } - }); - System.out.println("Valid count "+validIDs.size()+ "Load BY ID : "+byId.get()+" Error : "+error.get()+" OUT OF "+found.size()); - System.out.println("Valid IDS "+validIDs); - System.out.println("With imgs : "+imgs); - System.out.println("With piante : "+piante); - System.out.println("With pos : "+pos); - System.out.println("With wmsLink : "+wmsLink); - } - - - - - - -} diff --git a/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/serialization/SerializationTests.java b/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/serialization/SerializationTests.java new file mode 100644 index 0000000..5b9a16b --- /dev/null +++ b/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/serialization/SerializationTests.java @@ -0,0 +1,32 @@ +package org.gcube.application.geoportal.clients.serialization; + +import lombok.extern.slf4j.Slf4j; +import org.gcube.application.geoportal.client.utils.Serialization; +import org.junit.Test; + +import java.io.IOException; +import java.time.LocalDateTime; + +@Slf4j +public class SerializationTests { + + + @Test + public void testDates() throws IOException { + LocalDateTime obj = LocalDateTime.now(); + + roundTrip(obj); + } + + public boolean roundTrip(Object obj) throws IOException { + log.info("Round trip for {}",obj); + Class clazz =Object.class; + if(obj!=null) clazz=obj.getClass(); + log.debug("Class is {}",obj.getClass()); + String json= Serialization.write(obj); + log.debug("JSON String is : {}",json); + Object unmarshalled = Serialization.read(json,clazz); + log.debug("Unmarshalled as {}",unmarshalled); + return obj.equals(unmarshalled); + } +} diff --git a/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/serialization/UseCaseDescriptors.java b/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/serialization/UseCaseDescriptors.java new file mode 100644 index 0000000..9cf043e --- /dev/null +++ b/geoportal-client/src/test/java/org/gcube/application/geoportal/clients/serialization/UseCaseDescriptors.java @@ -0,0 +1,77 @@ +package org.gcube.application.geoportal.clients.serialization; + +import org.gcube.application.cms.tests.TestProfiles; +import org.gcube.application.geoportal.client.utils.Serialization; +import org.gcube.application.geoportal.common.model.JSONPathWrapper; +import org.gcube.application.geoportal.common.model.useCaseDescriptor.Field; +import org.gcube.application.geoportal.common.model.useCaseDescriptor.HandlerDeclaration; +import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor; +import org.gcube.application.geoportal.common.utils.Files; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.List; +import java.util.Map; + +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertTrue; + +public class UseCaseDescriptors { + + private static UseCaseDescriptor readProfile(String file) throws IOException { + return Serialization.read(getJSON(file), UseCaseDescriptor.class); + } + + private static String getJSON(String file) throws IOException { + return Files.readFileAsString( + new File(TestProfiles.BASE_FOLDER,file).getAbsolutePath(), Charset.defaultCharset()); + } + + @Test + public void read () throws IOException { + for (Map.Entry entry : TestProfiles.profiles.entrySet()) { + String s = entry.getKey(); + UseCaseDescriptor useCaseDescriptor = entry.getValue(); + System.out.println("Checking " + s); + + validate(useCaseDescriptor); + System.out.println(useCaseDescriptor); + UseCaseDescriptor converted = Serialization.convert(useCaseDescriptor, UseCaseDescriptor.class); + assertEquals(useCaseDescriptor, converted); + JSONPathWrapper wrapper = new JSONPathWrapper(Serialization.asDocument(useCaseDescriptor).toJson()); + List foundObjects = wrapper.getByPath("$." + UseCaseDescriptor.HANDLERS, List.class); + + foundObjects.get(0).forEach(o -> { + HandlerDeclaration h = Serialization.convert(o, HandlerDeclaration.class); + System.out.println(h); + validate(h); + }); + + if(useCaseDescriptor.getRelationshipDefinitions()!=null) + useCaseDescriptor.getRelationshipDefinitions().forEach(relationshipDefinition -> { + System.out.println(relationshipDefinition);}); + + } + + } + + + private void validate(UseCaseDescriptor useCaseDescriptor){ + assertTrue(useCaseDescriptor.getId()!=null); + if(useCaseDescriptor.getHandlers()!=null) + useCaseDescriptor.getHandlers().forEach(handlerDeclaration -> validate(handlerDeclaration)); + if(useCaseDescriptor.getSchema()!=null) + validate(useCaseDescriptor.getSchema()); + + } + private void validate(HandlerDeclaration handler){ + assertTrue(handler.getId()!=null); + } + + private void validate(Field f){ + //assertTrue(f.getType()!=null); + + } +} diff --git a/geoportal-common/CHANGELOG.md b/geoportal-common/CHANGELOG.md index 1b3264b..a1c9125 100644 --- a/geoportal-common/CHANGELOG.md +++ b/geoportal-common/CHANGELOG.md @@ -2,6 +2,11 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm # Changelog for org.gcube.application.geoportal-common +# [v1.0.9] - 2022-01-17 +- Minor fixes in model +- Schema and jsonPath support +- Fixes [#22722](https://support.d4science.org/issues/22722) + # [v1.0.8] - 2021-11-10 - Fixes [#22369](https://support.d4science.org/issues/22369) - Fixes [#22338](https://support.d4science.org/issues/22338) diff --git a/geoportal-common/pom.xml b/geoportal-common/pom.xml index 97d5a51..f80f92f 100644 --- a/geoportal-common/pom.xml +++ b/geoportal-common/pom.xml @@ -3,20 +3,19 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 geoportal-common - 1.0.8 + 1.0.9 Geoportal Common org.gcube.application.cms gcube-cms-suite - 1.0.1 + 1.0.2 https://code-repo.d4science.org/gCubeSystem 1.0 - @@ -27,9 +26,21 @@ + + + + org.gcube.distribution + gcube-bom + ${gcube-bom-version} + pom + import + + + + + - org.projectlombok lombok @@ -44,9 +55,32 @@ com.jayway.jsonpath json-path - 2.4.0 + 2.7.0 + + com.vdurmont + semver4j + 3.1.0 + compile + + + + + org.gcube.contentmanagement + storage-manager-core + + + + org.gcube.contentmanagement + storage-manager-wrapper + + + org.reflections + reflections + + + junit @@ -65,18 +99,20 @@ org.glassfish.jersey.media jersey-media-json-jackson - + + org.gcube.resources + registry-publisher + - org.gcube.contentmanagement - storage-manager-core + org.gcube.resources + registry-publisher - org.gcube.contentmanagement - storage-manager-wrapper + javax.xml.bind + jaxb-api + - - \ No newline at end of file diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/JSONSerializationProvider.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/JSONSerializationProvider.java new file mode 100644 index 0000000..2b7b619 --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/JSONSerializationProvider.java @@ -0,0 +1,7 @@ +package org.gcube.application.geoportal.common; + +public interface JSONSerializationProvider { + + public void setJSONWrapperDefaults(); + +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/faults/JsonParseException.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/faults/JsonParseException.java deleted file mode 100644 index f45f8a1..0000000 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/faults/JsonParseException.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.gcube.application.geoportal.common.faults; - -public class JsonParseException extends Exception{ - - /** - * - */ - private static final long serialVersionUID = 1L; - - public JsonParseException() { - super(); - // TODO Auto-generated constructor stub - } - - public JsonParseException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { - super(message, cause, enableSuppression, writableStackTrace); - // TODO Auto-generated constructor stub - } - - public JsonParseException(String message, Throwable cause) { - super(message, cause); - // TODO Auto-generated constructor stub - } - - public JsonParseException(String message) { - super(message); - // TODO Auto-generated constructor stub - } - - public JsonParseException(Throwable cause) { - super(cause); - // TODO Auto-generated constructor stub - } - - - -} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/BasicJSONObject.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/BasicJSONObject.java deleted file mode 100644 index 3ba4e81..0000000 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/BasicJSONObject.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.gcube.application.geoportal.common.model; - -public class BasicJSONObject { - - - -} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/JSONPathWrapper.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/JSONPathWrapper.java new file mode 100644 index 0000000..07f9386 --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/JSONPathWrapper.java @@ -0,0 +1,233 @@ +package org.gcube.application.geoportal.common.model; + + +import com.jayway.jsonpath.*; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.gcube.application.geoportal.common.JSONSerializationProvider; +import org.reflections.Reflections; +import org.reflections.util.ConfigurationBuilder; +import org.reflections.util.FilterBuilder; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +@Slf4j +public class JSONPathWrapper { + + /** + * Based on + * + * https://github.com/json-path/JsonPath + */ + + public static Configuration JSON_PATH_ALWAYS_LIST_CONFIG=null; + public static Configuration JSON_PATH_PATHS_CONFIGURATION=null; + + static { + Reflections reflections = new Reflections( + new ConfigurationBuilder() + .forPackage("org.gcube.application") + .filterInputsBy(new FilterBuilder().includePackage("org.gcube.application"))); + + reflections.getSubTypesOf(JSONSerializationProvider.class).iterator().forEachRemaining(providerClass->{ + if(!providerClass.isInterface()){ + try { + log.warn("Loading JSON Provider {} ",providerClass); + JSONSerializationProvider provider = providerClass.newInstance(); + provider.setJSONWrapperDefaults(); + }catch (Throwable t){ + log.error("Unable to instantiate provider "+providerClass,t); + } + } + + }); + + JSON_PATH_ALWAYS_LIST_CONFIG= Configuration.builder().options(Option.ALWAYS_RETURN_LIST,Option.SUPPRESS_EXCEPTIONS,Option.DEFAULT_PATH_LEAF_TO_NULL).build(); + JSON_PATH_PATHS_CONFIGURATION = Configuration.builder().options(Option.AS_PATH_LIST,Option.SUPPRESS_EXCEPTIONS,Option.DEFAULT_PATH_LEAF_TO_NULL).build(); + + } + + + + @Getter + DocumentContext valueCTX =null; + DocumentContext pathsCTX =null; + + + public JSONPathWrapper(String json) { + + valueCTX =JsonPath.using(JSON_PATH_ALWAYS_LIST_CONFIG).parse(json); + pathsCTX =JsonPath.using(JSON_PATH_PATHS_CONFIGURATION).parse(json); + } + + public List getByPath(String path){ + return getByPath(path,Object.class); + } + + public List getMatchingPaths(String path){ + List l=pathsCTX.read(path); + l.removeIf(p->p==null); + return l; + } + + public List getByPath(String path,Class clazz){ + List l= valueCTX.read(path, new TypeRef>() {}); + l.removeIf(p->p==null); + return l; + } + + /** + * Changes the value of an existent field at @path + * + * @param path + * @param toSet + * @return + */ + public JSONPathWrapper setElement(String path, Object toSet){ + log.debug("Setting Path {} = {}",path,toSet); + JsonPath jPath=JsonPath.compile(path); + if(jPath.isDefinite()){ + valueCTX.set(path,toSet); + } else{ + log.debug("Path is not definte, evaluating matching paths.."); + for(String p : getMatchingPaths(path)){ + log.debug("Actually setting {} as {} ",p,toSet); + setElement(p,toSet); + } + } + return this; + } + + /** + * Creates a new element @elementName == @toSet as child of all matching @path + * + * @param path + * @param elementName + * @param toSet + * @return + */ + public JSONPathWrapper putElement(String path,String elementName, Object toSet){ + log.debug("Putting {} = {} at Path {}",elementName,toSet,path); + JsonPath jPath=JsonPath.compile(path); + if(jPath.isDefinite()){ + valueCTX.put(path,elementName,toSet); + } else{ + log.debug("Path is not definte, evaluating matching paths.."); + for(String p : getMatchingPaths(path)){ + putElement(p,elementName,toSet); + } + } + return this; + } + + /** + * Appends a new element @toSet as child of all arrays matching @path + * + * @param path + * @param toAdd + * @return + */ + public JSONPathWrapper addElementToArray(String path, Object toAdd){ + log.debug("Setting Path {} = {}",path,toAdd); + JsonPath jPath=JsonPath.compile(path); + if(jPath.isDefinite()){ + valueCTX.add(path,toAdd); + } else{ + log.debug("Path is not definte, evaluating matching paths.."); + for(String p : getMatchingPaths(path)){ + addElementToArray(p,toAdd); + } + } + return this; + } + + + //***** EXTENSIONS + + private static Pattern DOTTED_PATH_PATTERN=Pattern.compile("(\\$?\\.\\w*(\\[((\\?\\(.*\\))|(\\d+|\\*))\\])?)(?=(\\.|$)?)"); + private static Pattern BRACKET_PATH_PATTERN=Pattern.compile("(\\$?\\['\\w*'\\](\\[((\\?\\(.*\\))|(\\d+|\\*))\\])?)"); + + +/* private static final DocumentContext addElement(DocumentContext ctx,String path,Object value) throws JsonPathException{ + log.debug("Inserting object at {}",path); + JsonPath jPath=JsonPath.compile(path); + if(jPath.isDefinite()) { + List tokens=tokenizePath(path); + DocumentContext currentCtx=ctx; + String parentPath = null; + for(int i = 0; i foundElements = currentCtx.read(s); + foundElements.removeIf(v->(v==null)); + + if(foundElements.isEmpty()){ + Document newElement=null; + log.trace("{} not found.."); + // add child + if (s.matches("")){ + log.trace("{} is array, checking existence",s,value); + // ARRAY + // if array exists add elements else create new + List foundArray= currentCtx.read(elementName,List.class); + throw new RuntimeException("Implement array support"); + } else { + // Map + newElement = new Document(); + } + currentCtx.put("$",elementName,newElement); + log.trace("Set {}, json is {}",s,currentCtx.jsonString()); + currentCtx= JsonPath.parse(newElement.toJson()); + }else currentCtx = JsonPath.parse(currentCtx.read(s,Document.class)); + } + } return ctx; + }else throw new JsonPathException("Unable to initialize non-definite path : "+path); + } + +*/ + static List tokenizePath(String path){ + List toReturn=null; + log.debug("Tokenizing JSON Path {} ",path); + // if path is $.element.child + if(path.matches("(\\$\\.)?\\w.*")) + toReturn= getByRegex(path, DOTTED_PATH_PATTERN); + else if (path.matches("(\\$)?\\[\\'.*")) + toReturn = getByRegex(path, BRACKET_PATH_PATTERN); + + log.debug("Path {} as tokens {}",path,toReturn); + return toReturn; + } + + private static List getByRegex(String s,Pattern p){ + ArrayList toReturn = new ArrayList<>(); + Matcher m = p.matcher(s); + log.trace("Groups from {} with {} : ",s,p.pattern()); + while(m.find()) { + String found=m.group(); + toReturn.add(found); + } + return toReturn; + } + + static String extractFieldNameFromPathElement(String p){ + Matcher m=Pattern.compile("\\$?\\.?(\\[')?([a-zA-Z_]+)").matcher(p); + m.find(); + return m.group(2); + } + +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/configuration/Archive.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/configuration/Archive.java new file mode 100644 index 0000000..eb752b0 --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/configuration/Archive.java @@ -0,0 +1,22 @@ +package org.gcube.application.geoportal.common.model.configuration; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import org.bson.Document; + +public class Archive extends Document { + public static final String TYPE = "_type"; + + @JsonIgnore + public String getType() { + return super.getString(TYPE); + } + + public Archive() { + super(); + } + + @JsonIgnore + public Archive(String type) { + this.put(TYPE, type); + } +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/configuration/Configuration.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/configuration/Configuration.java new file mode 100644 index 0000000..e5d8725 --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/configuration/Configuration.java @@ -0,0 +1,75 @@ +package org.gcube.application.geoportal.common.model.configuration; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.xml.bind.annotation.XmlRootElement; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@XmlRootElement +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Configuration{ + + public static final String PROFILE_ID="profile_id"; + public static final String CONTEXT = "context"; + public static final String LAST_UPDATED_TIME = "last_updated_time"; + + public static final String ERROR_MESSAGES="errorMessages"; + public static final String WARNING_MESSAGES="warningMessages"; + public static final String STATUS="status"; + + + public static final String INDEXES = "indexes"; + public static final String ARCHIVES = "archives"; + + public static enum Status{ + OK,ERROR,WARNING + } + + + @JsonProperty(PROFILE_ID) + private String profileId; + @JsonProperty(CONTEXT) + private String context; + @JsonProperty(LAST_UPDATED_TIME) + private LocalDateTime lastUpdatedTime; + + @JsonProperty(INDEXES) + private List indexes; + @JsonProperty(ARCHIVES) + private List archives; + + @JsonProperty(ERROR_MESSAGES) + private List errorMessages; + @JsonProperty(WARNING_MESSAGES) + private List warningMessages; + + @JsonProperty(STATUS) + private Status status=Status.OK; + + + @JsonIgnore + public Configuration addErrorMessage(String msg){ + status = Status.ERROR; + if(errorMessages==null) + errorMessages=new ArrayList<>(); + errorMessages.add(msg); + return this; + } + @JsonIgnore + public Configuration addWarningMessage(String msg){ + if(status == null || status.equals(Status.OK)) + status = Status.WARNING; + if(warningMessages==null) + warningMessages=new ArrayList<>(); + warningMessages.add(msg); + return this; + } +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/configuration/Index.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/configuration/Index.java new file mode 100644 index 0000000..66030a1 --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/configuration/Index.java @@ -0,0 +1,28 @@ +package org.gcube.application.geoportal.common.model.configuration; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import org.bson.Document; + +public class Index extends Document { + + public static class KnownTypes{ + public static final String GIS_CENTROIDS="GIS_CENTROIDS"; + } + + + public static final String TYPE = "_type"; + + @JsonIgnore + public String getType() { + return super.getString(TYPE); + } + + public Index() { + super(); + } + + @JsonIgnore + public Index(String type) { + this.put(TYPE, type); + } +} diff --git a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/model/internal/db/MongoConnection.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/configuration/MongoConnection.java similarity index 87% rename from geoportal-service/src/main/java/org/gcube/application/geoportal/service/model/internal/db/MongoConnection.java rename to geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/configuration/MongoConnection.java index 30e1509..40a1ab5 100644 --- a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/model/internal/db/MongoConnection.java +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/configuration/MongoConnection.java @@ -1,4 +1,4 @@ -package org.gcube.application.geoportal.service.model.internal.db; +package org.gcube.application.geoportal.common.model.configuration; import lombok.Data; diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/Access.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/Access.java deleted file mode 100644 index c265269..0000000 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/Access.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.gcube.application.geoportal.common.model.document; - -import lombok.*; - -@NoArgsConstructor -@AllArgsConstructor -@Getter -@Setter -@ToString -public class Access { - - public static final String POLICY="policy"; - public static final String LICENSE="license"; - - private AccessPolicy policy; - private String license; - -} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/AccessPolicy.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/AccessPolicy.java deleted file mode 100644 index cb04ae1..0000000 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/AccessPolicy.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.gcube.application.geoportal.common.model.document; - -public enum AccessPolicy { - - OPEN,RESTRICTED,EMBARGOED; - -} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/AccountingInfo.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/AccountingInfo.java deleted file mode 100644 index 4f25379..0000000 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/AccountingInfo.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.gcube.application.geoportal.common.model.document; - -import lombok.*; - -import java.time.LocalDateTime; - -@NoArgsConstructor -@AllArgsConstructor -@Getter -@Setter -@ToString -public class AccountingInfo { - - public static final String USER="user"; - public static final String CONTEXT="context"; - public static final String INSTANT="instant"; - - private User user; - private Context context; - private LocalDateTime instant; -} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/Context.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/Context.java deleted file mode 100644 index b0e7feb..0000000 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/Context.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.gcube.application.geoportal.common.model.document; - -import lombok.*; - -@NoArgsConstructor -@AllArgsConstructor -@Getter -@Setter -@ToString -public class Context { - public static final String ID="id"; - public static final String NAME = "name"; - - - private String id; - private String name; -} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/LifecycleInformation.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/LifecycleInformation.java deleted file mode 100644 index d6fc700..0000000 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/LifecycleInformation.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.gcube.application.geoportal.common.model.document; - -import lombok.*; - -import java.util.List; - -@NoArgsConstructor -@AllArgsConstructor -@Getter -@Setter -@ToString -public class LifecycleInformation { - - public static final String PHASE="phase"; - public static final String LAST_OPERATION_STATUS="lastOperationStatus"; - public static final String ERROR_MESSAGES="errorMessages"; - public static final String WARNING_MESSAGES="warningMEssages"; - public static final String CHILDREN="children"; - - public static enum Status{ - PASSED,ERROR,WARNING - } - - - private String phase; - private Status lastOperationStatus; - private List errorMessages; - private List warningMessages; - private List children; - -} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/Lock.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/Lock.java new file mode 100644 index 0000000..5373ca1 --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/Lock.java @@ -0,0 +1,25 @@ +package org.gcube.application.geoportal.common.model.document; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.*; +import org.gcube.application.geoportal.common.model.document.accounting.AccountingInfo; + +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +@ToString +public class Lock { + + public static final String ID="_id"; + public static final String INFO="_info"; + public static final String OPERATION="_operation"; + + @JsonProperty(INFO) + private AccountingInfo info; + @JsonProperty(ID) + private String id; + @JsonProperty(OPERATION) + private String operation; + +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/ProfiledDocument.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/ProfiledDocument.java deleted file mode 100644 index 3a081d9..0000000 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/ProfiledDocument.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.gcube.application.geoportal.common.model.document; - -import com.mongodb.client.model.geojson.GeoJsonObjectType; -import lombok.*; -import org.bson.Document; - - -@NoArgsConstructor -@AllArgsConstructor -@Getter -@Setter -@ToString -public class ProfiledDocument { - - public static final String _ID="_id"; - public static final String VERSION="version"; - public static final String INFO="info"; - public static final String PROFILE_ID="profileID"; - public static final String PROFILE_VERSION="profileVersion"; - public static final String LIFECYCLE_INFORMATION="lifecycleInformation"; - public static final String RELATIONSHIPS="relationships"; - public static final String SPATIAL_REFERENCE="spatialReference"; - public static final String TEMPORAL_REFERENCE="temporalReference"; - public static final String THE_DOCUMENT="theDocument"; - - // CORE METADATA - - private String _id; - private ComparableVersion version; - - // Publication Info - private PublicationInfo info; - - // Profile reference - private String profileID; - private ComparableVersion profileVersion; - - private LifecycleInformation lifecycleInformation; - - private Relationship[] relationships; - - private GeoJsonObjectType spatialReference; - - private TemporalReference temporalReference; - - private Document theDocument; - - public void setDefaults(){ - // TODO APPLY DEFAULTS ?? - - }; -} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/Project.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/Project.java new file mode 100644 index 0000000..c93927f --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/Project.java @@ -0,0 +1,107 @@ +package org.gcube.application.geoportal.common.model.document; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.vdurmont.semver4j.Semver; +import lombok.*; +import org.bson.Document; +import org.gcube.application.geoportal.common.model.document.accounting.PublicationInfo; +import org.gcube.application.geoportal.common.model.document.identification.IdentificationReference; +import org.gcube.application.geoportal.common.model.document.lifecycle.LifecycleInformation; +import org.gcube.application.geoportal.common.model.document.relationships.Relationship; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + + +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +@ToString +public class Project { + + public static final String ID="_id"; + public static final String VERSION="_version"; + public static final String INFO="_info"; + public static final String PROFILE_ID="_profileID"; + public static final String PROFILE_VERSION="_profileVersion"; + public static final String LIFECYCLE_INFORMATION="_lifecycleInformation"; + public static final String RELATIONSHIPS="_relationships"; + public static final String IDENTIFICATION_REFERENCES="_identificationReferences"; + public static final String THE_DOCUMENT="_theDocument"; + public static final String LOCK="_lock"; + + // CORE METADATA + + @JsonProperty(ID) + private String id; + @JsonProperty(VERSION) + private Semver version; + + // Publication Info + @JsonProperty(INFO) + private PublicationInfo info; + + // UseCaseDescriptor reference + @JsonProperty(PROFILE_ID) + private String profileID; + @JsonProperty(PROFILE_VERSION) + private Semver profileVersion; + + @JsonProperty(LIFECYCLE_INFORMATION) + private LifecycleInformation lifecycleInformation; + + @JsonProperty(RELATIONSHIPS) + private List relationships; + + @JsonProperty(IDENTIFICATION_REFERENCES) + private List identificationReferences; + + @JsonProperty(THE_DOCUMENT) + private Document theDocument; + + @JsonProperty(LOCK) + private Lock lock; + + + /** + * Similar to equals but without checking following fields + * + * lock + * @param o + * @return + */ + public boolean isEquivalent(Object o) { + if (this == o) return true; + if (!(o instanceof Project)) return false; + Project project = (Project) o; + return Objects.equals(getId(), project.getId()) && Objects.equals(getVersion(), project.getVersion()) && Objects.equals(getInfo(), project.getInfo()) && Objects.equals(getProfileID(), project.getProfileID()) && Objects.equals(getProfileVersion(), project.getProfileVersion()) && Objects.equals(getLifecycleInformation(), project.getLifecycleInformation()) && Objects.equals(getIdentificationReferences(), project.getIdentificationReferences()) && Objects.equals(getRelationships(), project.getRelationships()) && Objects.equals(getTheDocument(), project.getTheDocument()); + } + + + @JsonIgnore + public List getIdentificationReferenceByType(String type){ + if(identificationReferences==null) return Collections.emptyList(); + else return identificationReferences.stream() + .filter(item -> item.getType().equals(type)).collect(Collectors.toList()); + }; + + @JsonIgnore + public List getRelationshipsByName(String relation){ + if(relationships==null)return Collections.emptyList(); + else return relationships.stream().filter(relationship -> relationship. + getRelationshipName().equals(relation)).collect(Collectors.toList()); + }; + + + @JsonIgnore + public Project addRelation(Relationship rel){ + if(relationships==null) relationships = new ArrayList<>(); + relationships.add(rel); + return this; + } +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/PublicationInfo.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/PublicationInfo.java deleted file mode 100644 index c48add5..0000000 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/PublicationInfo.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.gcube.application.geoportal.common.model.document; - -import lombok.*; -import org.gcube.application.geoportal.common.model.legacy.AccessPolicy; - -@NoArgsConstructor -@AllArgsConstructor -@Getter -@Setter -@ToString -public class PublicationInfo { - - public static final String CREATION_INFO="creationInfo"; - public static final String LAST_EDIT_INFO="lastEditInfo"; - public static final String ACCESS = "access"; - - - private AccountingInfo creationInfo; - private AccountingInfo lastEditInfo; - private Access access; - - -} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/RegisteredFile.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/RegisteredFile.java deleted file mode 100644 index 1844eca..0000000 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/RegisteredFile.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.gcube.application.geoportal.common.model.document; - -import lombok.*; - -@NoArgsConstructor -@AllArgsConstructor -@Getter -@Setter -@ToString -public class RegisteredFile { - - public static String MIMETYPE="mimetype"; - public static String STORAGE_ID="storageID"; - public static String LINK="link"; - public static String NAME="NAME"; - - private String mimetype; - private String storageID; - private String link; - private String name; -} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/RegisteredFileSet.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/RegisteredFileSet.java deleted file mode 100644 index 376999d..0000000 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/RegisteredFileSet.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.gcube.application.geoportal.common.model.document; - -import lombok.*; -import org.bson.Document; - -import java.util.List; - -@NoArgsConstructor -@AllArgsConstructor -@Getter -@Setter -@ToString -public class RegisteredFileSet { - - public static final String CREATION_INFO="creationInfo"; - public static final String ACCESS="access"; - public static final String FOLDER_ID="folderID"; - public static final String PAYLOADS="payloads"; - - private AccountingInfo creationInfo; - private Access access; - private String folderID; - - private List payloads; -} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/Relationship.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/Relationship.java deleted file mode 100644 index caa0c93..0000000 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/Relationship.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.gcube.application.geoportal.common.model.document; - -import lombok.*; - -@NoArgsConstructor -@AllArgsConstructor -@Getter -@Setter -@ToString -public class Relationship { - - public static final String RELATIONSHIP_NAME="relationshipName"; - public static final String TARGET_ID="targetID"; - - private String relationshipName; - private String targetID; - -} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/TemporalReference.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/TemporalReference.java deleted file mode 100644 index 889db6e..0000000 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/TemporalReference.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.gcube.application.geoportal.common.model.document; - -import lombok.*; - -@NoArgsConstructor -@AllArgsConstructor -@Getter -@Setter -@ToString -public class TemporalReference { - - private String field; -} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/User.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/User.java deleted file mode 100644 index fda76a3..0000000 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/User.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.gcube.application.geoportal.common.model.document; - -import lombok.*; - -@NoArgsConstructor -@AllArgsConstructor -@Getter -@Setter -@ToString -public class User { - - public static final String USERNAME="username"; - - - private String username; - -} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/access/Access.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/access/Access.java new file mode 100644 index 0000000..8abb48a --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/access/Access.java @@ -0,0 +1,21 @@ +package org.gcube.application.geoportal.common.model.document.access; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.*; + +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +@ToString +public class Access { + + public static final String POLICY="_policy"; + public static final String LICENSE="_license"; + + @JsonProperty(POLICY) + private AccessPolicy policy; + @JsonProperty(LICENSE) + private String license; + +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/access/AccessPolicy.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/access/AccessPolicy.java new file mode 100644 index 0000000..eba157e --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/access/AccessPolicy.java @@ -0,0 +1,7 @@ +package org.gcube.application.geoportal.common.model.document.access; + +public enum AccessPolicy { + + OPEN,RESTRICTED,EMBARGOED; + +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/accounting/AccountingInfo.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/accounting/AccountingInfo.java new file mode 100644 index 0000000..7a0e8d9 --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/accounting/AccountingInfo.java @@ -0,0 +1,25 @@ +package org.gcube.application.geoportal.common.model.document.accounting; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.*; + +import java.time.LocalDateTime; + +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +@ToString +public class AccountingInfo { + + public static final String USER="_user"; + public static final String CONTEXT="_context"; + public static final String INSTANT="_instant"; + + @JsonProperty(USER) + private User user; + @JsonProperty(CONTEXT) + private Context context; + @JsonProperty(INSTANT) + private LocalDateTime instant; +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/accounting/Context.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/accounting/Context.java new file mode 100644 index 0000000..5fd4150 --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/accounting/Context.java @@ -0,0 +1,19 @@ +package org.gcube.application.geoportal.common.model.document.accounting; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.*; + +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +@ToString +public class Context { + public static final String ID="_id"; + public static final String NAME = "_name"; + + @JsonProperty(ID) + private String id; + @JsonProperty(NAME) + private String name; +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/accounting/PublicationInfo.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/accounting/PublicationInfo.java new file mode 100644 index 0000000..2a12411 --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/accounting/PublicationInfo.java @@ -0,0 +1,25 @@ +package org.gcube.application.geoportal.common.model.document.accounting; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.*; +import org.gcube.application.geoportal.common.model.document.access.Access; + +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +@ToString +public class PublicationInfo { + + public static final String CREATION_INFO="_creationInfo"; + public static final String LAST_EDIT_INFO="_lastEditInfo"; + public static final String ACCESS = "_access"; + + @JsonProperty(CREATION_INFO) + private AccountingInfo creationInfo; + @JsonProperty(LAST_EDIT_INFO) + private AccountingInfo lastEditInfo; + @JsonProperty(ACCESS) + private Access access; + +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/accounting/User.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/accounting/User.java new file mode 100644 index 0000000..dae28a0 --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/accounting/User.java @@ -0,0 +1,37 @@ +package org.gcube.application.geoportal.common.model.document.accounting; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.*; + +import java.util.Objects; +import java.util.Set; + +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +@ToString +public class User { + + public static final String USERNAME="_username"; + + @JsonProperty(USERNAME) + private String username; + + @JsonIgnore + private Set roles; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof User)) return false; + User user = (User) o; + return Objects.equals(getUsername(), user.getUsername()); + } + + @Override + public int hashCode() { + return Objects.hash(getUsername()); + } +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/filesets/Materialization.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/filesets/Materialization.java new file mode 100644 index 0000000..8e60d50 --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/filesets/Materialization.java @@ -0,0 +1,20 @@ +package org.gcube.application.geoportal.common.model.document.filesets; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.ToString; +import org.bson.Document; + +@ToString (callSuper = true) +public class Materialization extends Document { + + public static final String TYPE ="_type"; + + @JsonIgnore + public String getType(){return super.getString(TYPE);} + + public Materialization(){super();} + @JsonIgnore + public Materialization (String type){ + this.put(TYPE,type); + } +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/filesets/RegisteredFile.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/filesets/RegisteredFile.java new file mode 100644 index 0000000..30e8a4e --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/filesets/RegisteredFile.java @@ -0,0 +1,22 @@ +package org.gcube.application.geoportal.common.model.document.filesets; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +@Data +public class RegisteredFile { + + public static final String MIMETYPE="_mimetype"; + public static final String STORAGE_ID="_storageID"; + public static final String LINK="_link"; + public static final String NAME="_name"; + + @JsonProperty(MIMETYPE) + private String mimetype; + @JsonProperty(STORAGE_ID) + private String storageID; + @JsonProperty(LINK) + private String link; + @JsonProperty(NAME) + private String name; +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/filesets/RegisteredFileSet.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/filesets/RegisteredFileSet.java new file mode 100644 index 0000000..e3273bd --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/filesets/RegisteredFileSet.java @@ -0,0 +1,34 @@ +package org.gcube.application.geoportal.common.model.document.filesets; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.ToString; +import org.bson.Document; + +import java.util.List; + + +@ToString (callSuper = true) +public class RegisteredFileSet extends Document { + + + + public static final String UUID="_uuid"; + public static final String CREATION_INFO="_creationInfo"; + public static final String ACCESS="_access"; + public static final String FOLDER_ID="_folderID"; + public static final String PAYLOADS="_payloads"; + public static final String MATERIALIZATIONS="_materializations"; + + @JsonIgnore + public Object getCreationInfo(){ return this.get(CREATION_INFO); } + @JsonIgnore + public Object getAccess(){ return this.get(ACCESS); } + @JsonIgnore + public String getFolderId(){ return super.getString(FOLDER_ID); } + @JsonIgnore + public List getPayloads(){return super.get(PAYLOADS,List.class);} + @JsonIgnore + public List getMaterializations(){return super.get(MATERIALIZATIONS,List.class);} + @JsonIgnore + public String getUUID(){return super.getString(UUID);} +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/filesets/sdi/GCubeSDILayer.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/filesets/sdi/GCubeSDILayer.java new file mode 100644 index 0000000..8bdebdc --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/filesets/sdi/GCubeSDILayer.java @@ -0,0 +1,141 @@ +package org.gcube.application.geoportal.common.model.document.filesets.sdi; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.bson.Document; +import org.gcube.application.geoportal.common.model.document.filesets.Materialization; + +import java.util.List; +import java.util.Map; + +public class GCubeSDILayer extends Materialization { + + @Data + @NoArgsConstructor + /** + * A GeoJSON object MAY have a member named "bbox" to include + * information on the coordinate range for its Geometries, Features, or + * FeatureCollections. The value of the bbox member MUST be an array of + * length 2*n where n is the number of dimensions represented in the + * contained geometries, with all axes of the most southwesterly point + * followed by all axes of the more northeasterly point. The axes order + * of a bbox follows the axes order of geometries. + * + * source https://datatracker.ietf.org/doc/html/rfc7946#section-5 + */ + public static class BBOX extends Document { + + public final String asGeoJSONBBox(){ + StringBuilder builder = new StringBuilder("["); + builder.append(getMaxX()+","); // W + builder.append(getMinY()+","); // S + if(is3d()) builder.append(getMinZ()+","); // Z + + builder.append(getMinX()+","); // E + builder.append(getMaxY()+","); // N + if(is3d()) builder.append(getMaxZ()+","); // Z + + + builder.deleteCharAt(builder.length()); + builder.append("]"); + return builder.toString(); + } + public double[] asGeoJSONArray(){ + if(is3d()){ + return new double[]{getMaxX(),getMinY(),getMinZ(),getMinX(),getMaxY(),getMaxZ()}; + }else return new double[]{getMaxX(),getMinY(),getMinX(),getMaxY()}; + } + + public static final BBOX fromGeoJSON(double[] coords){ + BBOX toReturn = new BBOX(); + toReturn.setMaxX(coords[0]); + toReturn.setMinY(coords[1]); + + if(coords.length == 6){ + // 3D + toReturn.setMinZ(coords[2]); + toReturn.setMinX(coords[3]); + toReturn.setMaxY(coords[4]); + toReturn.setMaxZ(coords[5]); + }else { + toReturn.setMinX(coords[2]); + toReturn.setMaxY(coords[3]); + } + return toReturn; + } + + public static final BBOX WORLD=new BBOX(180d,-180d,90d,-90d); + + public static final BBOX WORLD_3D=new BBOX(180d,-180d,90d,-90d); + + public static final String MAX_X="_maxX"; + public static final String MAX_Y="_maxY"; + public static final String MAX_Z="_maxZ"; + public static final String MIN_X="_minX"; + public static final String MIN_Y="_minY"; + public static final String MIN_Z="_minZ"; + + + public BBOX(Double maxX,Double minX,Double maxY,Double minY,Double maxZ,Double minZ){ + this(maxX,minX,maxY,minY); + setMaxZ(maxZ); + setMinZ(minZ); + } + public BBOX(Double maxX,Double minX,Double maxY,Double minY){ + setMaxX(maxX); + setMinX(minX); + setMaxY(maxY); + setMinY(minY); + } + + @JsonIgnore + public BBOX setMaxX(Double d){this.put(MAX_X,d);return this;} + @JsonIgnore + public BBOX setMaxY(Double d){this.put(MAX_Y,d);return this;} + @JsonIgnore + public BBOX setMaxZ(Double d){this.put(MAX_Z,d);return this;} + @JsonIgnore + public BBOX setMinX(Double d){this.put(MIN_X,d);return this;} + @JsonIgnore + public BBOX setMinY(Double d){this.put(MIN_Y,d);return this;} + @JsonIgnore + public BBOX setMinZ(Double d){this.put(MIN_Z,d);return this;} + @JsonIgnore + public Double getMinY(){return (Double) this.getOrDefault(MIN_Y,-90d);} + @JsonIgnore + public Double getMaxY(){return (Double) this.getOrDefault(MAX_Y,90d);} + @JsonIgnore + public Double getMinX(){return (Double) this.getOrDefault(MIN_X,-180d);} + @JsonIgnore + public Double getMaxX(){return (Double) this.getOrDefault(MAX_X,180d);} + @JsonIgnore + public Double getMinZ(){return (Double) this.getOrDefault(MIN_Z,null);} + @JsonIgnore + public Double getMaxZ(){return (Double) this.getOrDefault(MAX_Z,null);} + + @JsonIgnore + public Boolean is3d(){ + return getMinZ()!=null && getMaxZ() !=null; + } + } + + + public static final String GCUBE_SDY_LAYER_TYPE="gcube-sdi-layer"; + public static final String OGC_LINKS="_ogcLinks"; + public static final String B_BOX = "_bbox"; + public static final String PLATFORM_INFO="_platformInfo"; + + public GCubeSDILayer(){ + super(GCUBE_SDY_LAYER_TYPE); + } + + @JsonIgnore + public Map getOGCLinks(){return this.get(OGC_LINKS, Map.class);} + @JsonIgnore + public Object getBBox(){return this.get(B_BOX);} + @JsonIgnore + public List getPlatformInfo(){return this.get(PLATFORM_INFO,List.class);} + + +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/filesets/sdi/GeoServerPlatform.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/filesets/sdi/GeoServerPlatform.java new file mode 100644 index 0000000..644b9b7 --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/filesets/sdi/GeoServerPlatform.java @@ -0,0 +1,29 @@ +package org.gcube.application.geoportal.common.model.document.filesets.sdi; + + +import com.fasterxml.jackson.annotation.JsonIgnore; + +import java.util.List; + +public class GeoServerPlatform extends PlatformInfo{ + + + public static final String GS_PLATFORM="Geoserver"; + public static final String WORKSPACE= "workspace"; + public static final String LAYER_NAME= "layerName"; + public static final String PERSISTENCE_PATH = "persistencePath"; + public static final String FILES="files"; + public static final String STORENAME="storeName"; + + @JsonIgnore + public String getWorkspace(){return this.getString(WORKSPACE);} + @JsonIgnore + public String getLayerName(){return this.getString(LAYER_NAME);} + @JsonIgnore + public String getPersistencePath(){return this.getString(PERSISTENCE_PATH);} + @JsonIgnore + public List getFiles(){return this.get(FILES,List.class);} + @JsonIgnore + public String getStoreName(){return this.getString(STORENAME);} + +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/filesets/sdi/PlatformInfo.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/filesets/sdi/PlatformInfo.java new file mode 100644 index 0000000..93e7627 --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/filesets/sdi/PlatformInfo.java @@ -0,0 +1,22 @@ +package org.gcube.application.geoportal.common.model.document.filesets.sdi; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import org.bson.Document; + + +public class PlatformInfo extends Document { + + public static final String TYPE="_type"; + public static final String HOST="_host"; + public static final String ENGINE_VERSION = "_engineVersion"; + + @JsonIgnore + public String getType(){ return this.getString(TYPE); } + @JsonIgnore + public String getHost(){ return this.getString(HOST); } + @JsonIgnore + public String getEngineVersion(){ return this.getString(ENGINE_VERSION); } + + +} + diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/identification/CentroidRecordReference.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/identification/CentroidRecordReference.java new file mode 100644 index 0000000..88a0e9b --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/identification/CentroidRecordReference.java @@ -0,0 +1,7 @@ +package org.gcube.application.geoportal.common.model.document.identification; + +public class CentroidRecordReference extends IdentificationReference{ + + public static final String CENTROID_RECORD_REFERENCE="CENTROID_RECORD_TYPE"; + +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/identification/IdentificationReference.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/identification/IdentificationReference.java new file mode 100644 index 0000000..29f91bf --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/identification/IdentificationReference.java @@ -0,0 +1,22 @@ +package org.gcube.application.geoportal.common.model.document.identification; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.NoArgsConstructor; +import lombok.ToString; +import org.bson.Document; + +@ToString(callSuper = true) +@NoArgsConstructor +public class IdentificationReference extends Document { + + public static final String TYPE="_type"; + + public IdentificationReference(String type) { + setType(type); + } + + @JsonIgnore + public String getType(){return super.getString(TYPE);} + @JsonIgnore + public void setType(String type){super.put(TYPE,type);} +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/identification/SpatialReference.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/identification/SpatialReference.java new file mode 100644 index 0000000..9ec1d99 --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/identification/SpatialReference.java @@ -0,0 +1,24 @@ +package org.gcube.application.geoportal.common.model.document.identification; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@NoArgsConstructor +@ToString(callSuper = true) +public class SpatialReference extends IdentificationReference{ + + public static final String SPATIAL_REFERENCE_TYPE="SPATIAL REFERENCE"; + public static final String GEO_JSON="geoJSON"; + + + public SpatialReference(Object geoJSON) { + setGeoJson(geoJSON); + setType(SPATIAL_REFERENCE_TYPE); + } + + @JsonIgnore + public Object getGeoJson(){return super.get(GEO_JSON);} + @JsonIgnore + public Object setGeoJson(Object geoJSON){return super.put(GEO_JSON,geoJSON);} +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/identification/TemporalReference.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/identification/TemporalReference.java new file mode 100644 index 0000000..9c35e31 --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/identification/TemporalReference.java @@ -0,0 +1,9 @@ +package org.gcube.application.geoportal.common.model.document.identification; + +import lombok.ToString; + +@ToString (callSuper = true) +public class TemporalReference extends IdentificationReference { + + public static final String TEMPORAL_REFERENCE_TYPE="TEMPORAL_REFERENCE_TYPE"; +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/lifecycle/LifecycleInformation.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/lifecycle/LifecycleInformation.java new file mode 100644 index 0000000..ef3b15d --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/lifecycle/LifecycleInformation.java @@ -0,0 +1,83 @@ +package org.gcube.application.geoportal.common.model.document.lifecycle; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +@Data +public class LifecycleInformation { + + public static final class CommonPhases{ + public static final String DRAFT_PHASE="DRAFT"; + } + + //COMMON PHASES + + + public static final String PHASE="_phase"; + public static final String LAST_INVOKED_STEP="_lastInvokedStep"; + public static final String LAST_OPERATION_STATUS="_lastOperationStatus"; + public static final String ERROR_MESSAGES="_errorMessages"; + public static final String WARNING_MESSAGES="_warningMessages"; + public static final String TRIGGERED_EVENTS="_triggeredEvents"; + public static final String NOTES="_notes"; + + public static enum Status{ + OK,ERROR,WARNING + } + + @JsonProperty(PHASE) + private String phase; + @JsonProperty(LAST_INVOKED_STEP) + private String lastInvokedStep; + @JsonProperty(LAST_OPERATION_STATUS) + private Status lastOperationStatus; + @JsonProperty(ERROR_MESSAGES) + private List errorMessages; + @JsonProperty(WARNING_MESSAGES) + private List warningMessages; + @JsonProperty(TRIGGERED_EVENTS) + private List triggeredEvents; + @JsonProperty(NOTES) + private String notes; + + + @JsonIgnore + public TriggeredEvents getLastEvent(){ + if(triggeredEvents==null || triggeredEvents.isEmpty()) return null; + return triggeredEvents.get(triggeredEvents.size()-1); + } + + @JsonIgnore + public LifecycleInformation addErrorMessage(String msg){ + if(errorMessages==null) + errorMessages=new ArrayList<>(); + errorMessages.add(msg); + return this; + } + @JsonIgnore + public LifecycleInformation addWarningMessage(String msg){ + if(warningMessages==null) + warningMessages=new ArrayList<>(); + warningMessages.add(msg); + return this; + } + @JsonIgnore + public LifecycleInformation addEventReport(TriggeredEvents info){ + if(triggeredEvents==null) triggeredEvents=new ArrayList<>(); + triggeredEvents.add(info); + return this; + } + @JsonIgnore + public LifecycleInformation cleanState(){ + setLastOperationStatus(null); + setLastInvokedStep(null); + setTriggeredEvents(new ArrayList<>()); + setErrorMessages(new ArrayList<>()); + setWarningMessages(new ArrayList<>()); + return this; + } +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/lifecycle/TriggeredEvents.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/lifecycle/TriggeredEvents.java new file mode 100644 index 0000000..a9b8912 --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/lifecycle/TriggeredEvents.java @@ -0,0 +1,33 @@ +package org.gcube.application.geoportal.common.model.document.lifecycle; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +@Data +public class TriggeredEvents { + + public static final String PHASE="_phase"; + public static final String LAST_INVOKED_STEP="_lastInvokedStep"; + public static final String LAST_OPERATION_STATUS="_lastOperationStatus"; + public static final String ERROR_MESSAGES="_errorMessages"; + public static final String WARNING_MESSAGES="_warningMessages"; + public static final String TRIGGERED_EVENTS="_triggeredEvents"; + + private String event; + private LifecycleInformation.Status lastOperationStatus; + private List errorMessages; + private List warningMessages; + + public void addErrorMessage(String msg){ + if(errorMessages==null) + errorMessages=new ArrayList<>(); + errorMessages.add(msg); + } + public void addWarningMessage(String msg){ + if(warningMessages==null) + warningMessages=new ArrayList<>(); + warningMessages.add(msg); + } +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/relationships/Relationship.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/relationships/Relationship.java new file mode 100644 index 0000000..2d8241e --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/relationships/Relationship.java @@ -0,0 +1,24 @@ +package org.gcube.application.geoportal.common.model.document.relationships; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.*; + +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +@ToString +public class Relationship { + + public static final String RELATIONSHIP_NAME="_relationshipName"; + public static final String TARGET_ID="_targetID"; + public static final String TARGET_UCD="_targetUCD"; + + @JsonProperty(RELATIONSHIP_NAME) + private String relationshipName; + @JsonProperty(TARGET_ID) + private String targetID; + @JsonProperty(TARGET_UCD) + private String targetUCD; + +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/relationships/RelationshipNavigationObject.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/relationships/RelationshipNavigationObject.java new file mode 100644 index 0000000..4da2092 --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/document/relationships/RelationshipNavigationObject.java @@ -0,0 +1,24 @@ +package org.gcube.application.geoportal.common.model.document.relationships; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.*; +import org.gcube.application.geoportal.common.model.document.Project; + +import java.util.List; + +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +@ToString +public class RelationshipNavigationObject { + public static final String CHILDREN="_children"; + public static final String TARGET="_target"; + + @JsonProperty(CHILDREN) + List children; + + @NonNull + @JsonProperty(TARGET) + Project target; +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/AssociatedContent.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/AssociatedContent.java index 43fd773..14dcc12 100644 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/AssociatedContent.java +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/AssociatedContent.java @@ -1,17 +1,15 @@ package org.gcube.application.geoportal.common.model.legacy; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; - -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElements; - -import org.gcube.application.geoportal.common.model.legacy.report.ValidationReport; -import org.gcube.application.geoportal.common.utils.CollectionsUtils; - import lombok.Getter; import lombok.Setter; +import org.gcube.application.geoportal.common.model.legacy.report.ValidationReport; +import org.gcube.application.geoportal.common.utils.CollectionsUtils; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElements; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; @Getter diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/BBOX.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/BBOX.java index aa88773..9ce82ab 100644 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/BBOX.java +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/BBOX.java @@ -1,13 +1,8 @@ package org.gcube.application.geoportal.common.model.legacy; -import java.io.Serializable; +import lombok.*; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; -import lombok.ToString; +import java.io.Serializable; @RequiredArgsConstructor @Getter diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/Concessione.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/Concessione.java index 45c97b7..c5d6f5d 100644 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/Concessione.java +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/Concessione.java @@ -1,12 +1,8 @@ package org.gcube.application.geoportal.common.model.legacy; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import javax.xml.bind.annotation.XmlRootElement; - +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; import org.gcube.application.geoportal.common.faults.InvalidRequestException; import org.gcube.application.geoportal.common.model.legacy.report.Check; import org.gcube.application.geoportal.common.model.legacy.report.ConstraintCheck; @@ -14,9 +10,11 @@ import org.gcube.application.geoportal.common.model.legacy.report.ValidationRepo import org.gcube.application.geoportal.common.model.legacy.report.ValidationReport.ValidationStatus; import org.gcube.application.geoportal.common.utils.CollectionsUtils; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; +import javax.xml.bind.annotation.XmlRootElement; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; @Getter @Setter diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/GeoServerContent.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/GeoServerContent.java index 88fd57a..5f50e17 100644 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/GeoServerContent.java +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/GeoServerContent.java @@ -1,13 +1,13 @@ package org.gcube.application.geoportal.common.model.legacy; -import java.util.ArrayList; -import java.util.List; - import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; import lombok.ToString; +import java.util.ArrayList; +import java.util.List; + @Getter @Setter @ToString(callSuper=true) diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/InputStreamDescriptor.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/InputStreamDescriptor.java index 2b04ec7..facf3ff 100644 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/InputStreamDescriptor.java +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/InputStreamDescriptor.java @@ -1,12 +1,12 @@ package org.gcube.application.geoportal.common.model.legacy; -import java.io.InputStream; - import lombok.Data; import lombok.Getter; import lombok.NonNull; import lombok.Setter; +import java.io.InputStream; + @Data @Getter @Setter diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/LayerConcessione.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/LayerConcessione.java index fa3362a..7635fd1 100644 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/LayerConcessione.java +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/LayerConcessione.java @@ -1,12 +1,11 @@ package org.gcube.application.geoportal.common.model.legacy; -import java.util.List; - -import org.gcube.application.geoportal.common.model.legacy.report.ValidationReport; -import org.gcube.application.geoportal.common.utils.CollectionsUtils; - import lombok.Getter; import lombok.Setter; +import org.gcube.application.geoportal.common.model.legacy.report.ValidationReport; +import org.gcube.application.geoportal.common.utils.CollectionsUtils; + +import java.util.List; @Getter diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/PersistedContent.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/PersistedContent.java index 9905d66..c125d98 100644 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/PersistedContent.java +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/PersistedContent.java @@ -3,7 +3,6 @@ package org.gcube.application.geoportal.common.model.legacy; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonSubTypes.Type; import com.fasterxml.jackson.annotation.JsonTypeInfo; - import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/Record.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/Record.java index 4efecac..f3b1773 100644 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/Record.java +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/Record.java @@ -1,14 +1,13 @@ package org.gcube.application.geoportal.common.model.legacy; -import java.time.LocalDateTime; - -import org.gcube.application.geoportal.common.model.legacy.report.ConstraintCheck; -import org.gcube.application.geoportal.common.model.legacy.report.ValidationReport; - import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; import lombok.ToString; +import org.gcube.application.geoportal.common.model.legacy.report.ConstraintCheck; +import org.gcube.application.geoportal.common.model.legacy.report.ValidationReport; + +import java.time.LocalDateTime; @Getter @Setter diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/RelazioneScavo.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/RelazioneScavo.java index 6cc5e88..e944813 100644 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/RelazioneScavo.java +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/RelazioneScavo.java @@ -1,13 +1,12 @@ package org.gcube.application.geoportal.common.model.legacy; -import java.util.List; - -import org.gcube.application.geoportal.common.model.legacy.report.ValidationReport; -import org.gcube.application.geoportal.common.utils.CollectionsUtils; - import lombok.Getter; import lombok.Setter; import lombok.ToString; +import org.gcube.application.geoportal.common.model.legacy.report.ValidationReport; +import org.gcube.application.geoportal.common.utils.CollectionsUtils; + +import java.util.List; @Getter @Setter diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/UploadedImage.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/UploadedImage.java index 3b5b413..635b4e8 100644 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/UploadedImage.java +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/UploadedImage.java @@ -1,12 +1,11 @@ package org.gcube.application.geoportal.common.model.legacy; -import java.util.List; - -import org.gcube.application.geoportal.common.utils.CollectionsUtils; - import lombok.Getter; import lombok.Setter; import lombok.ToString; +import org.gcube.application.geoportal.common.utils.CollectionsUtils; + +import java.util.List; @Getter @Setter diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/report/ConstraintCheck.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/report/ConstraintCheck.java index 211c73e..72d7470 100644 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/report/ConstraintCheck.java +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/report/ConstraintCheck.java @@ -1,14 +1,13 @@ package org.gcube.application.geoportal.common.model.legacy.report; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + @Getter @Setter @Slf4j diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/report/PublicationReport.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/report/PublicationReport.java index 1663091..d5440d1 100644 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/report/PublicationReport.java +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/report/PublicationReport.java @@ -1,14 +1,12 @@ package org.gcube.application.geoportal.common.model.legacy.report; -import java.io.Serializable; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; - -import org.gcube.application.geoportal.common.model.legacy.Record; - import lombok.Getter; import lombok.Setter; +import org.gcube.application.geoportal.common.model.legacy.Record; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import java.io.Serializable; @XmlAccessorType(XmlAccessType.NONE) public class PublicationReport extends ValidationReport implements Serializable{ diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/report/ValidationReport.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/report/ValidationReport.java index ed91409..d643446 100644 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/report/ValidationReport.java +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/legacy/report/ValidationReport.java @@ -1,12 +1,12 @@ package org.gcube.application.geoportal.common.model.legacy.report; +import lombok.Data; +import lombok.NoArgsConstructor; + import java.io.Serializable; import java.util.ArrayList; import java.util.List; -import lombok.Data; -import lombok.NoArgsConstructor; - @Data @NoArgsConstructor public class ValidationReport implements Serializable{ diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/plugins/IndexerPluginDescriptor.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/plugins/IndexerPluginDescriptor.java new file mode 100644 index 0000000..711ca27 --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/plugins/IndexerPluginDescriptor.java @@ -0,0 +1,8 @@ +package org.gcube.application.geoportal.common.model.plugins; + +public class IndexerPluginDescriptor extends PluginDescriptor{ + + public static final String INDEXER="Indexer"; + + +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/plugins/LifecycleManagerDescriptor.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/plugins/LifecycleManagerDescriptor.java new file mode 100644 index 0000000..f6d308f --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/plugins/LifecycleManagerDescriptor.java @@ -0,0 +1,27 @@ +package org.gcube.application.geoportal.common.model.plugins; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import javax.xml.bind.annotation.XmlRootElement; +import java.util.Map; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@XmlRootElement +@Slf4j +public class LifecycleManagerDescriptor extends PluginDescriptor{ + + public static final String LIFECYCLE_MANAGER_TYPE="LifecycleManagement"; + + public LifecycleManagerDescriptor(String id) { + super(id,LIFECYCLE_MANAGER_TYPE); + } + + private Map supportedSteps; + private Map supportedEvents; + +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/plugins/MaterializerPluginDescriptor.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/plugins/MaterializerPluginDescriptor.java new file mode 100644 index 0000000..99e7f84 --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/plugins/MaterializerPluginDescriptor.java @@ -0,0 +1,7 @@ +package org.gcube.application.geoportal.common.model.plugins; + +public class MaterializerPluginDescriptor extends PluginDescriptor{ + + public static final String MATERIALIZER="Materializer"; + +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/plugins/OperationDescriptor.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/plugins/OperationDescriptor.java new file mode 100644 index 0000000..dcf630a --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/plugins/OperationDescriptor.java @@ -0,0 +1,33 @@ +package org.gcube.application.geoportal.common.model.plugins; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.gcube.application.geoportal.common.model.useCaseDescriptor.Field; + +import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; +import java.util.Map; + + +@Data +@NoArgsConstructor +@AllArgsConstructor +@XmlRootElement +public class OperationDescriptor { + + public OperationDescriptor(String id) { + this.id = id; + } + + public OperationDescriptor(String id, String description) { + this.id = id; + this.description = description; + } + + private String id; + private Map parameters; + private String description; + + private List appliableToPhases; +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/plugins/PluginDescriptor.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/plugins/PluginDescriptor.java new file mode 100644 index 0000000..deb49fc --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/plugins/PluginDescriptor.java @@ -0,0 +1,26 @@ +package org.gcube.application.geoportal.common.model.plugins; + +import com.vdurmont.semver4j.Semver; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.xml.bind.annotation.XmlRootElement; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@XmlRootElement +public class PluginDescriptor { + + public PluginDescriptor(String id, String type) { + this.id = id; + this.type = type; + } + + private String id; + private String type; + private String label; + private String description; + private Semver version; +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/profile/HandlerDeclaration.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/profile/HandlerDeclaration.java deleted file mode 100644 index 3f70dae..0000000 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/profile/HandlerDeclaration.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.gcube.application.geoportal.common.model.profile; - -import lombok.Data; -import org.bson.Document; - -@Data -public class HandlerDeclaration { - - private String id; - private String type; - private Document configuration; -} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/profile/Profile.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/profile/Profile.java deleted file mode 100644 index c1f96bb..0000000 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/profile/Profile.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.gcube.application.geoportal.common.model.profile; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.xml.bind.annotation.XmlRootElement; - -import lombok.Data; -import lombok.Getter; -import lombok.NoArgsConstructor; -import org.bson.Document; -import org.gcube.application.geoportal.common.model.document.AccountingInfo; -import org.gcube.application.geoportal.common.model.document.ComparableVersion; - -@Data -@NoArgsConstructor -@XmlRootElement -public class Profile{ - - private String id; - private ComparableVersion version; - - private String name; - private String description; - private AccountingInfo creationInfo; - - private Document schema; - - private List handlers; - - /** - * Returns map Type -> Handler Declaration - * @return - */ - public Map> getHandlersMap(){ - HashMap> toReturn=new HashMap<>(); - handlers.forEach(h->{ - if(!toReturn.containsKey(h.getType())) - toReturn.put(h.getType(),new ArrayList<>()); - toReturn.get(h.getType()).add(h); - }); - return toReturn; - } -} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/rest/AddSectionToConcessioneRequest.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/rest/AddSectionToConcessioneRequest.java index ae9774a..2fa928d 100644 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/rest/AddSectionToConcessioneRequest.java +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/rest/AddSectionToConcessioneRequest.java @@ -1,25 +1,25 @@ package org.gcube.application.geoportal.common.model.rest; -import java.util.List; - -import javax.xml.bind.annotation.XmlRootElement; - import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import org.bson.Document; import org.gcube.application.geoportal.common.faults.InvalidRequestException; import org.gcube.application.geoportal.common.model.legacy.Concessione; -import org.gcube.application.geoportal.common.rest.TempFile; + +import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; @XmlRootElement @Data @AllArgsConstructor @NoArgsConstructor +@Deprecated public class AddSectionToConcessioneRequest { private String destinationPath; private List streams; - + private Document attributes; public void validate()throws InvalidRequestException { Concessione.Paths.validate(destinationPath); diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/rest/Configuration.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/rest/Configuration.java deleted file mode 100644 index 029618a..0000000 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/rest/Configuration.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.gcube.application.geoportal.common.model.rest; - -import lombok.Data; - -@Data -public class Configuration { - - // Index (postgis + layer) Configuration - public PostgisIndexDescriptor index; - - - - // Mongo DB Configuration - // TBD -} diff --git a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/model/internal/faults/ConfigurationException.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/rest/ConfigurationException.java similarity index 93% rename from geoportal-service/src/main/java/org/gcube/application/geoportal/service/model/internal/faults/ConfigurationException.java rename to geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/rest/ConfigurationException.java index 7a76d91..d2516d5 100644 --- a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/model/internal/faults/ConfigurationException.java +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/rest/ConfigurationException.java @@ -1,4 +1,4 @@ -package org.gcube.application.geoportal.service.model.internal.faults; +package org.gcube.application.geoportal.common.model.rest; public class ConfigurationException extends Exception { diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/rest/CreateRelationshipRequest.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/rest/CreateRelationshipRequest.java new file mode 100644 index 0000000..96d5303 --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/rest/CreateRelationshipRequest.java @@ -0,0 +1,17 @@ +package org.gcube.application.geoportal.common.model.rest; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CreateRelationshipRequest { + + private String projectId; + private String relationshipId; + private String targetId; + private String targetUCD; + +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/rest/DeleteRelationshipRequest.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/rest/DeleteRelationshipRequest.java new file mode 100644 index 0000000..96377d8 --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/rest/DeleteRelationshipRequest.java @@ -0,0 +1,11 @@ +package org.gcube.application.geoportal.common.model.rest; + +public class DeleteRelationshipRequest extends CreateRelationshipRequest{ + + public DeleteRelationshipRequest(String projectId, String relationshipId, String targetId, String targetUCD) { + super(projectId, relationshipId, targetId, targetUCD); + } + + public DeleteRelationshipRequest() { + } +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/rest/RegisterFileSetRequest.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/rest/RegisterFileSetRequest.java new file mode 100644 index 0000000..9b35c6d --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/rest/RegisterFileSetRequest.java @@ -0,0 +1,44 @@ +package org.gcube.application.geoportal.common.model.rest; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.bson.Document; +import org.gcube.application.geoportal.common.faults.InvalidRequestException; +import org.gcube.application.geoportal.common.model.document.access.Access; + +import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; + +@XmlRootElement +@Data +@AllArgsConstructor +@NoArgsConstructor +public class RegisterFileSetRequest { + + /** Behavior for existing JSON Object at @destinationPath + * + * REPLACE_EXISTING : removes previously defined attributes (only on single match) + * MERGE_EXISTING : merges the provided attributes with the matching ones (only on single match) + * APPEND : appends the object to the existing collection (only if field is multiple) + */ + public static enum ClashOptions { + REPLACE_EXISTING,MERGE_EXISTING, APPEND + } + + private String fieldDefinitionPath; + private String parentPath; + private String fieldName; + private List streams; + private Document attributes; + + // Default is project's access + private Access toSetAccess; + + private ClashOptions clashOption; + + public void validate()throws InvalidRequestException { + if(streams==null || streams.isEmpty()) throw new InvalidRequestException("No Temp File declared"); + for(TempFile t : streams) t.validate(); + } +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/rest/StepExecutionRequest.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/rest/StepExecutionRequest.java new file mode 100644 index 0000000..6e3a1a7 --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/rest/StepExecutionRequest.java @@ -0,0 +1,18 @@ +package org.gcube.application.geoportal.common.model.rest; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.bson.Document; + +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +@Data +@AllArgsConstructor +@NoArgsConstructor +public class StepExecutionRequest { + + private String stepID; + private Document options; +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/rest/TempFile.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/rest/TempFile.java similarity index 66% rename from geoportal-common/src/main/java/org/gcube/application/geoportal/common/rest/TempFile.java rename to geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/rest/TempFile.java index 4276512..f40c1a8 100644 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/rest/TempFile.java +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/rest/TempFile.java @@ -1,4 +1,4 @@ -package org.gcube.application.geoportal.common.rest; +package org.gcube.application.geoportal.common.model.rest; import lombok.AllArgsConstructor; import lombok.Data; @@ -11,10 +11,11 @@ import org.gcube.application.geoportal.common.faults.InvalidRequestException; public class TempFile { private String id; + private String url; private String filename; public void validate()throws InvalidRequestException { - if(id==null || id.isEmpty()) throw new InvalidRequestException("Invalid temp file "+this+" : ID null or empty"); + if((id==null || id.isEmpty() )&&(url==null||url.isEmpty())) throw new InvalidRequestException("Invalid temp file "+this+" : ID null or empty and no url defined"); if(filename==null || filename.isEmpty()) throw new InvalidRequestException("Invalid temp file "+this+" : filename null or empty"); } } diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/useCaseDescriptor/DataAccessPolicy.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/useCaseDescriptor/DataAccessPolicy.java new file mode 100644 index 0000000..81a0188 --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/useCaseDescriptor/DataAccessPolicy.java @@ -0,0 +1,87 @@ +package org.gcube.application.geoportal.common.model.useCaseDescriptor; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.*; +import org.bson.Document; +import org.gcube.application.geoportal.common.model.document.Project; +import org.gcube.application.geoportal.common.model.document.accounting.User; + +import java.util.List; + +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +@ToString +public class DataAccessPolicy { + + public static final String POLICY = "_policy"; + public static final String ROLES = "_roles"; + public static final String ENFORCER = "_enforcer"; + + @NoArgsConstructor + @AllArgsConstructor + @Getter + @Setter + @ToString + public static class Policy { + public static final String WRITE="_write"; + public static final String READ="_read"; + + public static enum Type{ + own, none, any + } + + @JsonProperty(WRITE) + private Type write; + @JsonProperty(READ) + private Type read; + } + + + @NoArgsConstructor + @AllArgsConstructor + @Getter + @Setter + @ToString + public static class PolicyEnforcer { + public static final String FILTER="_filter"; + @JsonProperty(FILTER) + private String filter; + + @JsonIgnore + public Document getFilterDocument(){ + if(filter!=null) return Document.parse(filter); + else return new Document(); + } + } + + + @JsonProperty(POLICY) + private Policy policy; + @JsonProperty(ROLES) + private List roles; + @JsonProperty(ENFORCER) + private PolicyEnforcer enforcer; + + @JsonIgnore + public boolean canRead(Project p, User u){ + switch(getPolicy().getRead()){ + case own: return p.getInfo().getCreationInfo().getUser().equals(u); + case any: return true; + case none: + default : return false; + } + } + + @JsonIgnore + public boolean canWrite(Project p, User u){ + switch(getPolicy().getWrite()){ + case own: return p.getInfo().getCreationInfo().getUser().equals(u); + case any: return true; + case none: + default : return false; + } + } +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/useCaseDescriptor/Field.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/useCaseDescriptor/Field.java new file mode 100644 index 0000000..63644a1 --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/useCaseDescriptor/Field.java @@ -0,0 +1,67 @@ +package org.gcube.application.geoportal.common.model.useCaseDescriptor; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import org.bson.Document; + +import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; + +@XmlRootElement +@AllArgsConstructor +@Getter +@Setter +@ToString(callSuper = true) +public class Field extends Document { + + public static final String TYPE="_type"; + public static final String CHILDREN="_children"; + public static final String MAX_CARDINALITY="_max"; + public static final String MIN_CARDINALITY="_min"; + public static final String LABEL="_label"; + + @JsonIgnore + public String getLabel(){ + return this.getString(LABEL); + } + + @JsonIgnore + public String getType(){ + return this.getString(TYPE); + }; + + @JsonIgnore + public Boolean isLeaf(){ + List children = getChildren(); + return children == null || children.isEmpty() || children.get(0)==null; + } + + @JsonIgnore + public List getChildren(){ + return this.get(CHILDREN,List.class); + } + + @JsonIgnore + public Boolean isCollection() { + Integer maxCard=this.getMaxCardinality(); + return (maxCard>1||maxCard<0); // Negative values for unbounded + } + + @JsonIgnore + public Integer getMaxCardinality(){ + return (Integer) this.getOrDefault(MAX_CARDINALITY,1); + } + + @JsonIgnore + public Integer getMinCardinality(){ + return (Integer) this.getOrDefault(MIN_CARDINALITY,0); + } + @JsonIgnore + public Boolean isMandatory(){ + return getMinCardinality()==0; + } + +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/useCaseDescriptor/FieldMap.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/useCaseDescriptor/FieldMap.java new file mode 100644 index 0000000..79008df --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/useCaseDescriptor/FieldMap.java @@ -0,0 +1,13 @@ +package org.gcube.application.geoportal.common.model.useCaseDescriptor; + +import java.util.ArrayList; +import java.util.HashMap; + + +class FieldMap extends ArrayList { + + public static class MapElement extends HashMap{ + + } + +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/useCaseDescriptor/HandlerDeclaration.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/useCaseDescriptor/HandlerDeclaration.java new file mode 100644 index 0000000..7c05ab4 --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/useCaseDescriptor/HandlerDeclaration.java @@ -0,0 +1,20 @@ +package org.gcube.application.geoportal.common.model.useCaseDescriptor; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import org.bson.Document; + +@Data +public class HandlerDeclaration { + + public static final String ID="_id"; + public static final String TYPE="_type"; + public static final String CONFIGURATION="_configuration"; + + @JsonProperty(ID) + private String id; + @JsonProperty(TYPE) + private String type; + @JsonProperty(CONFIGURATION) + private Document configuration; +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/useCaseDescriptor/RelationshipDefinition.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/useCaseDescriptor/RelationshipDefinition.java new file mode 100644 index 0000000..63e10aa --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/useCaseDescriptor/RelationshipDefinition.java @@ -0,0 +1,25 @@ +package org.gcube.application.geoportal.common.model.useCaseDescriptor; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import javax.xml.bind.annotation.XmlRootElement; + +@Data +@NoArgsConstructor +public class RelationshipDefinition { + + public static final String ID="_id"; + public static final String LABEL="_label"; + public static final String REVERSE_RELATION_ID="_reverseRelationId"; + + @JsonProperty(ID) + private String id; + @JsonProperty(LABEL) + private String label; + @JsonProperty(REVERSE_RELATION_ID) + private String reverseRelationId; + +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/useCaseDescriptor/UseCaseDescriptor.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/useCaseDescriptor/UseCaseDescriptor.java new file mode 100644 index 0000000..c8d0a9f --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/model/useCaseDescriptor/UseCaseDescriptor.java @@ -0,0 +1,138 @@ +package org.gcube.application.geoportal.common.model.useCaseDescriptor; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.vdurmont.semver4j.Semver; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.bson.types.ObjectId; +import org.gcube.application.geoportal.common.model.document.accounting.AccountingInfo; +import org.gcube.application.geoportal.common.model.document.accounting.User; + +import javax.xml.bind.annotation.XmlRootElement; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Data +@NoArgsConstructor +@XmlRootElement +@Slf4j +public class UseCaseDescriptor implements Serializable { + + public static final String MONGO_ID="_mongoId"; + public static final String ID="_id"; + public static final String VERSION="_version"; + public static final String NAME="_name"; + public static final String DESCRIPTION="_description"; + public static final String CREATION_INFO="_creationInfo"; + public static final String SCHEMA="_schema"; + public static final String HANDLERS="_handlers"; + public static final String DATA_ACCESS_POLICIES="_dataAccessPolicies"; + + public static final String RELATIONSHIP_DEFINITIONS="_relationshipDefinitions"; + + @JsonProperty(MONGO_ID) + private ObjectId mongoId; + + @JsonProperty(ID) + private String id; + @JsonProperty(VERSION) + private Semver version; + + @JsonProperty(NAME) + private String name; + @JsonProperty(DESCRIPTION) + private String description; + @JsonProperty(CREATION_INFO) + private AccountingInfo creationInfo; + + @JsonProperty(SCHEMA) + private Field schema; + + @JsonProperty(HANDLERS) + private List handlers; + + @JsonProperty(DATA_ACCESS_POLICIES) + private List dataAccessPolicies; + + + @JsonProperty(RELATIONSHIP_DEFINITIONS) + private List relationshipDefinitions; + + + /** + * Returns map Type -> Handler Declaration + * @return + */ + @JsonIgnore + public Map> getHandlersMapByType(){ + HashMap> toReturn=new HashMap<>(); + handlers.forEach(h->{ + try { + if(!toReturn.containsKey(h.getType())) + toReturn.put(h.getType(),new ArrayList<>()); + toReturn.get(h.getType()).add(h); + }catch (Throwable t){ + log.error("Invalid useCaseDescriptor : unable to get Handler Map by Type with {} in useCaseDescriptor [ID {}]",h,this.getId(),t);} + }); + if(log.isTraceEnabled()) { + toReturn.forEach((s, handlerDeclarations) -> log.trace("UCD {} : Found N {} handlers of type {}",this.getId(),handlerDeclarations.size(),s)); + } + return toReturn; + } + + /** + * Returns List of Handler Declaration by type + * + * @param type + * @return + */ + @JsonIgnore + public List getHandlersByType(String type){ + List toReturn= + handlers.stream().sequential(). + filter(handlerDeclaration -> handlerDeclaration.getType().equals(type)).collect(Collectors.toList()); + log.debug("UCD {} : Found {} Handlers for {}",getId(),toReturn.size(),type); + return toReturn; + } + + /** + * Returns map ID -> Handler Declaration + * @return + */ + @JsonIgnore + public Map> getHandlersMapByID(){ + HashMap> toReturn=new HashMap<>(); + handlers.forEach(h->{ + try { + if (!toReturn.containsKey(h.getId())) + toReturn.put(h.getId(), new ArrayList<>()); + toReturn.get(h.getId()).add(h); + }catch (Throwable t){ + log.error("Invalid useCaseDescriptor : unable to get Handler Map by ID with {} in useCaseDescriptor [ID {}]",h,this.getId(),t);} + }); + return toReturn; + } + + @JsonIgnore + public DataAccessPolicy getMatching(User u){ + DataAccessPolicy defaultPolicy = null; + if(dataAccessPolicies!=null) + for (DataAccessPolicy dataAccessPolicy : dataAccessPolicies) { + if(dataAccessPolicy.getRoles()==null||dataAccessPolicy.getRoles().isEmpty()) + defaultPolicy= dataAccessPolicy; + for (String r : dataAccessPolicy.getRoles()) + if (u.getRoles().contains(r)) + return dataAccessPolicy; + } + return defaultPolicy; + } + + + +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/rest/InterfaceConstants.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/rest/InterfaceConstants.java index 1dac42a..0ffa144 100644 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/rest/InterfaceConstants.java +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/rest/InterfaceConstants.java @@ -6,15 +6,15 @@ public class InterfaceConstants { public static final String APPLICATION_BASE_PATH="geoportal-service"; public static final String APPLICATION_PATH="/srv"; - public static final String SERVICE_CLASS="Application"; - public static final String SERVICE_NAME="GeoPortal"; + public static String SERVICE_CLASS="org.gcube.application"; + public static String SERVICE_NAME="geoportal-service"; public static final class Methods{ - public static final String PROFILES="profiles"; - public static final String SECTIONS="sections"; + public static final String UCD ="ucd"; public static final String PROJECTS="projects"; + public static final String PLUGINS="plugins"; + - public static final String CONCESSIONI="concessioni"; public static final String MONGO_CONCESSIONI="mongo-concessioni"; @@ -25,20 +25,26 @@ public class InterfaceConstants { public static final String CONFIGURATION_PATH="configuration"; public static final String SEARCH_PATH="search"; public static final String QUERY_PATH="query"; - + + public static final String STEP="step"; + + public static final String RELATIONSHIP="relationship"; + public static final String FORCE_UNLOCK="forceUnlock"; + public static final String SET_PROJECT_ACCESS_POLICY="setAccess"; + } public static final class Parameters{ public static final String PROJECT_ID="project_id"; public static final String SECTION_ID="section_id"; - public static final String PROFILE_ID="profile_id"; + public static final String UCID ="usecase_id"; -// //INVESTIGATE CAPABILITIES -// public static final String ORDER_BY="order_by"; -// public static final String LIMIT="limit"; -// public static final String OFFSET="offset"; public static final String FORCE="force"; + public static final String RELATIONSHIP_ID="relationship_id"; + public static final String DEEP="deep"; + public static final String TARGET_UCD="target_ucd"; + public static final String TARGET_ID="target_id"; } diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/rest/MongoConcessioni.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/rest/MongoConcessioni.java index e7e107e..4c37bf5 100644 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/rest/MongoConcessioni.java +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/rest/MongoConcessioni.java @@ -1,8 +1,8 @@ package org.gcube.application.geoportal.common.rest; +import org.gcube.application.geoportal.common.model.configuration.Configuration; import org.gcube.application.geoportal.common.model.legacy.Concessione; import org.gcube.application.geoportal.common.model.rest.AddSectionToConcessioneRequest; -import org.gcube.application.geoportal.common.model.rest.Configuration; import org.gcube.application.geoportal.common.model.rest.QueryRequest; import java.util.Iterator; diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/rest/ProfiledDocumentsI.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/rest/ProfiledDocumentsI.java deleted file mode 100644 index c7aaabd..0000000 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/rest/ProfiledDocumentsI.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.gcube.application.geoportal.common.rest; - -import org.bson.Document; -import org.gcube.application.geoportal.common.model.document.ProfiledDocument; -import org.gcube.application.geoportal.common.model.rest.Configuration; -import org.gcube.application.geoportal.common.model.rest.QueryRequest; - -import java.rmi.RemoteException; -import java.util.Iterator; - -public interface ProfiledDocumentsI

{ - - // CRUD - public P createNew(Document toCreate)throws RemoteException; - public void deleteById(String id) throws RemoteException; - public void deleteById(String id,Boolean force) throws RemoteException; - public P getById(String id) throws RemoteException; - - // CONFIG - public Configuration getConfiguration() throws RemoteException; - - // QUERY - public Iterator

query (QueryRequest request) throws RemoteException; - public String querForJSON(QueryRequest request)throws RemoteException; - - //Execution - public P performStep(String id, String step, Document request); -} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/rest/Projects.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/rest/Projects.java new file mode 100644 index 0000000..10ff2bd --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/rest/Projects.java @@ -0,0 +1,54 @@ +package org.gcube.application.geoportal.common.rest; + +import org.bson.Document; +import org.gcube.application.geoportal.common.faults.InvalidRequestException; +import org.gcube.application.geoportal.common.model.configuration.Configuration; +import org.gcube.application.geoportal.common.model.document.Project; +import org.gcube.application.geoportal.common.model.document.access.Access; +import org.gcube.application.geoportal.common.model.document.relationships.RelationshipNavigationObject; +import org.gcube.application.geoportal.common.model.rest.*; + +import java.rmi.RemoteException; +import java.util.Iterator; + +public interface Projects

{ + + public Class

getManagedClass(); + + // CRUD + public P createNew(Document toCreate)throws RemoteException; + public P getById(String id) throws RemoteException; + public P updateDocument(String id,Document updatedDocument) throws RemoteException; + public void deleteById(String id) throws RemoteException; + public void deleteById(String id,Boolean force) throws RemoteException; + + + + // CONFIG + public Configuration getConfiguration() throws RemoteException; + + // QUERY + public Iterator

query (QueryRequest request) throws RemoteException; + public Iterator queryForClass (QueryRequest request,Class clazz) throws RemoteException; + public String queryForJSON(QueryRequest request)throws RemoteException; + + //Execution + public P performStep(String id, StepExecutionRequest request) throws RemoteException; + + //FileSets + public P registerFileSet(String id, RegisterFileSetRequest req) throws RemoteException, InvalidRequestException; + //FileSets + public P deleteFileSet(String id, String path, Boolean force) throws RemoteException; + + public P forceUnlock(String id) throws RemoteException; + public P setAccessPolicy(String id, Access toSet) throws RemoteException; + + // Relationships + public Project setRelation(CreateRelationshipRequest request)throws RemoteException; + + public Project deleteRelation(DeleteRelationshipRequest request)throws RemoteException; + + public Iterator getRelationshipChain(String id, String relationId, Boolean deep) throws RemoteException; + + public Iterator getRelationshipChain(String id, String relationId) throws RemoteException; +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/rest/UseCaseDescriptorsI.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/rest/UseCaseDescriptorsI.java new file mode 100644 index 0000000..c55185b --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/rest/UseCaseDescriptorsI.java @@ -0,0 +1,22 @@ +package org.gcube.application.geoportal.common.rest; + +import org.bson.Document; +import org.gcube.application.geoportal.common.model.rest.QueryRequest; +import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor; + +import java.rmi.RemoteException; +import java.util.Iterator; + + +public interface UseCaseDescriptorsI { + + public UseCaseDescriptor create(Document toCreate)throws RemoteException; + + public Iterator query(QueryRequest request) throws Exception; + + public void deleteById(String id,boolean force)throws RemoteException; + + public UseCaseDescriptor update(String ID, Document toSet)throws RemoteException; + + public UseCaseDescriptor getById(String id) throws Exception; +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/utils/ContextUtils.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/utils/ContextUtils.java index 6adb30a..6969202 100644 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/utils/ContextUtils.java +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/utils/ContextUtils.java @@ -1,12 +1,11 @@ package org.gcube.application.geoportal.common.utils; -import static org.gcube.common.authorization.client.Constants.authorizationService; - +import lombok.extern.slf4j.Slf4j; import org.gcube.common.authorization.library.AuthorizationEntry; import org.gcube.common.authorization.library.provider.SecurityTokenProvider; import org.gcube.common.scope.api.ScopeProvider; -import lombok.extern.slf4j.Slf4j; +import static org.gcube.common.authorization.client.Constants.authorizationService; @Slf4j public class ContextUtils { @@ -15,12 +14,12 @@ public class ContextUtils { public static String getCurrentScope(){ try{ String token=SecurityTokenProvider.instance.get(); - log.debug("Token is : "+token.substring(0,2)+"..."+token.substring(token.length()-3)); + log.trace("Token is : "+token.substring(0,2)+"..."+token.substring(token.length()-3)); if(token==null) throw new Exception("Security Token is null"); AuthorizationEntry entry = authorizationService().get(token); return entry.getContext(); }catch(Exception e ){ - log.debug("Unable to resolve token, checking scope provider..",e); + log.trace("Unable to resolve token, checking scope provider..",e); return ScopeProvider.instance.get(); } } @@ -29,12 +28,12 @@ public class ContextUtils { public static String getCurrentCaller(){ try{ String token=SecurityTokenProvider.instance.get(); - log.debug("Token is : "+token.substring(0,2)+"..."+token.substring(token.length()-3)); + log.trace("Token is : "+token.substring(0,2)+"..."+token.substring(token.length()-3)); if(token==null) throw new Exception("Security Token is null"); AuthorizationEntry entry = authorizationService().get(token); return entry.getClientInfo().getId(); }catch(Exception e ){ - log.debug("Unable to resolve token, checking scope provider..",e); + log.trace("Unable to resolve token, checking scope provider..",e); return "Unidentified data-transfer user"; } } diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/utils/FileSets.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/utils/FileSets.java index a70421d..41d0aa7 100644 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/utils/FileSets.java +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/utils/FileSets.java @@ -1,20 +1,29 @@ package org.gcube.application.geoportal.common.utils; +import org.bson.Document; +import org.gcube.application.geoportal.common.model.document.access.Access; import org.gcube.application.geoportal.common.model.legacy.InputStreamDescriptor; -import org.gcube.application.geoportal.common.model.rest.AddSectionToConcessioneRequest; -import org.gcube.application.geoportal.common.rest.TempFile; +import org.gcube.application.geoportal.common.model.rest.RegisterFileSetRequest; +import org.gcube.application.geoportal.common.model.rest.TempFile; import org.gcube.contentmanagement.blobstorage.transport.backend.RemoteBackendException; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.util.ArrayList; +import java.util.Collection; public class FileSets { public static class RequestBuilder { - AddSectionToConcessioneRequest theRequest=new AddSectionToConcessioneRequest(); + RegisterFileSetRequest theRequest=new RegisterFileSetRequest(); + public RequestBuilder addAll(Collection toAdd){ + if(theRequest.getStreams()==null) + theRequest.setStreams(new ArrayList()); + theRequest.getStreams().addAll(toAdd); + return this; + } public RequestBuilder add(TempFile... f){ if(theRequest.getStreams()==null) theRequest.setStreams(new ArrayList()); @@ -30,25 +39,51 @@ public class FileSets { return this; } - public RequestBuilder setPath(String path){ - theRequest.setDestinationPath(path); + public RequestBuilder setFieldDefinitionPath(String path){ + theRequest.setFieldDefinitionPath(path); return this; } + public RequestBuilder setParentPath(String path){ + theRequest.setParentPath(path); + return this; + } + public RequestBuilder setFieldName(String fieldName){ + theRequest.setFieldName(fieldName); + return this; + } + public RequestBuilder setClashPolicy(RegisterFileSetRequest.ClashOptions path){ + theRequest.setClashOption(path); + return this; + } + public RequestBuilder setAttributes(Document attributes){ + theRequest.setAttributes(attributes); + return this; + } + + public RegisterFileSetRequest getTheRequest(){ + if(theRequest.getClashOption()==null) + // default Clash Policy + setClashPolicy(RegisterFileSetRequest.ClashOptions.REPLACE_EXISTING); + return theRequest;} + + public RequestBuilder setAccess(Access access){ + theRequest.setToSetAccess(access); + return this; + } - public AddSectionToConcessioneRequest getTheRequest(){return theRequest;} } - public static RequestBuilder build(String path) { - return new RequestBuilder().setPath(path); + public static RequestBuilder build(String parent,String fieldName, String fieldDefinition) { + return new RequestBuilder().setParentPath(parent).setFieldDefinitionPath(fieldDefinition).setFieldName(fieldName); } - public static RequestBuilder build(String path, TempFile...files) { - return new RequestBuilder().setPath(path).add(files); + public static RequestBuilder build(String parent,String fieldName, String fieldDefinition, TempFile...files) { + return build(parent,fieldName,fieldDefinition).add(files); } public static TempFile asTemp(StorageUtils storage,InputStreamDescriptor descriptor) throws RemoteBackendException, FileNotFoundException { @@ -62,18 +97,19 @@ public class FileSets { return toReturn.toArray(new TempFile[toReturn.size()]); } - public static AddSectionToConcessioneRequest prepareRequestFromFolder(StorageUtils storage, String path, File directory) throws FileNotFoundException { + public static RegisterFileSetRequest prepareRequestFromFolder(StorageUtils storage, + String parentPath,String fieldName,String fieldDefinition, File directory) throws FileNotFoundException { File[] children =directory.listFiles(); - System.out.println("Found "+children+ " files to push"); InputStreamDescriptor[] iss=new InputStreamDescriptor[children.length]; - return prepareRequest(storage,path,children); + return prepareRequest(storage,parentPath,fieldName,fieldDefinition,children); } - public static AddSectionToConcessioneRequest prepareRequest(StorageUtils storage, String path, File... toUpload) throws FileNotFoundException { + public static RegisterFileSetRequest prepareRequest(StorageUtils storage, + String parentPath,String fieldName,String fieldDefinition, File... toUpload) throws FileNotFoundException { - FileSets.RequestBuilder builder = FileSets.build(path); + FileSets.RequestBuilder builder = FileSets.build(parentPath,fieldName,fieldDefinition); for (File f : toUpload) { if(!f.isDirectory()) builder.add(FileSets.asTemp(storage, new InputStreamDescriptor(new FileInputStream(f), f.getName()))); diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/utils/Files.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/utils/Files.java index fc04d6b..98e4fb9 100644 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/utils/Files.java +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/utils/Files.java @@ -1,11 +1,14 @@ package org.gcube.application.geoportal.common.utils; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.IOUtils; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.net.URL; import java.nio.charset.Charset; +import java.nio.file.Path; import java.nio.file.Paths; import java.util.*; @@ -96,6 +99,17 @@ public class Files { toFix=toFix.substring(0,toFix.indexOf(".")); } return toFix.toLowerCase(). - replaceAll("[\\*\\+\\/\\\\ \\[\\]\\(\\)\\.\\\"\\:\\;\\|]","_")+extension; + replaceAll("[\\-\\*\\+\\/\\\\ \\[\\]\\(\\)\\.\\\"\\:\\;\\|\\=]","_")+extension; + } + + public static final File downloadFromUrl(String name,String url) throws IOException { + Path dest =java.nio.file.Files.createTempDirectory("downloads_").resolve(name); + InputStream is = null; + try { + java.nio.file.Files.copy(new URL(url).openStream(), dest); + return dest.toFile(); + }finally { + if(is!=null) IOUtils.closeQuietly(is); + } } } diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/utils/ISUtils.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/utils/ISUtils.java new file mode 100644 index 0000000..97777a7 --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/utils/ISUtils.java @@ -0,0 +1,91 @@ +package org.gcube.application.geoportal.common.utils; + + +import org.gcube.application.geoportal.common.model.rest.ConfigurationException; +import org.gcube.application.geoportal.common.model.rest.DatabaseConnection; +import org.gcube.common.encryption.encrypter.StringEncrypter; +import org.gcube.common.resources.gcore.GenericResource; +import org.gcube.common.resources.gcore.Resource; +import org.gcube.common.resources.gcore.ServiceEndpoint; +import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint; +import org.gcube.informationsystem.publisher.RegistryPublisher; +import org.gcube.informationsystem.publisher.RegistryPublisherFactory; +import org.gcube.resources.discovery.client.api.DiscoveryClient; +import org.gcube.resources.discovery.client.queries.api.SimpleQuery; + +import java.util.List; + +import static org.gcube.resources.discovery.icclient.ICFactory.clientFor; +import static org.gcube.resources.discovery.icclient.ICFactory.queryFor; + +public class ISUtils { + + + public static DatabaseConnection performQueryForDB(String category, String platform,String flagName, String flag) throws ConfigurationException { + + List found=performGetAP(category,platform, flagName,flag); + if(found.size()>1) { + throw new ConfigurationException("Multiple SE found ["+found.size()+"] for platform : "+platform+" flag : "+flag); + }else if (found.isEmpty()){ + throw new ConfigurationException("No SE found for platform : "+platform+" flag : "+flag); + } + AccessPoint point=found.get(0); + + DatabaseConnection toReturn=new DatabaseConnection(); + toReturn.setPwd(decryptString(point.password())); + toReturn.setUser(point.username()); + toReturn.setUrl(point.address()); + return toReturn; + + } + + + public static List performGetAP(String category,String platform,String flagName,String flagValue) { + SimpleQuery query = queryFor(ServiceEndpoint.class); + + query.addCondition("$resource/Profile/Category/text() eq '"+category+"'") + .addCondition("$resource/Profile/Platform/Name/text() eq '"+platform+"'") + .addCondition("$resource/Profile/AccessPoint//Property[Name/text() eq '"+ + flagName+"'][Value/text() eq '"+flagValue+"']") + .setResult("$resource/Profile/AccessPoint"); + + DiscoveryClient client = clientFor(AccessPoint.class); + return client.submit(query); + } + + + public static List getGenericResources(String secondaryType,String name) { + SimpleQuery query = queryFor(GenericResource.class); + + query.addCondition("$resource/Profile/SecondaryType/text() eq '"+secondaryType+"'") + .addCondition("$resource/Profile/Name/text() eq '"+name+"'"); + + DiscoveryClient client = clientFor(GenericResource.class); + return client.submit(query); + } + + + public static T writeGR(T toRegister) { + RegistryPublisher rp= RegistryPublisherFactory.create(); + if(toRegister.scopes().isEmpty()) + return rp.create(toRegister); + else + return rp.update(toRegister); + } + + public static String decryptString(String toDecrypt){ + try{ + return StringEncrypter.getEncrypter().decrypt(toDecrypt); + }catch(Exception e) { + throw new RuntimeException("Unable to decrypt : "+toDecrypt,e); + } + } + + public static String encryptString(String toEncrypt){ + try{ + return StringEncrypter.getEncrypter().encrypt(toEncrypt); + }catch(Exception e) { + throw new RuntimeException("Unable to decrypt : "+toEncrypt,e); + } + } +} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/utils/JSONPathWrapper.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/utils/JSONPathWrapper.java deleted file mode 100644 index 3b0cfdf..0000000 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/utils/JSONPathWrapper.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.gcube.application.geoportal.common.utils; - -import com.jayway.jsonpath.Configuration; -import com.jayway.jsonpath.DocumentContext; -import com.jayway.jsonpath.JsonPath; -import com.jayway.jsonpath.Option; -import lombok.Getter; - -import java.util.List; - -public class JSONPathWrapper { - - public static Configuration JSON_PATH_ALWAYS_LIST_CONFIG=null; - public static Configuration JSON_PATH_PATHS_CONFIGURATION=null; - - static { - JSON_PATH_ALWAYS_LIST_CONFIG= Configuration.builder().options(Option.ALWAYS_RETURN_LIST,Option.SUPPRESS_EXCEPTIONS,Option.DEFAULT_PATH_LEAF_TO_NULL).build(); - JSON_PATH_PATHS_CONFIGURATION = Configuration.builder().options(Option.AS_PATH_LIST,Option.SUPPRESS_EXCEPTIONS,Option.DEFAULT_PATH_LEAF_TO_NULL).build(); - } - - - @Getter - DocumentContext ctx=null; - - public JSONPathWrapper(String json) { - ctx=JsonPath.using(JSON_PATH_ALWAYS_LIST_CONFIG).parse(json); - } - - public List getByPath(String path){ - throw new RuntimeException("TO IMPLEMENT"); - } - - -} diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/utils/StorageUtils.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/utils/StorageUtils.java index 6f383b1..60dd45b 100644 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/utils/StorageUtils.java +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/utils/StorageUtils.java @@ -1,20 +1,19 @@ package org.gcube.application.geoportal.common.utils; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.InputStream; -import java.util.UUID; - +import lombok.extern.slf4j.Slf4j; +import org.gcube.application.geoportal.common.faults.StorageException; +import org.gcube.application.geoportal.common.model.rest.TempFile; import org.gcube.application.geoportal.common.rest.InterfaceConstants; -import org.gcube.application.geoportal.common.rest.TempFile; import org.gcube.contentmanagement.blobstorage.service.IClient; import org.gcube.contentmanagement.blobstorage.transport.backend.RemoteBackendException; import org.gcube.contentmanager.storageclient.wrapper.AccessType; import org.gcube.contentmanager.storageclient.wrapper.MemoryType; import org.gcube.contentmanager.storageclient.wrapper.StorageClient; -import lombok.extern.slf4j.Slf4j; +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.UUID; @Slf4j public class StorageUtils { @@ -36,7 +35,7 @@ public class StorageUtils { public TempFile putOntoStorage(InputStream source,String filename) throws RemoteBackendException, FileNotFoundException{ log.debug("Uploading source "+filename); String id=client.put(true).LFile(source).RFile(getUniqueString()); - return new TempFile(id,filename); + return new TempFile(id,null,filename); } @@ -74,4 +73,13 @@ public class StorageUtils { public static final String getUniqueString(){ return UUID.randomUUID().toString(); } + + public File download(String id,String name) throws IOException, StorageException { + Path p = Files.createTempDirectory(id).resolve(name); + + client.get().LFile(p.toAbsolutePath().toString()).RFile(id); + File toReturn =p.toFile(); + if(!toReturn.exists()) throw new StorageException("Unable to download "+id); + return p.toFile(); + } } diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/utils/tests/GCubeTest.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/utils/tests/GCubeTest.java new file mode 100644 index 0000000..2b54862 --- /dev/null +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/utils/tests/GCubeTest.java @@ -0,0 +1,32 @@ +package org.gcube.application.geoportal.common.utils.tests; + +public class GCubeTest { + + public static String getContext() { + String testContext=null; + testContext = System.getProperty("testContext"); + if(testContext==null) { + // trying with env + testContext=System.getenv("testContext"); + } + + +// testContext = "/pred4s/preprod/preVRE"; +// InterfaceConstants.SERVICE_CLASS="Application"; +// InterfaceConstants.SERVICE_NAME="GeoPortal"; + + testContext = "/gcube/devsec/devVRE"; + + + System.out.println("TEST CONTEXT = "+testContext); + return testContext; + } + + + + public static boolean isTestInfrastructureEnabled() { + return getContext()!=null; + } + + +} diff --git a/geoportal-common/src/test/java/org/gcube/application/geoportal/common/JacksonProvider.java b/geoportal-common/src/test/java/org/gcube/application/geoportal/common/JacksonProvider.java new file mode 100644 index 0000000..f75d6bb --- /dev/null +++ b/geoportal-common/src/test/java/org/gcube/application/geoportal/common/JacksonProvider.java @@ -0,0 +1,38 @@ +package org.gcube.application.geoportal.common; + +import com.jayway.jsonpath.Configuration; +import com.jayway.jsonpath.Option; +import com.jayway.jsonpath.spi.json.JacksonJsonProvider; +import com.jayway.jsonpath.spi.json.JsonProvider; +import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider; +import com.jayway.jsonpath.spi.mapper.MappingProvider; + +import java.util.EnumSet; +import java.util.Set; + +public class JacksonProvider implements JSONSerializationProvider { + + + @Override + public void setJSONWrapperDefaults() { + Configuration.setDefaults(new Configuration.Defaults() { + private JsonProvider jacksonProvider = new JacksonJsonProvider(); + + private final MappingProvider mappingProvider = new JacksonMappingProvider(); + @Override + public JsonProvider jsonProvider() { + return jacksonProvider; + } + + @Override + public Set