first commit. smartgear service, keycloack client prototipe
This commit is contained in:
commit
493961ad0b
|
@ -0,0 +1,171 @@
|
|||
# originale
|
||||
target
|
||||
.classpath
|
||||
.visual
|
||||
.project
|
||||
.settings
|
||||
/**/.DS_Store
|
||||
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/java,macos,linux,visualstudiocode,eclipse
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=java,macos,linux,visualstudiocode,eclipse
|
||||
|
||||
### Eclipse ###
|
||||
.metadata
|
||||
bin/
|
||||
tmp/
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*~.nib
|
||||
local.properties
|
||||
.settings/
|
||||
.loadpath
|
||||
.recommenders
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
|
||||
# Locally stored "Eclipse launch configurations"
|
||||
*.launch
|
||||
|
||||
# PyDev specific (Python IDE for Eclipse)
|
||||
*.pydevproject
|
||||
|
||||
# CDT-specific (C/C++ Development Tooling)
|
||||
.cproject
|
||||
|
||||
# CDT- autotools
|
||||
.autotools
|
||||
|
||||
# Java annotation processor (APT)
|
||||
.factorypath
|
||||
|
||||
# PDT-specific (PHP Development Tools)
|
||||
.buildpath
|
||||
|
||||
# sbteclipse plugin
|
||||
.target
|
||||
|
||||
# Tern plugin
|
||||
.tern-project
|
||||
|
||||
# TeXlipse plugin
|
||||
.texlipse
|
||||
|
||||
# STS (Spring Tool Suite)
|
||||
.springBeans
|
||||
|
||||
# Code Recommenders
|
||||
.recommenders/
|
||||
|
||||
# Annotation Processing
|
||||
.apt_generated/
|
||||
.apt_generated_test/
|
||||
|
||||
# Scala IDE specific (Scala & Java development for Eclipse)
|
||||
.cache-main
|
||||
.scala_dependencies
|
||||
.worksheet
|
||||
|
||||
# Uncomment this line if you wish to ignore the project description file.
|
||||
# Typically, this file would be tracked if it contains build/dependency configurations:
|
||||
#.project
|
||||
|
||||
### Eclipse Patch ###
|
||||
# Spring Boot Tooling
|
||||
.sts4-cache/
|
||||
|
||||
### Java ###
|
||||
# Compiled class file
|
||||
*.class
|
||||
|
||||
# Log file
|
||||
*.log
|
||||
|
||||
# BlueJ files
|
||||
*.ctxt
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.nar
|
||||
*.ear
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
replay_pid*
|
||||
|
||||
### Linux ###
|
||||
*~
|
||||
|
||||
# temporary files which can be created if a process still has a handle open of a deleted file
|
||||
.fuse_hidden*
|
||||
|
||||
# KDE directory preferences
|
||||
.directory
|
||||
|
||||
# Linux trash folder which might appear on any partition or disk
|
||||
.Trash-*
|
||||
|
||||
# .nfs files are created when an open file is removed but is still being accessed
|
||||
.nfs*
|
||||
|
||||
### macOS ###
|
||||
# General
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
### macOS Patch ###
|
||||
# iCloud generated files
|
||||
*.icloud
|
||||
|
||||
### VisualStudioCode ###
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
!.vscode/*.code-snippets
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Built Visual Studio Code Extensions
|
||||
*.vsix
|
||||
|
||||
### VisualStudioCode Patch ###
|
||||
# Ignore all local history of files
|
||||
.history
|
||||
.ionide
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/java,macos,linux,visualstudiocode,eclipse
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"java.compile.nullAnalysis.mode": "automatic",
|
||||
"java.configuration.updateBuildConfiguration": "automatic"
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
# Changelog for Identity Manager Service
|
||||
|
||||
|
||||
## [v1.0.0-SNAPSHOT]
|
||||
|
||||
- First Version
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
FROM smartgears-distribution:4.0.0-java11-tomcat9
|
||||
ARG REPOUSER=admin
|
||||
ARG REPOPWD=admin
|
||||
COPY ./target/identity-manager.war /tomcat/webapps/
|
||||
# COPY ./docker/storagehub.xml /tomcat/conf/Catalina/localhost/
|
||||
COPY ./docker/logback.xml /etc/
|
||||
COPY ./docker/container.ini /etc/
|
||||
RUN unzip /tomcat/webapps/identity-manager.war -d /tomcat/webapps/identity-manager
|
||||
RUN rm /tomcat/webapps/identity-manager.war
|
||||
# COPY ./docker/storage-settings.properties /tomcat/webapps/identity-manager/WEB-INF/classes/
|
||||
RUN sed -i "s/{{adminId}}/$REPOUSER/g; s/{{adminPwd}}/$REPOPWD/g" /tomcat/webapps/storagehub/WEB-INF/web.xml
|
|
@ -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);
|
|
@ -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
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
# Identity Manager Service
|
||||
|
||||
This service allows any client to publish on the gCube Catalogue.
|
||||
|
||||
## Built With
|
||||
|
||||
* [OpenJDK](https://openjdk.java.net/) - The JDK used
|
||||
* [Maven](https://maven.apache.org/) - Dependency Management
|
||||
|
||||
## Documentation
|
||||
|
||||
[Identity Manager Service](https://wiki.gcube-system.org/gcube/SmartGears)
|
||||
|
||||
## Change log
|
||||
|
||||
See [CHANGELOG.md](CHANGELOG.md).
|
||||
|
||||
## Authors
|
||||
|
||||
* **Alfredo Oliviero** [ISTI-CNR Infrascience Group](http://nemis.isti.cnr.it/groups/infrascience)
|
||||
* **Luca Frosini** ([ORCID](https://orcid.org/0000-0003-3183-2291)) - [ISTI-CNR Infrascience Group](http://nemis.isti.cnr.it/groups/infrascience)
|
||||
|
||||
## How to Cite this Software
|
||||
|
||||
Tell people how to cite this software.
|
||||
* Cite an associated paper?
|
||||
* Use a specific BibTeX entry for the software?
|
||||
|
||||
@software{gcat,
|
||||
author = {{Alfredo Oliviero}},
|
||||
title = {Identity Manager Service},
|
||||
abstract = {This is an Identity Manager smargears service},
|
||||
url = {doi Zenodo URL}
|
||||
keywords = {D4Science, gCube}
|
||||
}
|
||||
|
||||
## 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 see [FUNDING.md](FUNDING.md)
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<!-- // da implementare rispetto al contesto -->
|
||||
|
||||
/2/users/get-profile // profilo utente corrente
|
||||
/2/users/get-email // utente corrente
|
||||
/2/users/get-fullname // utente corrente
|
||||
|
||||
/2/users/get-all-usernames
|
||||
/2/users/get-all-fullnames-and-usernames
|
||||
/2/users/get-usernames-by-role
|
||||
/2/users/user-exists
|
||||
|
||||
// attenzione al risultato. vedere in seguito
|
||||
/2/users/get-oauth-profile
|
||||
|
||||
// eventualemente in seguito. da approfondire
|
||||
/2/users/get-custom-attribute
|
||||
/2/users/get-usernames-by-global-role
|
||||
|
||||
rif. https://api.dev.d4science.org/social-networking-library-ws/api-docs/index.html
|
||||
|
||||
implementazione social: https://code-repo.d4science.org/gCubeSystem/social-networking-library-ws/src/branch/master/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Users.java
|
|
@ -0,0 +1,23 @@
|
|||
eseguendo ```mvn install``` su gcat, ricevo questo errore
|
||||
|
||||
[ERROR] Failed to execute goal org.codehaus.gmaven:groovy-maven-plugin:2.1.1:execute (default) on project gcat: Execution default of goal org.codehaus.gmaven:groovy-maven-plugin:2.1.1:execute failed: startup failed:
|
||||
[ERROR] script1.groovy: 1: expecting EOF, found 'matcher' @ line 1, column 100.
|
||||
[ERROR] ANGELOG.md").getText('UTF-8') matcher =
|
||||
[ERROR] ^
|
||||
[ERROR]
|
||||
[ERROR] 1 error
|
||||
[ERROR]
|
||||
|
||||
|
||||
https://maven.d4science.org/nexus/content/repositories/gcube-externals/org/gcube/tools/maven-parent/1.1.0/maven-parent-1.1.0.pom
|
||||
|
||||
|
||||
|
||||
cd ~/.m2/repository
|
||||
grep -R "getText('UTF-8') matcher" .
|
||||
|
||||
|
||||
<source> def fileContents = new File("${project.basedir}/CHANGELOG.md").getText('UTF-8') matcher = (fileContents =~ /(?s).\[v$project.version\].*?/) if (!matcher.find()) { throw new IllegalArgumentException("Tag [v$project.version] not found in ${project.basedir}/CHANGELOG.md") } assert matcher[0][1]: "Tag [v$project.version] not found in ${project.basedir}/CHANGELOG.md" </source>
|
||||
</configuration>
|
||||
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
[node]
|
||||
mode = online
|
||||
hostname = alfredo-idm-service-dev
|
||||
protocol= http
|
||||
port = 8080
|
||||
infrastructure = gcube
|
||||
authorizeChildrenContext = true
|
||||
publicationFrequencyInSeconds = 60
|
||||
|
||||
[properties]
|
||||
SmartGearsDistribution = 4.0.0-SNAPSHOT
|
||||
SmartGearsDistributionBundle = UnBundled
|
||||
|
||||
[site]
|
||||
country = it
|
||||
location = pisa
|
||||
|
||||
[authorization]
|
||||
factory = org.gcube.smartgears.security.defaults.DefaultAuthorizationProviderFactory
|
||||
factory.endpoint = https://accounts.dev.d4science.org/auth/realms/d4science/protocol/openid-connect/token
|
||||
credentials.class = org.gcube.smartgears.security.SimpleCredentials
|
||||
; credentials.clientID = node-whn-test-uno-d-d4s.d4science.org
|
||||
; credentials.secret = 979bd3bc-5cc4-11ec-bf63-0242ac130002
|
||||
credentials.clientID = alfredo-idm-service-dev
|
||||
credentials.secret = 979bd3bc-5cc4-11ec-bf63-0242ac130002
|
|
@ -0,0 +1,25 @@
|
|||
<configuration scan="true" debug="true">
|
||||
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>Ï
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
|
||||
|
||||
<logger name="org.gcube" level="DEBUG" />
|
||||
<logger name="org.gcube.smartgears" level="TRACE" />
|
||||
<logger name="org.gcube.smartgears.handlers" level="TRACE"/>
|
||||
<logger name="org.gcube.common.events" level="WARN" />
|
||||
<logger name="org.gcube.data.publishing" level="ERROR" />
|
||||
<logger name="org.gcube.documentstore" level="ERROR" />
|
||||
<logger name="org.gcube.common.core.publisher.is.legacy" level="TRACE" />
|
||||
<logger name="org.gcube.data.access" level="TRACE" />
|
||||
<logger name="org.gcube.data.access.storagehub.handlers" level="DEBUG"/>
|
||||
|
||||
<root level="WARN">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
|
@ -0,0 +1 @@
|
|||
/_build/
|
|
@ -0,0 +1,20 @@
|
|||
# Minimal makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line, and also
|
||||
# from the environment for the first two.
|
||||
SPHINXOPTS ?=
|
||||
SPHINXBUILD ?= sphinx-build
|
||||
SOURCEDIR = .
|
||||
BUILDDIR = _build
|
||||
|
||||
# Put it first so that "make" without argument is like "make help".
|
||||
help:
|
||||
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
|
||||
.PHONY: help Makefile
|
||||
|
||||
# Catch-all target: route all unknown targets to Sphinx using the new
|
||||
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
||||
%: Makefile
|
||||
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
|
@ -0,0 +1,54 @@
|
|||
# Configuration file for the Sphinx documentation builder.
|
||||
#
|
||||
# This file only contains a selection of the most common options. For a full
|
||||
# list see the documentation:
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
||||
|
||||
# -- Path setup --------------------------------------------------------------
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#
|
||||
# import os
|
||||
# import sys
|
||||
# sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
project = 'gCube Catalogue (gCat) Service'
|
||||
copyright = '2022, Luca Frosini (ISTI-CNR)'
|
||||
author = 'Luca Frosini (ISTI-CNR)'
|
||||
|
||||
# The full version, including alpha/beta/rc tags
|
||||
release = '2.5.1'
|
||||
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = []
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
# This pattern also affects html_static_path and html_extra_path.
|
||||
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
||||
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
#
|
||||
html_theme = 'sphinxdoc'
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
|
@ -0,0 +1,484 @@
|
|||
---
|
||||
title: Welcome to gCube Catalogue Service (aka gCat) documentation
|
||||
---
|
||||
|
||||
gCat is a RESTful application which exposes operations via REST-API.
|
||||
|
||||
See the available [REST-API docs](../api-docs/index.html).
|
||||
|
||||
Base URL
|
||||
========
|
||||
|
||||
In the production environment, its current value is
|
||||
<https://api.d4science.org/gcat>
|
||||
|
||||
Authorization
|
||||
=============
|
||||
|
||||
D4Science adopts state-of-the-art industry standards for authentication
|
||||
and authorization. Specifically, the implementation fully adopts [OIDC
|
||||
(OpenID Connect)](https://openid.net/connect) for authentication and UMA
|
||||
2 (User-Managed Authorization) for authorization flows. [JSON Web Token
|
||||
(JWT) Access token](https://jwt.io/) are used for both authentication
|
||||
and authorization.
|
||||
|
||||
Obtain your Bearer token here:
|
||||
<https://dev.d4science.org/how-to-access-resources>
|
||||
|
||||
Service
|
||||
=======
|
||||
|
||||
You can call the methods of the Web Service by writing your own REST
|
||||
client application or using existing REST client plugins.
|
||||
|
||||
HTTP Statuses
|
||||
-------------
|
||||
|
||||
Any successful operation returns *200 OK* HTTP status code. The create
|
||||
operation returns *201 Created*. Any Background operation returns *202
|
||||
Accepted*. Any operation which does not provide any content return *204
|
||||
No Content*.
|
||||
|
||||
The most common error status a client can obtain are:
|
||||
|
||||
- **400 Bad Request** used to indicate a clients error
|
||||
<https://tools.ietf.org/html/rfc7231#section-6.5.1>;
|
||||
- **401 Unauthorized** used to indicate that the client does not
|
||||
provide the authorization token in the HTTP Header or the client has
|
||||
not enough right to perform such request
|
||||
<https://tools.ietf.org/html/rfc7235#section-3.1>;
|
||||
- **404 Not Found** used to indicate that the requested instance does
|
||||
not exist <https://tools.ietf.org/html/rfc7231#section-6.5.4>;
|
||||
- **405 Method Not Allowed** the used HTTP method is not supported for
|
||||
the requested URL
|
||||
<https://tools.ietf.org/html/rfc7231#section-6.5.5>. The response
|
||||
contains the *Allow* HTTP Header indicating the supported HTTP
|
||||
method for such URL
|
||||
<https://tools.ietf.org/html/rfc7231#section-7.4.1>;
|
||||
- **409 Conflict** the request could not be completed due to a
|
||||
conflict with the current state of the target resource (e.g. the
|
||||
name of the resource already exists)
|
||||
<https://tools.ietf.org/html/rfc7231#section-6.5.8>;
|
||||
- **500 Internal Server Error** indicate a server failure
|
||||
<https://tools.ietf.org/html/rfc7231#section-6.6.1>.
|
||||
|
||||
You can find a complete list of HTTP Status at
|
||||
<https://httpstatuses.com/>
|
||||
|
||||
If you get a *500 Internal Server Error*, please report it in the [gCube
|
||||
ticketing system](https://support.d4science.org).
|
||||
|
||||
Please use this checklist before reporting an error:
|
||||
|
||||
- Replicate the request;
|
||||
- The failure could be temporal due to network error, server issue and
|
||||
many other temporal issues. For this reason, please retry the
|
||||
request after a certain amount of time before reporting the issue;
|
||||
- indicate how to replicate the error;
|
||||
- indicate the time when the error occurred (this simplifies
|
||||
identifying the issue).
|
||||
|
||||
HTTP Methods
|
||||
------------
|
||||
|
||||
gCat is a pure RESTful service. It uses standard HTTP Methods to perform
|
||||
listing of collections and CRUD (Create Read Update Delete) operations
|
||||
on instances.
|
||||
|
||||
:::{table} Supported operations
|
||||
:align: center
|
||||
:widths: grid
|
||||
|
||||
|
||||
| Operation | HTTP Method | URL | Success HTTP Status | Safe | Idempotent |
|
||||
|-----------|-------------|-----|---------------------|------|------------|
|
||||
| **Supported<br/>HTTP Methods** | OPTIONS | /{COLLECTION} | 204 No Content | Y | Y |
|
||||
| **List** | GET | /{COLLECTION} | 200 OK | Y | Y |
|
||||
| **Count** | GET | /{COLLECTION}?count=true | 200 OK | Y | Y |
|
||||
| **Exists** | HEAD | /{COLLECTION} | 204 No Content | Y | Y |
|
||||
| **Create** | POST | /{COLLECTION} | 201 Created | N | N |
|
||||
| **Supported<br/>HTTP Methods** | OPTIONS | /{COLLECTION}/{INSTANCE_ID} | 204 No Content | Y | Y |
|
||||
| **Exist** | HEAD | /{COLLECTION}/{INSTANCE_ID} | 204 No Content | Y | Y |
|
||||
| **Read** | GET | /{COLLECTION}/{INSTANCE_ID} | 200 OK | Y | Y |
|
||||
| **Update** | PUT | /{COLLECTION}/{INSTANCE_ID} | 200 OK | N | Y |
|
||||
| **Patch** | PATCH | /{COLLECTION}/{INSTANCE_ID} | 200 OK | N | Y |
|
||||
| **Delete** | DELETE | /{COLLECTION}/{INSTANCE_ID} | 204 No Content | N | N |
|
||||
| **Purge** | PURGE | /{COLLECTION}/{INSTANCE_ID} | 204 No Content | N | N |
|
||||
| **Purge** | DELETE | /{COLLECTION}/{INSTANCE_ID}?purge=true | 204 No Content | N | N |
|
||||
|
||||
|
||||
### About URL
|
||||
|
||||
The presented URL uses the following convention:
|
||||
|
||||
- **{COLLECTION}** is the plural name of the entity type;
|
||||
- **{INSTANCE\_ID}** is an identification that enables univocally
|
||||
identifying the instance in the collection.
|
||||
|
||||
### About Safety and Idempotency properties
|
||||
|
||||
- A method is *Safe* if it does not produce any side effects. \"This
|
||||
does not prevent an implementation from including behaviour that is
|
||||
potentially harmful, that is not entirely read-only, or that causes
|
||||
side effects while invoking a safe method\"
|
||||
<https://tools.ietf.org/html/rfc7231#section-4.2.1>;
|
||||
- A method is *Idempotent* if the same operation repeated multiple
|
||||
times has the same side effect than using it one time. \"repeating
|
||||
the request will have the same intended effect, even if the original
|
||||
request succeeded, though the response might differ\"
|
||||
<https://tools.ietf.org/html/rfc7231#section-4.2.2>.
|
||||
|
||||
You can find more information about HTTP Methods at
|
||||
<https://restfulapi.net/http-methods/>
|
||||
|
||||
### Uncommon HTTP Methods
|
||||
|
||||
- PATCH method allows to perform a differential update (i.e. an update
|
||||
which provides only the differences and not the whole new
|
||||
representation);
|
||||
- PURGE method is not a standard but is widely used in service which
|
||||
requires this action (e.g.
|
||||
[Varnish](https://varnish-cache.org/docs/3.0/tutorial/purging.html),
|
||||
[Squid](https://wiki.squid-cache.org/SquidFaq/OperatingSquid#How_can_I_purge_an_object_from_my_cache.3F)).
|
||||
gCat provides support for this method, but to support a wider range
|
||||
of clients, it also provides the Purge action via *DELETE* with the
|
||||
additional get parameter `purge=true`.
|
||||
|
||||
Content-Type
|
||||
------------
|
||||
|
||||
Any request must contain an indication of the interesting content type.
|
||||
|
||||
The client must specify the **Accept** HTTP Header for any operation
|
||||
returning a result.
|
||||
|
||||
``` {.rest}
|
||||
Accept: application/json
|
||||
```
|
||||
|
||||
For any operation sending content to the service, it is necessary to
|
||||
specify the **Content-Type** HTTP Header.
|
||||
|
||||
``` {.rest}
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
The service accepts and returns only JSON objects.
|
||||
|
||||
[Profile Collection](../api-docs/resource\_Profile.html) instead can be
|
||||
manipulated in XML only.
|
||||
|
||||
Collections
|
||||
-----------
|
||||
|
||||
The following collections are available to any user. Catalogue-Editor or
|
||||
above can invoke Non-safe methods only.
|
||||
|
||||
- [Item Collection](../api-docs/resource_Item.html);
|
||||
- [Resource Collection](../api-docs/resource_Resource.html);
|
||||
- [Profile Collection](../api-docs/resource_Profile.html);
|
||||
- [Namespace Collection](../api-docs/resource_Namespace.html);
|
||||
- [License Collection](../api-docs/resource_License.html);
|
||||
- [Trash Collection](../api-docs/resource_Trash.html);
|
||||
|
||||
The following collections are available for Catalogue-Admins or above
|
||||
only:
|
||||
|
||||
- [Group Collection](../api-docs/resource_Group.html);
|
||||
- [Organization Collection](../api-docs/resource_Organization.html);
|
||||
- [User Collection](../api-docs/resource_User.html);
|
||||
- [Configuration Collection](../api-docs/resource_Configuration.html).
|
||||
|
||||
An overview of the available collections is available at
|
||||
[../api-docs/index.html](../api-docs/index.html);
|
||||
|
||||
Roles
|
||||
-----
|
||||
|
||||
Any user has one or more roles in the catalogue. Only the VRE Manager
|
||||
can assign roles to VRE users.
|
||||
|
||||
The catalogue uses the following hierarchic roles:
|
||||
|
||||
**Catalogue-Member**:
|
||||
|
||||
: A user with such a role is mainly capable of listing and reading
|
||||
items;
|
||||
|
||||
**Catalogue-Editor**:
|
||||
|
||||
: A user with such a role is capable of managing the items he/she
|
||||
creates and capable of using other safe APIs;
|
||||
|
||||
**Catalogue-Admin**:
|
||||
|
||||
: A user with such a role is capable of administrating many aspects of
|
||||
the catalogue;
|
||||
|
||||
**Catalogue-Manager**:
|
||||
|
||||
: A user with such a role can use all the APIs exposed by the service
|
||||
except item moderation APIs (e.g. approve, reject, \...).
|
||||
|
||||
Another role that is not in the role hierarchy:
|
||||
|
||||
**Catalogue-Moderator**:
|
||||
|
||||
: A user with such a role is capable of invoking the item moderation
|
||||
APIs.
|
||||
|
||||
::: {.tip}
|
||||
::: {.title}
|
||||
Tip
|
||||
:::
|
||||
:::
|
||||
|
||||
Please note that not all catalogues are moderated.
|
||||
|
||||
Moderated Catalogues
|
||||
====================
|
||||
|
||||
Any catalogues can be declared as moderated. This means that, a
|
||||
**Catalogue-Moderator** must approve any submitted items to make them
|
||||
available to the other users of the catalogue.
|
||||
|
||||
In a moderated catalogue, an item can be in the following states:
|
||||
|
||||
**pending**:
|
||||
|
||||
: The item published by any allowed author (a Catalogue-Editor or
|
||||
above) but not available to the other users of the catalogue. A
|
||||
Catalogue-Moderator has to approve or reject it;
|
||||
|
||||
**approved**:
|
||||
|
||||
: A Catalogue-Moderator has approved the item published by any allowed
|
||||
users;
|
||||
|
||||
**rejected**:
|
||||
|
||||
: A Catalogue-Moderator has rejected the item published by any allowed
|
||||
users.
|
||||
|
||||
The following are the moderation operations that an allowed user can
|
||||
perform on an item. To present the moderation operations, we use the
|
||||
following convention:
|
||||
|
||||
> `initial_state` \-\--**operation** (*User/Role performing the
|
||||
> operation*)\-\--\> `final_state`
|
||||
|
||||
`initial_state` can be `none`, meaning the item does not exist.
|
||||
|
||||
The following are the allowed moderation operation on an item
|
||||
|
||||
> `none` \-\--**create** (*Author*)\-\--\> `pending`
|
||||
>
|
||||
> `pending` \-\--**reject** (*Catalogue-Moderator*)\-\--\> `rejected`
|
||||
>
|
||||
> `pending` \-\--**approve** (*Catalogue-Moderator*)\-\--\> `approved`
|
||||
>
|
||||
> `rejected` \-\--**update** (*Author*)\-\--\> `pending`
|
||||
>
|
||||
> `approved` \-\--**update** (*Author*)\-\--\> `pending`
|
||||
|
||||
Please check the table below whcih summarise the item collection
|
||||
operation and the allowed users/roles.
|
||||
|
||||
In a moderated catalogue, both the Catalogue-Moderators and the item
|
||||
author can send messages to discuss the approval process of the item.
|
||||
The messages are related to a specific item. Any Catalogue-Moderators
|
||||
receive a message sent by an Author. The author receives a message sent
|
||||
by a Catalogue-Moderator as well as the other Catalogue-Moderators (if
|
||||
any).
|
||||
|
||||
Messages can be sent both with an action which changes the status of the
|
||||
item or as explicit action which does not change the status of the item:
|
||||
|
||||
> `pending` \-\--**message** (*Author OR Catalogue-Moderator*)\-\--\>
|
||||
> `pending`
|
||||
>
|
||||
> `rejected` \-\--**message** (*Author OR Catalogue-Moderator*)\-\--\>
|
||||
> `rejected`
|
||||
>
|
||||
> `approved` \-\--**message** (*Author OR Catalogue-Moderator*)\-\--\>
|
||||
> `approved`
|
||||
|
||||
The following table summarize the allowed/forbidden operations depending
|
||||
on: the role of the user and the state of the item.
|
||||
|
||||
The Moderation process has associated notification to authors and
|
||||
Catalogue-Moderators. Please note that the user who has acted is not
|
||||
self-notified, e.g. approve operation made by a Catalogue-Moderator
|
||||
notifies the item author and the other Catalogue-Moderators of the VRE.
|
||||
|
||||
The following table summarises the addressee of the notification for any
|
||||
action.
|
||||
|
||||
Java Client
|
||||
===========
|
||||
|
||||
We provide the following Java Client out-of-the-box.
|
||||
|
||||
> ::: {.tip}
|
||||
> ::: {.title}
|
||||
> Tip
|
||||
> :::
|
||||
>
|
||||
> If you\'re coding in Java, it is recommended that you use this Java
|
||||
> Client.
|
||||
> :::
|
||||
|
||||
**Maven Coordinates**
|
||||
|
||||
``` {.xml}
|
||||
<groupId>org.gcube.data-catalogue</groupId>
|
||||
<artifactId>gcat-client</artifactId>
|
||||
<version>[2.2.0, 3.0.0-SNAPSHOT)</version>
|
||||
```
|
||||
|
||||
**Methods Result**
|
||||
|
||||
The service exposes [its methods](../api-docs/index.html) using a
|
||||
standard naming approach. Moreover, they accept (in the case of HTTP
|
||||
POST/PUT methods) JSON objects.
|
||||
|
||||
> ::: {.important}
|
||||
> ::: {.title}
|
||||
> Important
|
||||
> :::
|
||||
>
|
||||
> The result of all methods is always a JSON object as per below:
|
||||
> :::
|
||||
|
||||
``` {.javascript}
|
||||
{
|
||||
"rating": 0.0,
|
||||
"license_title": "Creative Commons Attribution Share-Alike 4.0",
|
||||
"maintainer": "Frosini Luca",
|
||||
"relationships_as_object": [],
|
||||
"private": false,
|
||||
"maintainer_email": "luca.frosini@isti.cnr.it",
|
||||
"num_tags": 1,
|
||||
"id": "17051d86-c127-4928-9296-d3d7590161fe",
|
||||
"metadata_created": "2022-10-17T12:45:53.118318",
|
||||
"metadata_modified": "2022-10-18T10:30:03.362756",
|
||||
"author": "Frosini Luca",
|
||||
"author_email": "luca.frosini@isti.cnr.it",
|
||||
"state": "active",
|
||||
"version": null,
|
||||
"creator_user_id": "f1b0265c-9983-4f97-a7b6-be3cc0544b27",
|
||||
"type": "dataset",
|
||||
"resources": [],
|
||||
"num_resources": 0,
|
||||
"tags": [
|
||||
{
|
||||
"vocabulary_id": null,
|
||||
"state": "active",
|
||||
"display_name": "Test",
|
||||
"id": "fec9de86-51a2-41b0-aef4-ba06eb39e16d",
|
||||
"name": "Test"
|
||||
}
|
||||
],
|
||||
"groups": [],
|
||||
"license_id": "CC-BY-SA-4.0",
|
||||
"relationships_as_subject": [],
|
||||
"organization": {
|
||||
"description": "",
|
||||
"created": "2016-05-30T11:30:41.710079",
|
||||
"title": "devVRE",
|
||||
"name": "devvre",
|
||||
"is_organization": true,
|
||||
"state": "active",
|
||||
"image_url": "",
|
||||
"revision_id": "a7eee485-a6d5-4a7b-8f73-b0ed999d5b03",
|
||||
"type": "organization",
|
||||
"id": "3571cca5-b0ae-4dc6-b791-434a8e062ce5",
|
||||
"approval_status": "approved"
|
||||
},
|
||||
"name": "my_test_item_devvre",
|
||||
"isopen": true,
|
||||
"url": "http://www.d4science.org",
|
||||
"notes": "A test item of Luca Frosini",
|
||||
"extras": [
|
||||
{
|
||||
"key": "Item URL",
|
||||
"value": "https://data.dev.d4science.org/ctlg/devVRE/my_test_item_devvre"
|
||||
},
|
||||
{
|
||||
"key": "Language",
|
||||
"value": "EN"
|
||||
},
|
||||
{
|
||||
"key": "system:cm_item_status",
|
||||
"value": "approved"
|
||||
},
|
||||
{
|
||||
"key": "system:cm_item_visibility",
|
||||
"value": "public"
|
||||
},
|
||||
{
|
||||
"key": "system:type",
|
||||
"value": "EmptyProfile"
|
||||
}
|
||||
],
|
||||
"license_url": "https://creativecommons.org/licenses/by-sa/4.0/",
|
||||
"ratings_count": 0,
|
||||
"title": "My Test Item",
|
||||
"revision_id": "bc0d1f2a-4e97-4810-b951-8b72e8279719"
|
||||
}
|
||||
```
|
||||
|
||||
*Inputs are automatically validated before the request is served.*
|
||||
|
||||
**Usage examples**
|
||||
|
||||
- Example 1
|
||||
|
||||
``` {.java}
|
||||
import org.gcube.gcat.client.Item;
|
||||
|
||||
// count item number
|
||||
Item item = new Item();
|
||||
int count = item.count();
|
||||
...
|
||||
```
|
||||
|
||||
Service Discovery on IS
|
||||
=======================
|
||||
|
||||
The service can be discovered in the gCore IS as gCore Endpoint with the
|
||||
following parameter:
|
||||
|
||||
``` {.xml}
|
||||
<ServiceClass>org.gcube.data-catalogue</ServiceClass>
|
||||
<ServiceName>gcat</ServiceName>
|
||||
```
|
||||
|
||||
The service can be discovered in the Facet Based IS as EService with the
|
||||
following json query:
|
||||
|
||||
``` {.json}
|
||||
{
|
||||
"@class": "EService",
|
||||
"consistsOf": [
|
||||
{
|
||||
"@class": "IsIdentifiedBy",
|
||||
"target": {
|
||||
"@class": "SoftwareFacet",
|
||||
"group": "org.gcube.data-catalogue",
|
||||
"name": "gcat"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Service Maven Coordinates
|
||||
=========================
|
||||
|
||||
The maven coordinates of gCat service are:
|
||||
|
||||
``` {.xml}
|
||||
<groupId>org.gcube.data-catalogue</groupId>
|
||||
<artifactId>gcat</artifactId>
|
||||
```
|
|
@ -0,0 +1,510 @@
|
|||
|
||||
***********************************************************
|
||||
Welcome to gCube Catalogue Service (aka gCat) documentation
|
||||
***********************************************************
|
||||
|
||||
gCat is a RESTful application which exposes operations via REST-API.
|
||||
|
||||
See the available `REST-API docs <../api-docs/index.html>`_.
|
||||
|
||||
Base URL
|
||||
========
|
||||
|
||||
In the production environment, its current value is https://api.d4science.org/gcat
|
||||
|
||||
|
||||
Authorization
|
||||
=============
|
||||
|
||||
D4Science adopts state-of-the-art industry standards for authentication and authorization.
|
||||
Specifically, the implementation fully adopts `OIDC (OpenID Connect) <https://openid.net/connect>`_ for authentication and UMA 2 (User-Managed Authorization) for authorization flows.
|
||||
`JSON Web Token (JWT) Access token <https://jwt.io/>`_ are used for both authentication and authorization.
|
||||
|
||||
Obtain your Bearer token here: https://dev.d4science.org/how-to-access-resources
|
||||
|
||||
Service
|
||||
=======
|
||||
|
||||
You can call the methods of the Web Service by writing your own REST client application or using existing REST client plugins.
|
||||
|
||||
|
||||
HTTP Statuses
|
||||
-------------
|
||||
|
||||
Any successful operation returns *200 OK* HTTP status code.
|
||||
The create operation returns *201 Created*.
|
||||
Any Background operation returns *202 Accepted*.
|
||||
Any operation which does not provide any content return *204 No Content*.
|
||||
|
||||
|
||||
|
||||
The most common error status a client can obtain are:
|
||||
|
||||
* **400 Bad Request** used to indicate a clients error `<https://tools.ietf.org/html/rfc7231#section-6.5.1>`_;
|
||||
* **401 Unauthorized** used to indicate that the client does not provide the authorization token in the HTTP Header or the client has not enough right to perform such request `<https://tools.ietf.org/html/rfc7235#section-3.1>`_;
|
||||
* **404 Not Found** used to indicate that the requested instance does not exist `<https://tools.ietf.org/html/rfc7231#section-6.5.4>`_;
|
||||
* **405 Method Not Allowed** the used HTTP method is not supported for the requested URL `<https://tools.ietf.org/html/rfc7231#section-6.5.5>`_.
|
||||
The response contains the *Allow* HTTP Header indicating the supported HTTP method for such URL `<https://tools.ietf.org/html/rfc7231#section-7.4.1>`_;
|
||||
* **409 Conflict** the request could not be completed due to a conflict with the current state of the target resource (e.g. the name of the resource already exists) `<https://tools.ietf.org/html/rfc7231#section-6.5.8>`_;
|
||||
* **500 Internal Server Error** indicate a server failure `<https://tools.ietf.org/html/rfc7231#section-6.6.1>`_.
|
||||
|
||||
You can find a complete list of HTTP Status at `<https://httpstatuses.com/>`_
|
||||
|
||||
If you get a *500 Internal Server Error*, please report it in the `gCube ticketing system <https://support.d4science.org>`_.
|
||||
|
||||
Please use this checklist before reporting an error:
|
||||
|
||||
* Replicate the request;
|
||||
* The failure could be temporal due to network error, server issue and many other temporal issues. For this reason, please retry the request after a certain amount of time before reporting the issue;
|
||||
* indicate how to replicate the error;
|
||||
* indicate the time when the error occurred (this simplifies identifying the issue).
|
||||
|
||||
HTTP Methods
|
||||
------------
|
||||
|
||||
gCat is a pure RESTful service. It uses standard HTTP Methods to perform a listing of collections and CRUD (Create Read Update Delete) operations on instances.
|
||||
|
||||
|
||||
.. table::
|
||||
|
||||
+--------------+-------------+----------------------------------------+---------------------+--------+------------+
|
||||
| Operation | HTTP Method | URL | Success HTTP Status | Safe | Idempotent |
|
||||
+==============+=============+========================================+=====================+========+============+
|
||||
| Supported | OPTIONS | /{COLLECTION} | 204 No Content | Y | Y |
|
||||
| HTTP Methods | | | [#allow]_ | | |
|
||||
+--------------+-------------+----------------------------------------+---------------------+--------+------------+
|
||||
| List | GET | /{COLLECTION} | 200 OK | Y | Y |
|
||||
+--------------+-------------+----------------------------------------+---------------------+--------+------------+
|
||||
| Count | GET | /{COLLECTION}?count=true | 200 OK | Y | Y |
|
||||
+--------------+-------------+----------------------------------------+---------------------+--------+------------+
|
||||
| Exists | HEAD | /{COLLECTION} | 204 No Content | Y | Y |
|
||||
+--------------+-------------+----------------------------------------+---------------------+--------+------------+
|
||||
| Create | POST | /{COLLECTION} | 201 Created | N | N |
|
||||
+--------------+-------------+----------------------------------------+---------------------+--------+------------+
|
||||
| Supported | OPTIONS | /{COLLECTION}/{INSTANCE_ID} | 204 No Content | Y | Y |
|
||||
| HTTP Methods | | | [#allow]_ | | |
|
||||
+--------------+-------------+----------------------------------------+---------------------+--------+------------+
|
||||
| Exist | HEAD | /{COLLECTION}/{INSTANCE_ID} | 204 No Content | Y | Y |
|
||||
+--------------+-------------+----------------------------------------+---------------------+--------+------------+
|
||||
| Read | GET | /{COLLECTION}/{INSTANCE_ID} | 200 OK | Y | Y |
|
||||
+--------------+-------------+----------------------------------------+---------------------+--------+------------+
|
||||
| Update | PUT | /{COLLECTION}/{INSTANCE_ID} | 200 OK | N | Y |
|
||||
+--------------+-------------+----------------------------------------+---------------------+--------+------------+
|
||||
| Patch | PATCH | /{COLLECTION}/{INSTANCE_ID} | 200 OK | N | Y |
|
||||
+--------------+-------------+----------------------------------------+---------------------+--------+------------+
|
||||
| Delete | DELETE | /{COLLECTION}/{INSTANCE_ID} | 204 No Content | N | N [#del]_ |
|
||||
+--------------+-------------+----------------------------------------+---------------------+--------+------------+
|
||||
| Purge | DELETE | /{COLLECTION}/{INSTANCE_ID}?purge=true | 204 No Content | N | N [#del]_ |
|
||||
+ +-------------+----------------------------------------+---------------------+--------+------------+
|
||||
| | PURGE | /{COLLECTION}/{INSTANCE_ID} | 204 No Content | N | N [#del]_ |
|
||||
+--------------+-------------+----------------------------------------+---------------------+--------+------------+
|
||||
|
||||
.. [#allow] Supported HTTP Methods in **Allow** HTTP Header
|
||||
|
||||
.. [#del] DELETE has been defined as idempotent.
|
||||
|
||||
*Allamaraju* [#Allamaraju]_ argues that DELETE idempotency should be accomplished client-side.
|
||||
The server should inform the client if the delete operation succeeded because the resource was really deleted or it was not found, i.e., **404 Not Found** error is suggested instead of **204 No Content**.
|
||||
The latter situation should be treated as idempotent by the client.
|
||||
|
||||
We share the same vision. For this reason, gCat does not provide server-side idempotency for DELETE and PURGE operations.
|
||||
|
||||
.. [#Allamaraju] Allamaraju S. RESTful Web Services Cookbook: Solutions for Improving Scalability and Simplicity . O’Reilly. first ed. 2010
|
||||
|
||||
|
||||
About URL
|
||||
^^^^^^^^^
|
||||
|
||||
The presented URL uses the following convention:
|
||||
|
||||
* **{COLLECTION}** is the plural name of the entity type;
|
||||
* **{INSTANCE_ID}** is an identification that enables univocally identifying the instance in the collection.
|
||||
|
||||
|
||||
About Safety and Idempotency properties
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
* A method is *Safe* if it does not produce any side effects.
|
||||
"This does not prevent an implementation from including behaviour that is potentially harmful, that is not entirely read-only, or that causes side effects while invoking a safe method"
|
||||
`<https://tools.ietf.org/html/rfc7231#section-4.2.1>`_;
|
||||
* A method is *Idempotent* if the same operation repeated multiple times has the same side effect than using it one time.
|
||||
"repeating the request will have the same intended effect, even if the original request succeeded, though the response might differ"
|
||||
`<https://tools.ietf.org/html/rfc7231#section-4.2.2>`_.
|
||||
|
||||
You can find more information about HTTP Methods at `<https://restfulapi.net/http-methods/>`_
|
||||
|
||||
Uncommon HTTP Methods
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
* PATCH method allows to perform a differential update (i.e. an update which provides only the differences and not the whole new representation);
|
||||
* PURGE method is not a standard but is widely used in service which requires this action
|
||||
(e.g. `Varnish <https://varnish-cache.org/docs/3.0/tutorial/purging.html>`_, `Squid <https://wiki.squid-cache.org/SquidFaq/OperatingSquid#How_can_I_purge_an_object_from_my_cache.3F>`_).
|
||||
gCat provides support for this method, but to support a wider range of clients, it also provides the Purge action via *DELETE* with the additional get parameter ``purge=true``.
|
||||
|
||||
|
||||
Content-Type
|
||||
------------
|
||||
|
||||
Any request must contain an indication of the interesting content type.
|
||||
|
||||
The client must specify the **Accept** HTTP Header for any operation returning a result.
|
||||
|
||||
.. code-block:: rest
|
||||
|
||||
Accept: application/json
|
||||
|
||||
For any operation sending content to the service, it is necessary to specify the **Content-Type** HTTP Header.
|
||||
|
||||
.. code-block:: rest
|
||||
|
||||
Content-Type: application/json
|
||||
|
||||
The service accepts and returns only JSON objects.
|
||||
|
||||
`Profile Collection <../api-docs/resource\_Profile.html>`_ instead can be manipulated in XML only.
|
||||
|
||||
Collections
|
||||
-----------
|
||||
|
||||
The following collections are available to any user.
|
||||
Catalogue-Editor or above can invoke Non-safe methods only.
|
||||
|
||||
* `Item Collection <../api-docs/resource_Item.html>`_;
|
||||
|
||||
* `Resource Collection <../api-docs/resource_Resource.html>`_;
|
||||
|
||||
* `Profile Collection <../api-docs/resource_Profile.html>`_;
|
||||
* `Namespace Collection <../api-docs/resource_Namespace.html>`_;
|
||||
* `License Collection <../api-docs/resource_License.html>`_;
|
||||
* `Trash Collection <../api-docs/resource_Trash.html>`_;
|
||||
|
||||
The following collections are available for Catalogue-Admins or above only:
|
||||
|
||||
* `Group Collection <../api-docs/resource_Group.html>`_;
|
||||
* `Organization Collection <../api-docs/resource_Organization.html>`_;
|
||||
* `User Collection <../api-docs/resource_User.html>`_;
|
||||
* `Configuration Collection <../api-docs/resource_Configuration.html>`_.
|
||||
|
||||
An overview of the available collections is available at `<../api-docs/index.html>`_;
|
||||
|
||||
|
||||
Roles
|
||||
-----
|
||||
|
||||
Any user has one or more roles in the catalogue.
|
||||
Only the VRE Manager can assign roles to VRE users.
|
||||
|
||||
|
||||
The catalogue uses the following hierarchic roles:
|
||||
|
||||
**Catalogue-Member**:
|
||||
A user with such a role is mainly capable of listing and reading items;
|
||||
|
||||
**Catalogue-Editor**:
|
||||
A user with such a role is capable of managing the items he/she creates and capable of using other safe APIs;
|
||||
|
||||
**Catalogue-Admin**:
|
||||
A user with such a role is capable of administrating many aspects of the catalogue;
|
||||
|
||||
**Catalogue-Manager**:
|
||||
A user with such a role can use all the APIs exposed by the service except item moderation APIs (e.g. approve, reject, ...).
|
||||
|
||||
|
||||
Another role that is not in the role hierarchy:
|
||||
|
||||
**Catalogue-Moderator**:
|
||||
A user with such a role is capable of invoking the item moderation APIs.
|
||||
|
||||
|
||||
.. TIP::
|
||||
Please note that not all catalogues are moderated.
|
||||
|
||||
Moderated Catalogues
|
||||
====================
|
||||
|
||||
|
||||
Any catalogues can be declared as moderated.
|
||||
This means that, a **Catalogue-Moderator** must approve any submitted items to make them available to the other users of the catalogue.
|
||||
|
||||
In a moderated catalogue, an item can be in the following states:
|
||||
|
||||
**pending**:
|
||||
The item published by any allowed author (a Catalogue-Editor or above) but not available to the other users of the catalogue.
|
||||
A Catalogue-Moderator has to approve or reject it;
|
||||
|
||||
**approved**:
|
||||
A Catalogue-Moderator has approved the item published by any allowed users;
|
||||
|
||||
**rejected**:
|
||||
A Catalogue-Moderator has rejected the item published by any allowed users.
|
||||
|
||||
|
||||
|
||||
The following are the moderation operations that an allowed user can perform on an item.
|
||||
To present the moderation operations, we use the following convention:
|
||||
|
||||
``initial_state`` ---**operation** (*User/Role performing the operation*)---> ``final_state``
|
||||
|
||||
|
||||
``initial_state`` can be ``none``, meaning the item does not exist.
|
||||
|
||||
|
||||
The following are the allowed moderation operation on an item
|
||||
|
||||
``none`` ---**create** (*Author*)---> ``pending``
|
||||
|
||||
``pending`` ---**reject** (*Catalogue-Moderator*)---> ``rejected``
|
||||
|
||||
``pending`` ---**approve** (*Catalogue-Moderator*)---> ``approved``
|
||||
|
||||
``rejected`` ---**update** (*Author*)---> ``pending``
|
||||
|
||||
``approved`` ---**update** (*Author*)---> ``pending``
|
||||
|
||||
|
||||
Please check the table below whcih summarise the item collection operation and the allowed users/roles.
|
||||
|
||||
In a moderated catalogue, both the Catalogue-Moderators and the item author can send messages to
|
||||
discuss the approval process of the item. The messages are related to a specific item.
|
||||
Any Catalogue-Moderators receive a message sent by an Author.
|
||||
The author receives a message sent by a Catalogue-Moderator as well as the other Catalogue-Moderators (if any).
|
||||
|
||||
Messages can be sent both with an action which changes the status of the item or as explicit action which does not change the status of the item:
|
||||
|
||||
``pending`` ---**message** (*Author OR Catalogue-Moderator*)---> ``pending``
|
||||
|
||||
``rejected`` ---**message** (*Author OR Catalogue-Moderator*)---> ``rejected``
|
||||
|
||||
``approved`` ---**message** (*Author OR Catalogue-Moderator*)---> ``approved``
|
||||
|
||||
|
||||
|
||||
The following table summarize the allowed/forbidden operations depending on: the role of the user and the state of the item.
|
||||
|
||||
.. table::
|
||||
|
||||
+-------------------------------------+-------------+----------------------+--------------------------+------------------------------------------+-------------------+
|
||||
| Operation | Item State | Roles |
|
||||
+ + +----------------------+--------------------------+------------------------------------------+-------------------+
|
||||
| | | Catalogue Moderator | Catalogue Admin/Manager | Catalogue Editor | Catalogue Member |
|
||||
+=====================================+=============+======================+==========================+==========================================+===================+
|
||||
| List | Yes all states | Yes all states | Yes only approved - All states if Author | Yes only approved |
|
||||
+-------------------------------------+-------------+----------------------+--------------------------+------------------------------------------+-------------------+
|
||||
| Count | Yes all states | Yes all states | Yes only approved - All states if Author | Yes only approved |
|
||||
+-------------------------------------+-------------+----------------------+--------------------------+------------------------------------------+-------------------+
|
||||
| Create | 403 Forbidden | Yes -> Pending | Yes -> Pending | 403 Forbidden |
|
||||
+-------------------------------------+-------------+----------------------+--------------------------+------------------------------------------+-------------------+
|
||||
| Read | Yes all states | Yes all states | Yes only approved - All states if Author | Yes only approved |
|
||||
+-------------------------------------+-------------+----------------------+--------------------------+------------------------------------------+-------------------+
|
||||
| Update | Pending | Yes -> Pending | Yes if Author -> Pending | Yes if Author -> Pending | 403 Forbidden |
|
||||
+ +-------------+----------------------+--------------------------+------------------------------------------+-------------------+
|
||||
| | Rejected | Yes -> Pending | Yes if Author -> Pending | Yes if Author -> Pending | 403 Forbidden |
|
||||
+ +-------------+----------------------+--------------------------+------------------------------------------+-------------------+
|
||||
| | Approved | 403 Forbidden | Yes -> Approved | Yes if Author -> Pending | 403 Forbidden |
|
||||
+-------------------------------------+-------------+----------------------+--------------------------+------------------------------------------+-------------------+
|
||||
| Delete/Purge | Pending | Yes | Yes | Yes if Author | 403 Forbidden |
|
||||
+ +-------------+----------------------+--------------------------+------------------------------------------+-------------------+
|
||||
| | Rejected | Yes | Yes | Yes if Author | 403 Forbidden |
|
||||
+ +-------------+----------------------+--------------------------+------------------------------------------+-------------------+
|
||||
| | Approved | 403 Forbidden | Yes | Yes if Author | 403 Forbidden |
|
||||
+-------------------------------------+-------------+----------------------+--------------------------+------------------------------------------+-------------------+
|
||||
| Approve a pending item | Yes | 403 Forbidden | 403 Forbidden | 403 Forbidden |
|
||||
+-------------------------------------+-------------+----------------------+--------------------------+------------------------------------------+-------------------+
|
||||
| Reject a pending item | Yes | 403 Forbidden | 403 Forbidden | 403 Forbidden |
|
||||
+-------------------------------------+-------------+----------------------+--------------------------+------------------------------------------+-------------------+
|
||||
| Message about an item | Yes | Yes if Author | Yes if Author | 403 Forbidden |
|
||||
+-------------------------------------+-------------+----------------------+--------------------------+------------------------------------------+-------------------+
|
||||
|
||||
|
||||
The Moderation process has associated notification to authors and Catalogue-Moderators.
|
||||
Please note that the user who has acted is not self-notified, e.g.
|
||||
approve operation made by a Catalogue-Moderator notifies the item author and the other Catalogue-Moderators of the VRE.
|
||||
|
||||
The following table summarises the addressee of the notification for any action.
|
||||
|
||||
|
||||
.. table::
|
||||
|
||||
+--------------+----------------------+--------+----------------------+
|
||||
| Operation | Notified user/role |
|
||||
+ +----------------------+--------+----------------------+
|
||||
| | Catalogue-Moderators | Author | User made the action |
|
||||
+==============+======================+========+======================+
|
||||
| Create | Yes | Yes | Yes (custom message) |
|
||||
+--------------+----------------------+--------+----------------------+
|
||||
| Update | Yes | Yes | Yes (custom message) |
|
||||
+--------------+----------------------+--------+----------------------+
|
||||
| Approve | Yes + Social Post if | No |
|
||||
| | requested (social_post=true) | |
|
||||
| | and enabled for the VRE | |
|
||||
+--------------+----------------------+--------+----------------------+
|
||||
| Reject | Yes | Yes | No |
|
||||
+--------------+----------------------+--------+----------------------+
|
||||
| Delete/Purge | Yes | Yes | No |
|
||||
+--------------+----------------------+--------+----------------------+
|
||||
| Message | Yes | Yes | No |
|
||||
+--------------+----------------------+--------+----------------------+
|
||||
|
||||
|
||||
|
||||
Java Client
|
||||
===========
|
||||
|
||||
We provide the following Java Client out-of-the-box.
|
||||
|
||||
.. TIP::
|
||||
If you're coding in Java, it is recommended that you use this Java Client.
|
||||
|
||||
**Maven Coordinates**
|
||||
|
||||
.. code:: xml
|
||||
|
||||
<groupId>org.gcube.data-catalogue</groupId>
|
||||
<artifactId>gcat-client</artifactId>
|
||||
<version>[2.2.0, 3.0.0-SNAPSHOT)</version>
|
||||
|
||||
**Methods Result**
|
||||
|
||||
The service exposes `its methods <../api-docs/index.html>`_ using a standard naming approach. Moreover, they accept (in the case of HTTP POST/PUT methods) JSON objects.
|
||||
|
||||
.. IMPORTANT::
|
||||
The result of all methods is always a JSON object as per below:
|
||||
|
||||
.. code:: javascript
|
||||
|
||||
{
|
||||
"rating": 0.0,
|
||||
"license_title": "Creative Commons Attribution Share-Alike 4.0",
|
||||
"maintainer": "Frosini Luca",
|
||||
"relationships_as_object": [],
|
||||
"private": false,
|
||||
"maintainer_email": "luca.frosini@isti.cnr.it",
|
||||
"num_tags": 1,
|
||||
"id": "17051d86-c127-4928-9296-d3d7590161fe",
|
||||
"metadata_created": "2022-10-17T12:45:53.118318",
|
||||
"metadata_modified": "2022-10-18T10:30:03.362756",
|
||||
"author": "Frosini Luca",
|
||||
"author_email": "luca.frosini@isti.cnr.it",
|
||||
"state": "active",
|
||||
"version": null,
|
||||
"creator_user_id": "f1b0265c-9983-4f97-a7b6-be3cc0544b27",
|
||||
"type": "dataset",
|
||||
"resources": [],
|
||||
"num_resources": 0,
|
||||
"tags": [
|
||||
{
|
||||
"vocabulary_id": null,
|
||||
"state": "active",
|
||||
"display_name": "Test",
|
||||
"id": "fec9de86-51a2-41b0-aef4-ba06eb39e16d",
|
||||
"name": "Test"
|
||||
}
|
||||
],
|
||||
"groups": [],
|
||||
"license_id": "CC-BY-SA-4.0",
|
||||
"relationships_as_subject": [],
|
||||
"organization": {
|
||||
"description": "",
|
||||
"created": "2016-05-30T11:30:41.710079",
|
||||
"title": "devVRE",
|
||||
"name": "devvre",
|
||||
"is_organization": true,
|
||||
"state": "active",
|
||||
"image_url": "",
|
||||
"revision_id": "a7eee485-a6d5-4a7b-8f73-b0ed999d5b03",
|
||||
"type": "organization",
|
||||
"id": "3571cca5-b0ae-4dc6-b791-434a8e062ce5",
|
||||
"approval_status": "approved"
|
||||
},
|
||||
"name": "my_test_item_devvre",
|
||||
"isopen": true,
|
||||
"url": "http://www.d4science.org",
|
||||
"notes": "A test item of Luca Frosini",
|
||||
"extras": [
|
||||
{
|
||||
"key": "Item URL",
|
||||
"value": "https://data.dev.d4science.org/ctlg/devVRE/my_test_item_devvre"
|
||||
},
|
||||
{
|
||||
"key": "Language",
|
||||
"value": "EN"
|
||||
},
|
||||
{
|
||||
"key": "system:cm_item_status",
|
||||
"value": "approved"
|
||||
},
|
||||
{
|
||||
"key": "system:cm_item_visibility",
|
||||
"value": "public"
|
||||
},
|
||||
{
|
||||
"key": "system:type",
|
||||
"value": "EmptyProfile"
|
||||
}
|
||||
],
|
||||
"license_url": "https://creativecommons.org/licenses/by-sa/4.0/",
|
||||
"ratings_count": 0,
|
||||
"title": "My Test Item",
|
||||
"revision_id": "bc0d1f2a-4e97-4810-b951-8b72e8279719"
|
||||
}
|
||||
|
||||
*Inputs are automatically validated before the request is served.*
|
||||
|
||||
|
||||
**Usage examples**
|
||||
|
||||
- Example 1
|
||||
|
||||
.. code:: java
|
||||
|
||||
import org.gcube.gcat.client.Item;
|
||||
|
||||
// count item number
|
||||
Item item = new Item();
|
||||
int count = item.count();
|
||||
...
|
||||
|
||||
|
||||
|
||||
Service Discovery on IS
|
||||
=======================
|
||||
|
||||
The service can be discovered in the gCore IS as gCore Endpoint with the following parameter:
|
||||
|
||||
.. code:: xml
|
||||
|
||||
<ServiceClass>org.gcube.data-catalogue</ServiceClass>
|
||||
<ServiceName>gcat</ServiceName>
|
||||
|
||||
|
||||
The service can be discovered in the Facet Based IS as EService with the following json query:
|
||||
|
||||
.. code:: json
|
||||
|
||||
{
|
||||
"@class": "EService",
|
||||
"consistsOf": [
|
||||
{
|
||||
"@class": "IsIdentifiedBy",
|
||||
"target": {
|
||||
"@class": "SoftwareFacet",
|
||||
"group": "org.gcube.data-catalogue",
|
||||
"name": "gcat"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
|
||||
Service Maven Coordinates
|
||||
=========================
|
||||
|
||||
The maven coordinates of gCat service are:
|
||||
|
||||
.. code:: xml
|
||||
|
||||
<groupId>org.gcube.data-catalogue</groupId>
|
||||
<artifactId>gcat</artifactId>
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
@ECHO OFF
|
||||
|
||||
pushd %~dp0
|
||||
|
||||
REM Command file for Sphinx documentation
|
||||
|
||||
if "%SPHINXBUILD%" == "" (
|
||||
set SPHINXBUILD=sphinx-build
|
||||
)
|
||||
set SOURCEDIR=.
|
||||
set BUILDDIR=_build
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
%SPHINXBUILD% >NUL 2>NUL
|
||||
if errorlevel 9009 (
|
||||
echo.
|
||||
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
||||
echo.installed, then set the SPHINXBUILD environment variable to point
|
||||
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
||||
echo.may add the Sphinx directory to PATH.
|
||||
echo.
|
||||
echo.If you don't have Sphinx installed, grab it from
|
||||
echo.https://www.sphinx-doc.org/
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||
goto end
|
||||
|
||||
:help
|
||||
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||
|
||||
:end
|
||||
popd
|
|
@ -0,0 +1,23 @@
|
|||
Dev and Pre Users used for moderation tests
|
||||
========
|
||||
|
||||
To perform moderation tests in dev and preproduction infrastructure we use different users with the indicated roles.
|
||||
|
||||
.. table::
|
||||
|
||||
+---------------+---------------+----------------------------------------+
|
||||
| User | Username | Role |
|
||||
+===============+===============+========================================+
|
||||
| Mister Blonde | mister.blonde | Catalogue-Admin + Catalogue-Moderator |
|
||||
+---------------+---------------+----------------------------------------+
|
||||
| Mister Blue | mister.blue | Catalogue-Admin |
|
||||
+---------------+---------------+----------------------------------------+
|
||||
| Mister Brown | mister.brown | Catalogue-Moderator |
|
||||
+---------------+---------------+----------------------------------------+
|
||||
| Mister Orange | mister.orange | Catalogue-Editor |
|
||||
+---------------+---------------+----------------------------------------+
|
||||
| Mister Pink | mister.pink | NO ROLE (means Catalogue-Member) |
|
||||
+---------------+---------------+----------------------------------------+
|
||||
| Mister White | mister.white | Catalogue-Manager |
|
||||
+---------------+---------------+----------------------------------------+
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<enunciate
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="http://enunciate.webcohesion.com/schemas/enunciate-2.14.0.xsd">
|
||||
<description package="org.gcube.acme.rest"/>
|
||||
<api-classes>
|
||||
<include pattern="org.gcube.acme.rest.*" />
|
||||
<exclude pattern="org.gcube.acme.*" />
|
||||
</api-classes>
|
||||
<modules>
|
||||
<gwt-json-overlay disabled="true " />
|
||||
<php-json-client disabled="true" />
|
||||
<ruby-json-client disabled="true" />
|
||||
<java-json-client disabled="true" />
|
||||
<javascript-client disabled="true" />
|
||||
<docs docsDir="${project.build.directory}" docsSubdir="api-docs" />
|
||||
<swagger basePath="/${project.artifactId}" />
|
||||
<docs freemarkerTemplate="${project.basedir}/src/main/resources/META-INF/enunciate/d4science_docs.fmt">
|
||||
<additional-css
|
||||
file="css/d4science_enunciate_custom.css" />
|
||||
</docs>
|
||||
</modules>
|
||||
</enunciate>
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE xml>
|
||||
<application mode='online'>
|
||||
<name>${project.artifactId}</name>
|
||||
<group>${project.groupId}</group>
|
||||
<version>${project.version}</version>
|
||||
<description>${project.description}</description>
|
||||
<exclude>/api-docs.*</exclude>
|
||||
<exclude>/docs.*</exclude>
|
||||
</application>
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app>
|
||||
<!-- <context-param>
|
||||
<param-name>resolver-basepath</param-name>
|
||||
<param-value>https://data-d.d4science.org/shub</param-value>
|
||||
</context-param> -->
|
||||
<servlet>
|
||||
<servlet-name>org.gcube.data.access.storagehub.StorageHub</servlet-name>
|
||||
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>org.gcube.data.access.storagehub.StorageHub</servlet-name>
|
||||
<url-pattern>/workspace/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
</web-app>
|
|
@ -0,0 +1,6 @@
|
|||
name: IdentityManagerService
|
||||
group: IAM
|
||||
version: ${version}
|
||||
description: ${description}
|
||||
excludes:
|
||||
- path: /workspace/api-docs/*
|
|
@ -0,0 +1,209 @@
|
|||
<project xmlns="https://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.gcube.tools</groupId>
|
||||
<artifactId>maven-parent</artifactId>
|
||||
<version>1.2.0</version>
|
||||
</parent>
|
||||
<groupId>org.gcube.idm</groupId>
|
||||
<artifactId>identity-manager</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<packaging>war</packaging>
|
||||
<name>Identity Manager Service</name>
|
||||
<description>Identity Manager Smargears Service</description>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
<webappDirectory>
|
||||
${project.basedir}${file.separator}src${file.separator}main${file.separator}webapp${file.separator}WEB-INF</webappDirectory>
|
||||
<enunciate.version>2.14.0</enunciate.version>
|
||||
</properties>
|
||||
|
||||
<scm>
|
||||
<connection>
|
||||
scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}.git</connection>
|
||||
<developerConnection>
|
||||
scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}.git</developerConnection>
|
||||
<url>https://code-repo.d4science.org/gCubeSystem/${project.artifactId}</url>
|
||||
</scm>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.gcube.distribution</groupId>
|
||||
<artifactId>gcube-smartgears-bom</artifactId>
|
||||
<version>3.0.1-SNAPSHOT</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.common</groupId>
|
||||
<artifactId>common-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.common</groupId>
|
||||
<artifactId>keycloak-client</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-admin-client</artifactId>
|
||||
<version>21.0.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.media</groupId>
|
||||
<artifactId>jersey-media-multipart</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.containers</groupId>
|
||||
<artifactId>jersey-container-servlet</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.ws.rs</groupId>
|
||||
<artifactId>javax.ws.rs-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.gcube.core</groupId>
|
||||
<artifactId>common-smartgears-app</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.gcube.core</groupId>
|
||||
<artifactId>common-smartgears</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- Required for Enunciate plugin -->
|
||||
<dependency>
|
||||
<groupId>com.webcohesion.enunciate</groupId>
|
||||
<artifactId>enunciate-core-annotations</artifactId>
|
||||
<version>${enunciate.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.webcohesion.enunciate</groupId>
|
||||
<artifactId>enunciate-rt-util</artifactId>
|
||||
<version>${enunciate.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- END Required for Enunciate plugin -->
|
||||
|
||||
<!-- Test libraries -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.11</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.portlets.user</groupId>
|
||||
<artifactId>uri-resolver-manager</artifactId>
|
||||
<version>[1.0.0, 2.0.0-SNAPSHOT)</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<plugins>
|
||||
<!-- Sphinx plugin' -->
|
||||
<plugin>
|
||||
<groupId>kr.motd.maven</groupId>
|
||||
<artifactId>sphinx-maven-plugin</artifactId>
|
||||
<version>2.10.0</version>
|
||||
<configuration>
|
||||
<outputDirectory>
|
||||
${project.build.directory}/${project.artifactId}-${project.version}/docs</outputDirectory>
|
||||
<builder>html</builder>
|
||||
<configDirectory>${basedir}/docs</configDirectory>
|
||||
<sourceDirectory>${basedir}/docs</sourceDirectory>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>process-resources</phase>
|
||||
<goals>
|
||||
<goal>generate</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
|
||||
<!-- Enunciate Maven plugin -->
|
||||
<plugin>
|
||||
<groupId>com.webcohesion.enunciate</groupId>
|
||||
<artifactId>enunciate-maven-plugin</artifactId>
|
||||
<version>${enunciate.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>assemble</id>
|
||||
<goals>
|
||||
<goal>assemble</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<!-- Copy Enunciate Documentation from your-application/api-docs
|
||||
into your war -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-enunciate-docs</id>
|
||||
<phase>process-resources</phase>
|
||||
<goals>
|
||||
<goal>copy-resources</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>target</outputDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<targetPath>
|
||||
${project.build.directory}/${project.artifactId}-${project.version}/api-docs</targetPath>
|
||||
<directory>
|
||||
${project.build.directory}/api-docs</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<configuration>
|
||||
<attachClasses>true</attachClasses>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,38 @@
|
|||
package org.gcube.idm;
|
||||
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
import javax.ws.rs.ext.ExceptionMapper;
|
||||
import javax.ws.rs.ext.Provider;
|
||||
|
||||
/**
|
||||
* @author Alfredo Oliviero (ISTI - CNR)
|
||||
*/
|
||||
@Provider
|
||||
public class IdentityManagerExceptionMapper implements ExceptionMapper<Exception> {
|
||||
|
||||
@Override
|
||||
public Response toResponse(Exception exception) {
|
||||
|
||||
Status status = Status.INTERNAL_SERVER_ERROR;
|
||||
String exceptionMessage = exception.getMessage();
|
||||
try {
|
||||
if(exception.getCause() != null) {
|
||||
exceptionMessage = exception.getCause().getMessage();
|
||||
}
|
||||
} catch(Exception e) {
|
||||
exceptionMessage = exception.getMessage();
|
||||
}
|
||||
MediaType mediaType = MediaType.TEXT_PLAIN_TYPE;
|
||||
|
||||
if(WebApplicationException.class.isAssignableFrom(exception.getClass())) {
|
||||
Response gotResponse = ((WebApplicationException) exception).getResponse();
|
||||
status = Status.fromStatusCode(gotResponse.getStatusInfo().getStatusCode());
|
||||
}
|
||||
|
||||
return Response.status(status).entity(exceptionMessage).type(mediaType).build();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package org.gcube.idm;
|
||||
|
||||
import javax.ws.rs.ApplicationPath;
|
||||
|
||||
import org.gcube.idm.rest.GreetingsRest;
|
||||
import org.gcube.smartgears.annotations.ManagedBy;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
|
||||
/**
|
||||
* @author Alfredo Oliviero (ISTI - CNR)
|
||||
*/
|
||||
|
||||
|
||||
// SMARTGEARS
|
||||
// legge i parametri del service da application.yaml
|
||||
|
||||
@ApplicationPath("/")
|
||||
@ManagedBy(IdentityManagerdInitializator.class)
|
||||
public class IdentityManagerResourceInitializer extends ResourceConfig {
|
||||
|
||||
public IdentityManagerResourceInitializer() {
|
||||
packages(GreetingsRest.class.getPackage().toString());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package org.gcube.idm;
|
||||
|
||||
import org.gcube.common.security.providers.SecretManagerProvider;
|
||||
import org.gcube.smartgears.ApplicationManager;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author Alfredo Oliviero (ISTI - CNR)
|
||||
*/
|
||||
public class IdentityManagerdInitializator implements ApplicationManager {
|
||||
|
||||
/**
|
||||
* Logger
|
||||
*/
|
||||
private static Logger logger = LoggerFactory.getLogger(IdentityManagerdInitializator.class);
|
||||
|
||||
public static boolean initialised;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public synchronized void onInit() {
|
||||
|
||||
String context = SecretManagerProvider.instance.get().getContext();
|
||||
|
||||
logger.trace(
|
||||
"\n-------------------------------------------------------\n"
|
||||
+ "Identity Manager Service is Starting on context {}\n"
|
||||
+ "-------------------------------------------------------",
|
||||
context);
|
||||
|
||||
// ApplicationContext applicationContext = ContextProvider.get();
|
||||
// String helloWorldEServiceID = applicationContext.id();
|
||||
|
||||
logger.trace(
|
||||
"\n-------------------------------------------------------\n"
|
||||
+ "Identity Manager Service Started Successfully on context {}\n"
|
||||
+ "-------------------------------------------------------",
|
||||
context);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public synchronized void onShutdown(){
|
||||
|
||||
String context = SecretManagerProvider.instance.get().getContext();
|
||||
|
||||
logger.trace(
|
||||
"\n-------------------------------------------------------\n"
|
||||
+ "Identity Manager Service is Stopping on context {}\n"
|
||||
+ "-------------------------------------------------------",
|
||||
context);
|
||||
|
||||
|
||||
logger.trace(
|
||||
"\n-------------------------------------------------------\n"
|
||||
+ "Identity Manager Service Stopped Successfully on context {}\n"
|
||||
+ "-------------------------------------------------------",
|
||||
context);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
package org.gcube.idm.rest;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.DefaultValue;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
|
||||
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
|
||||
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
|
||||
import com.webcohesion.enunciate.metadata.rs.ResourceGroup;
|
||||
import com.webcohesion.enunciate.metadata.rs.ResourceLabel;
|
||||
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
|
||||
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
||||
|
||||
@Path("greetings")
|
||||
@ResourceGroup("Greetings APIs")
|
||||
@ResourceLabel("Greetings APIs")
|
||||
@RequestHeaders ({
|
||||
@RequestHeader( name = "Authorization", description = "Bearer token, see <a href=\"https://dev.d4science.org/how-to-access-resources\">https://dev.d4science.org/how-to-access-resources</a>")
|
||||
})
|
||||
public class GreetingsRest {
|
||||
|
||||
@GET
|
||||
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
|
||||
public String list(@QueryParam("limit") @DefaultValue("10") int limit,
|
||||
@QueryParam("offset") @DefaultValue("0") int offset) {
|
||||
|
||||
return "[\"saluti\",\"saluti_volgari\"]";
|
||||
}
|
||||
|
||||
@POST
|
||||
@Produces("application/json;charset=UTF-8")
|
||||
@Consumes("application/json;charset=UTF-8")
|
||||
public String create(String json) {
|
||||
//Greeting g = new Greeting();
|
||||
//return g.create(json);
|
||||
return "{\"text\":\"hi\"}";
|
||||
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/{greeting_name}")
|
||||
@Consumes("application/json;charset=UTF-8")
|
||||
@Produces("application/json;charset=UTF-8")
|
||||
@StatusCodes ({
|
||||
@ResponseCode ( code = 200, condition = "The greeting has been updated successfully.")
|
||||
})
|
||||
// @AuthorizationControl(allowedRoles={"boss"}, exception=NotAuthorizedException.class)
|
||||
public String update(@PathParam("greeting_name") String name, String json) {
|
||||
return "{}";
|
||||
}
|
||||
|
||||
|
||||
@DELETE
|
||||
@Path("/{greeting_name}")
|
||||
@StatusCodes ({
|
||||
@ResponseCode ( code = 204, condition = "The item has been deleted successfully."),
|
||||
@ResponseCode ( code = 404, condition = "The item was not found.")
|
||||
})
|
||||
public String delete(@PathParam("greeting_name") String name) {
|
||||
return "{}";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,153 @@
|
|||
package org.gcube.idm.rest;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
|
||||
import org.gcube.common.authorization.library.policies.Users;
|
||||
import org.gcube.common.security.Owner;
|
||||
import org.gcube.common.security.providers.SecretManagerProvider;
|
||||
import org.gcube.keycloack.KeycloackApiClient;
|
||||
import org.gcube.keycloack.KeycloakAPIFactory;
|
||||
import org.gcube.rest.ResponseBean;
|
||||
import org.gcube.smartgears.ContextProvider;
|
||||
import org.gcube.smartgears.context.application.ApplicationContext;
|
||||
import org.gcube.smartgears.security.SimpleCredentials;
|
||||
import org.gcube.smartgears.security.defaults.DefaultAuthorizationProvider;
|
||||
import org.gcube.smartgears.utils.InnerMethodName;
|
||||
import org.jboss.resteasy.spi.NotImplementedYetException;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
|
||||
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
|
||||
import com.webcohesion.enunciate.metadata.rs.ResourceGroup;
|
||||
import com.webcohesion.enunciate.metadata.rs.ResourceLabel;
|
||||
|
||||
@Path("2/users")
|
||||
@ResourceGroup("Users APIs")
|
||||
@ResourceLabel("Greetings APIs")
|
||||
@RequestHeaders({
|
||||
@RequestHeader(name = "Authorization", description = "Bearer token, see <a href=\"https://dev.d4science.org/how-to-access-resources\">https://dev.d4science.org/how-to-access-resources</a>")
|
||||
})
|
||||
public class UsersRest {
|
||||
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(Users.class);
|
||||
|
||||
@GET
|
||||
@Path("/{get-usernames-by-role}")
|
||||
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
|
||||
public Response getUsernamesByRole(
|
||||
@QueryParam("role-name") String roleName) {
|
||||
Status status = Status.OK;
|
||||
ResponseBean responseBean = new ResponseBean();
|
||||
|
||||
List<String> usernames = new ArrayList<String>();
|
||||
try {
|
||||
String ctx = SecretManagerProvider.instance.get().getContext();
|
||||
KeycloackApiClient keycloackApiClient = KeycloakAPIFactory.getSingleton().createtKeycloakInstance(ctx);
|
||||
|
||||
List<UserRepresentation> users = searchByRole(keycloackApiClient, roleName);
|
||||
if (users != null) {
|
||||
for (UserRepresentation user : users) {
|
||||
usernames.add(user.getUsername());
|
||||
}
|
||||
}
|
||||
responseBean.setResult(usernames);
|
||||
responseBean.setSuccess(true);
|
||||
} catch (Exception e) {
|
||||
logger.error("Unable to retrieve user with the requested role", e);
|
||||
responseBean.setMessage(e.getMessage());
|
||||
status = Status.INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
return Response.status(status).entity(responseBean).build();
|
||||
|
||||
}
|
||||
|
||||
private static List<UserRepresentation> searchByRole(KeycloackApiClient keycloackApiClient, String roleName) {
|
||||
logger.info("Searching by role: {}", roleName);
|
||||
|
||||
List<ClientRepresentation> clients = keycloackApiClient.kclient.realm(keycloackApiClient.realmName)
|
||||
.clients().findByClientId(keycloackApiClient.clientIdContext);
|
||||
|
||||
String id = "";
|
||||
for (ClientRepresentation client : clients) {
|
||||
logger.info("found client =" + client.getClientId());
|
||||
logger.info("found client id=" + client.getId());
|
||||
id = client.getId();
|
||||
}
|
||||
|
||||
List<UserRepresentation> users = keycloackApiClient.kclient.realm(keycloackApiClient.realmName)
|
||||
.clients()
|
||||
.get(id).roles().get(roleName)
|
||||
.getUserMembers(0, 100000);
|
||||
return users;
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/{get-profile}")
|
||||
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
|
||||
public String getCurrentProfile() {
|
||||
// SMARTGEARS Specializza il tracciamento della chiamata su Accounting
|
||||
InnerMethodName.instance.set("getCurrentProfile");
|
||||
Owner owner = SecretManagerProvider.instance.get().getOwner();
|
||||
|
||||
ApplicationContext appContext = ContextProvider.get();
|
||||
SimpleCredentials credentials = ((DefaultAuthorizationProvider) appContext.container().authorizationProvider())
|
||||
.getCredentials();
|
||||
|
||||
String ctx = SecretManagerProvider.instance.get().getContext();
|
||||
KeycloackApiClient keycloackApiClient = KeycloakAPIFactory.getSingleton().createtKeycloakInstance(ctx);
|
||||
return null;
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/{get-email}")
|
||||
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
|
||||
public String getCurrentEmail() {
|
||||
throw new NotImplementedYetException();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/{get-fullname}")
|
||||
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
|
||||
public String getCurrentFullname() {
|
||||
throw new NotImplementedYetException();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/{get-all-usernames}")
|
||||
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
|
||||
public String getAllUsernames() {
|
||||
throw new NotImplementedYetException();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/{get-all-fullnames-and-usernames}")
|
||||
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
|
||||
public String getAllUsernamesFullnames() {
|
||||
throw new NotImplementedYetException();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/{user-exists}")
|
||||
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
|
||||
public boolean checkUserExists() {
|
||||
throw new NotImplementedYetException();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/{get-oauth-profile}")
|
||||
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
|
||||
public boolean getCurrentOAuthProfile() {
|
||||
throw new NotImplementedYetException();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package org.gcube.keycloack;
|
||||
|
||||
public class ErrorMessages {
|
||||
|
||||
protected static final String NOT_USER_TOKEN_CONTEXT_USED = "User's information can only be retrieved through a user token (not qualified)";
|
||||
protected static final String CANNOT_RETRIEVE_SERVICE_ENDPOINT_INFORMATION = "Unable to retrieve such service endpoint information";
|
||||
|
||||
private static final String NO_RUNTIME_RESOURCE_TEMPLATE_NAME_CATEGORY = "There is no Runtime Resource having name %s and Category %s in this scope";
|
||||
|
||||
protected static final String no_runtime_category(String runtime, String category) {
|
||||
return String.format(NO_RUNTIME_RESOURCE_TEMPLATE_NAME_CATEGORY, runtime, category);
|
||||
}
|
||||
|
||||
// public static final String MISSING_TOKEN = "Missing token.";
|
||||
// public static final String MISSING_PARAMETERS = "Missing request
|
||||
// parameters.";
|
||||
// public static final String INVALID_TOKEN = "Invalid token.";
|
||||
// public static final String TOKEN_GENERATION_APP_FAILED = "Token generation
|
||||
// failed.";
|
||||
// public static final String NOT_APP_TOKEN = "Invalid token: not belonging to
|
||||
// an application.";
|
||||
// public static final String NOT_APP_ID = "Invalid application id: it doesn't
|
||||
// belong to an application.";
|
||||
// public static final String NO_APP_PROFILE_FOUND = "There is no application
|
||||
// profile for this app id/scope.";
|
||||
// public static final String BAD_REQUEST = "Please check the parameter you
|
||||
// passed, it seems a bad request";
|
||||
// public static final String ERROR_IN_API_RESULT = "The error is reported into
|
||||
// the 'message' field of the returned object";
|
||||
// public static final String POST_OUTSIDE_VRE = "A post cannot be written into
|
||||
// a context that is not a VRE";
|
||||
// public static final String DEPRECATED_METHOD = "This method is deprecated,
|
||||
// must use version 2";
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package org.gcube.keycloack;
|
||||
|
||||
import org.keycloak.admin.client.Keycloak;
|
||||
|
||||
public class KeycloackApiClient {
|
||||
public Keycloak kclient;
|
||||
public String realmName;
|
||||
public String clientIdContext;
|
||||
public String context;
|
||||
|
||||
public static String getClientIdContext(String context){
|
||||
return context.replace("/", "%2F");
|
||||
}
|
||||
|
||||
public KeycloackApiClient(Keycloak kclient, String realmName, String context) {
|
||||
this.clientIdContext = getClientIdContext(context);
|
||||
this.context = context;
|
||||
this.kclient = kclient;
|
||||
this.realmName = realmName;
|
||||
// ClientsResource clients = kclient.realm(realmName).clients();
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
package org.gcube.keycloack;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.AbstractMap.SimpleEntry;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.ws.rs.InternalServerErrorException;
|
||||
|
||||
import org.gcube.common.security.providers.SecretManagerProvider;
|
||||
import org.gcube.common.keycloak.DefaultKeycloakClient;
|
||||
import org.gcube.common.keycloak.KeycloakClientException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class KeycloackClientParams_UNUSED {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(KeycloackClientParams_UNUSED.class);
|
||||
|
||||
public static final String CATALOGUE_NAME = "IDM";
|
||||
|
||||
protected static final String CLIENT_ID_SECRET_FILENAME = "config.properties";
|
||||
protected static final String CLIENT_ID_PROPERTY_NAME = "clientId";
|
||||
|
||||
public String context;
|
||||
public String clientId;
|
||||
public String clientSecret;
|
||||
public DefaultKeycloakClient gcubeKeycloakClient;
|
||||
|
||||
// Reads the property file and extracts the keycloack configuration params
|
||||
protected static Entry<String, String> getClientIdAndClientSecret(String context) {
|
||||
try {
|
||||
Properties properties = new Properties();
|
||||
ClassLoader classLoader = KeycloackClientParams_UNUSED.class.getClassLoader();
|
||||
URL url = classLoader.getResource(CLIENT_ID_SECRET_FILENAME);
|
||||
logger.trace("Going to read {} at {}", CLIENT_ID_SECRET_FILENAME, url.toString());
|
||||
InputStream input = classLoader.getResourceAsStream(CLIENT_ID_SECRET_FILENAME);
|
||||
properties.load(input);
|
||||
|
||||
String clientId = "IDM";
|
||||
if (properties.containsKey(CLIENT_ID_PROPERTY_NAME)) {
|
||||
clientId = properties.getProperty(CLIENT_ID_PROPERTY_NAME);
|
||||
}
|
||||
|
||||
int index = context.indexOf('/', 1);
|
||||
String root = context.substring(0, index == -1 ? context.length() : index);
|
||||
String clientSecret = properties.getProperty(root);
|
||||
|
||||
SimpleEntry<String, String> entry = new SimpleEntry<String, String>(clientId, clientSecret);
|
||||
return entry;
|
||||
} catch (Exception e) {
|
||||
throw new InternalServerErrorException(
|
||||
"Unable to retrieve Application Token for context "
|
||||
+ SecretManagerProvider.instance.get().getContext(),
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: VERIFICARE
|
||||
public URL getRealmBaseURL() throws KeycloakClientException {
|
||||
return this.gcubeKeycloakClient.getRealmBaseURL(this.context);
|
||||
}
|
||||
|
||||
public URL getRealmBaseURL(String realm) throws KeycloakClientException {
|
||||
return this.gcubeKeycloakClient.getRealmBaseURL(this.context, realm);
|
||||
}
|
||||
|
||||
public URL getServerURL() {
|
||||
try {
|
||||
return this.getRealmBaseURL();
|
||||
} catch (KeycloakClientException e) {
|
||||
// That should be almost impossible
|
||||
logger.warn("Cannot create base URL", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String getClientid() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
// TODO: serve? implementare
|
||||
public String getPassword() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO: VERIFICARE
|
||||
public String getRealm() {
|
||||
return this.context;
|
||||
}
|
||||
|
||||
public KeycloackClientParams_UNUSED(String context) {
|
||||
this.context = context;
|
||||
Entry<String, String> params = getClientIdAndClientSecret(context);
|
||||
this.clientId = params.getKey();
|
||||
this.clientSecret = params.getKey();
|
||||
|
||||
this.gcubeKeycloakClient = new DefaultKeycloakClient();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
package org.gcube.keycloack;
|
||||
|
||||
import static org.gcube.resources.discovery.icclient.ICFactory.clientFor;
|
||||
import static org.gcube.resources.discovery.icclient.ICFactory.queryFor;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.gcube.common.encryption.encrypter.StringEncrypter;
|
||||
import org.gcube.common.resources.gcore.ServiceEndpoint;
|
||||
import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint;
|
||||
import org.gcube.resources.discovery.client.api.DiscoveryClient;
|
||||
import org.gcube.resources.discovery.client.queries.api.SimpleQuery;
|
||||
import org.gcube.smartgears.ContextProvider;
|
||||
import org.gcube.smartgears.context.application.ApplicationContext;
|
||||
import org.keycloak.OAuth2Constants;
|
||||
import org.keycloak.admin.client.Keycloak;
|
||||
import org.keycloak.admin.client.KeycloakBuilder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class KeycloakAPIFactory {
|
||||
private static final Logger logger = LoggerFactory.getLogger(KeycloakAPIFactory.class);
|
||||
|
||||
private final static String RUNTIME_RESOURCE_NAME = "IAM";
|
||||
private final static String CATEGORY = "Service";
|
||||
|
||||
// the singleton obj
|
||||
|
||||
private static KeycloakAPIFactory singleton = new KeycloakAPIFactory();
|
||||
|
||||
// properties that it contains
|
||||
private String keycloakURL;
|
||||
private String realm;
|
||||
private String clientid;
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* Private constructor
|
||||
*/
|
||||
private KeycloakAPIFactory() {
|
||||
logger.info("Building KeycloakAPICredentials object");
|
||||
|
||||
lookupPropertiesFromIs();
|
||||
logger.info("KeycloakAPICredentials object built");
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the properties from the infrastructure
|
||||
*/
|
||||
private void lookupPropertiesFromIs() {
|
||||
|
||||
logger.info("Starting creating KeycloakAPICredentials");
|
||||
|
||||
// String ctx = SecretManagerProvider.instance.get().getContext();
|
||||
// TODO: verificare che sia contesto corretto
|
||||
ApplicationContext ctx = ContextProvider.get(); // get this info from SmartGears
|
||||
|
||||
logger.info("Discovering liferay user's credentials in context "
|
||||
+ ctx.container().configuration().infrastructure());
|
||||
|
||||
try {
|
||||
List<ServiceEndpoint> resources = getConfigurationFromIS();
|
||||
if (resources.size() == 0) {
|
||||
logger.error("There is no Runtime Resource having name " + RUNTIME_RESOURCE_NAME + " and Category "
|
||||
+ CATEGORY + " in this scope.");
|
||||
throw new Exception("There is no Runtime Resource having name " + RUNTIME_RESOURCE_NAME
|
||||
+ " and Category " + CATEGORY + " in this scope.");
|
||||
} else {
|
||||
for (ServiceEndpoint res : resources) {
|
||||
Iterator<AccessPoint> accessPointIterator = res.profile().accessPoints().iterator();
|
||||
while (accessPointIterator.hasNext()) {
|
||||
ServiceEndpoint.AccessPoint accessPoint = (ServiceEndpoint.AccessPoint) accessPointIterator
|
||||
.next();
|
||||
|
||||
if (accessPoint.name().equals("d4science")) {
|
||||
keycloakURL = accessPoint.address();
|
||||
realm = accessPoint.name();
|
||||
clientid = accessPoint.username();
|
||||
password = StringEncrypter.getEncrypter().decrypt(accessPoint.password());
|
||||
logger.info("Found accesspoint URL = " + keycloakURL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("Unable to retrieve such service endpoint information!", e);
|
||||
return;
|
||||
// }finally{
|
||||
// if(oldContext != null)
|
||||
// ScopeProvider.instance.set(oldContext);
|
||||
}
|
||||
|
||||
logger.info("Bean built " + toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve endpoints information from IS for DB
|
||||
*
|
||||
* @return list of endpoints for ckan database
|
||||
* @throws Exception
|
||||
*/
|
||||
private List<ServiceEndpoint> getConfigurationFromIS() throws Exception {
|
||||
SimpleQuery query = queryFor(ServiceEndpoint.class);
|
||||
query.addCondition("$resource/Profile/Name/text() eq '" + RUNTIME_RESOURCE_NAME + "'");
|
||||
query.addCondition("$resource/Profile/Category/text() eq '" + CATEGORY + "'");
|
||||
DiscoveryClient<ServiceEndpoint> client = clientFor(ServiceEndpoint.class);
|
||||
List<ServiceEndpoint> toReturn = client.submit(query);
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
public static KeycloakAPIFactory getSingleton() {
|
||||
if (singleton == null)
|
||||
singleton = new KeycloakAPIFactory();
|
||||
return singleton;
|
||||
}
|
||||
|
||||
public String getServerURL() {
|
||||
return keycloakURL;
|
||||
}
|
||||
|
||||
public String getClientid() {
|
||||
return clientid;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public String getRealm() {
|
||||
return realm;
|
||||
}
|
||||
|
||||
public KeycloackApiClient createtKeycloakInstance(String context) {
|
||||
// String clientIdContext = KeycloackUtils.getClientIdContext(context);
|
||||
String realm = this.getRealm();
|
||||
Keycloak keycloak = KeycloakBuilder.builder()
|
||||
.serverUrl(this.getServerURL())
|
||||
.realm(realm)
|
||||
.grantType(OAuth2Constants.CLIENT_CREDENTIALS)
|
||||
.clientId(this.getClientid()) //
|
||||
.clientSecret(this.getPassword()).build();
|
||||
return new KeycloackApiClient(keycloak, realm, context);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package org.gcube.rest;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Response bean
|
||||
*
|
||||
*/
|
||||
public class ResponseBean implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -2725238162673879658L;
|
||||
/**
|
||||
* The result of the request: true if it succeeded, false otherwise
|
||||
*/
|
||||
private boolean success;
|
||||
|
||||
/**
|
||||
* An error message if something wrong happened, null/empty otherwise
|
||||
*/
|
||||
private String message;
|
||||
/**
|
||||
* The result object of the request
|
||||
*/
|
||||
private Object result;
|
||||
|
||||
public ResponseBean() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param success
|
||||
* @param message
|
||||
* @param result
|
||||
*/
|
||||
public ResponseBean(boolean success, String message, Object result) {
|
||||
super();
|
||||
this.success = success;
|
||||
this.message = message;
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public boolean isSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
public void setSuccess(boolean success) {
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public Object getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setResult(Object result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ResponseBean [success=" + success
|
||||
+ ", message=" + message + ", result=" + result + "]";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package org.gcube.rest.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import javax.ws.rs.HttpMethod;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI - CNR)
|
||||
*/
|
||||
@Target({ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@HttpMethod("PATCH")
|
||||
public @interface PATCH {
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package org.gcube.rest.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import javax.ws.rs.HttpMethod;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI - CNR)
|
||||
*/
|
||||
@Target({ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@HttpMethod("PURGE")
|
||||
public @interface PURGE {
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package org.gcube.rest.utils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.HttpURLConnection;
|
||||
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
|
||||
import org.gcube.common.gxhttp.request.GXHTTPStringRequest;
|
||||
import org.gcube.keycloack.KeycloackClientParams_UNUSED;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI - CNR)
|
||||
*/
|
||||
public class HTTPUtility {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(HTTPUtility.class);
|
||||
|
||||
public static StringBuilder getStringBuilder(InputStream inputStream) throws IOException {
|
||||
StringBuilder result = new StringBuilder();
|
||||
try(BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
|
||||
String line;
|
||||
while((line = reader.readLine()) != null) {
|
||||
result.append(line);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static GXHTTPStringRequest createGXHTTPStringRequest(String url, String path, boolean post)
|
||||
throws UnsupportedEncodingException {
|
||||
GXHTTPStringRequest gxhttpStringRequest = GXHTTPStringRequest.newRequest(url);
|
||||
gxhttpStringRequest.from(KeycloackClientParams_UNUSED.CATALOGUE_NAME);
|
||||
if(post) {
|
||||
gxhttpStringRequest.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
|
||||
}
|
||||
gxhttpStringRequest.header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON);
|
||||
gxhttpStringRequest.path(path);
|
||||
return gxhttpStringRequest;
|
||||
}
|
||||
|
||||
public static String getResultAsString(HttpURLConnection httpURLConnection) throws IOException {
|
||||
int responseCode = httpURLConnection.getResponseCode();
|
||||
if(responseCode >= Status.BAD_REQUEST.getStatusCode()) {
|
||||
Status status = Status.fromStatusCode(responseCode);
|
||||
InputStream inputStream = httpURLConnection.getErrorStream();
|
||||
StringBuilder result = getStringBuilder(inputStream);
|
||||
logger.trace(result.toString());
|
||||
throw new WebApplicationException(result.toString(), status);
|
||||
}
|
||||
InputStream inputStream = httpURLConnection.getInputStream();
|
||||
String ret = getStringBuilder(inputStream).toString();
|
||||
logger.trace("Got Respose is {}", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package org.gcube.utils.IdmConstantsaa;
|
||||
|
||||
public class IdmConstants {
|
||||
|
||||
public static final String SERVICE_CLASS = "org.gcube.data-catalogue";
|
||||
public static final String SERVICE_NAME = "gcat";
|
||||
|
||||
public final static String CONFIGURATION_CATEGORY = IdmConstants.SERVICE_CLASS;
|
||||
public final static String CONFIGURATION_NAME = IdmConstants.SERVICE_NAME + "-configuration";
|
||||
|
||||
public static final String SERVICE_ENTRY_NAME = "org.gcube.gcat.ResourceInitializer";
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,5 @@
|
|||
/LICENSE.md
|
||||
/README.md
|
||||
/changelog.xml
|
||||
/gcube-app.xml
|
||||
/CHANGELOG.md
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE xml>
|
||||
<web-app>
|
||||
<servlet>
|
||||
<servlet-name>org.gcube.acme.ResourceInitializer</servlet-name>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>default</servlet-name>
|
||||
<url-pattern>/docs/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
<servlet-mapping>
|
||||
<servlet-name>default</servlet-name>
|
||||
<url-pattern>/api-docs/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
<servlet-mapping>
|
||||
<servlet-name>org.gcube.acme.ResourceInitializer</servlet-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
</web-app>
|
|
@ -0,0 +1,25 @@
|
|||
.d4science_intro {
|
||||
top: 0;
|
||||
z-index: 2000;
|
||||
position: fixed;
|
||||
display: block ruby;
|
||||
padding: 10px;
|
||||
background: white;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.navbar-fixed-top {
|
||||
top: 100px !important;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
top: 160px !important;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
margin-bottom: 40px !important;
|
||||
}
|
||||
|
||||
.main {
|
||||
top: 90px;
|
||||
}
|
Loading…
Reference in New Issue