first commit

This commit is contained in:
Ahmed Salah Tawfik Ibrahim 2024-02-09 12:01:03 +01:00
commit 68c654328a
36 changed files with 7334 additions and 0 deletions

250
.gitignore vendored Normal file
View File

@ -0,0 +1,250 @@
# Created by https://www.toptal.com/developers/gitignore/api/macos,intellij,eclipse,visualstudiocode,linux
# Edit at https://www.toptal.com/developers/gitignore?templates=macos,intellij,eclipse,visualstudiocode,linux
### 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/
### Intellij ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# AWS User-specific
.idea/**/aws.xml
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# SonarLint plugin
.idea/sonarlint/
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
### Intellij Patch ###
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
# *.iml
# modules.xml
# .idea/misc.xml
# *.ipr
# Sonarlint plugin
# https://plugins.jetbrains.com/plugin/7973-sonarlint
.idea/**/sonarlint/
# SonarQube Plugin
# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
.idea/**/sonarIssues.xml
# Markdown Navigator plugin
# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
.idea/**/markdown-navigator.xml
.idea/**/markdown-navigator-enh.xml
.idea/**/markdown-navigator/
# Cache file creation bug
# See https://youtrack.jetbrains.com/issue/JBR-2257
.idea/$CACHE_FILE$
# CodeStream plugin
# https://plugins.jetbrains.com/plugin/12206-codestream
.idea/codestream.xml
# Azure Toolkit for IntelliJ plugin
# https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij
.idea/**/azureSettings.xml
### 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/macos,intellij,eclipse,visualstudiocode,linux

8
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

16
.idea/compiler.xml Normal file
View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="social-service" />
</profile>
</annotationProcessing>
<bytecodeTargetLevel>
<module name="hello-world" target="1.8" />
</bytecodeTargetLevel>
</component>
</project>

8
.idea/encodings.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
<file url="file:///opt/gcube/local-classpath" charset="UTF-8" />
</component>
</project>

35
.idea/jarRepositories.xml Normal file
View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://repo.maven.apache.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="gcube-externals" />
<option name="name" value="gCube Externals" />
<option name="url" value="https://maven.d4science.org/nexus/content/repositories/gcube-externals" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="gcube-releases" />
<option name="name" value="gCube Releases" />
<option name="url" value="https://nexus.d4science.org/nexus/content/repositories/gcube-releases" />
</remote-repository>
<remote-repository>
<option name="id" value="gcube-snapshots" />
<option name="name" value="gCube Snapshots" />
<option name="url" value="https://maven.d4science.org/nexus/content/repositories/gcube-snapshots" />
</remote-repository>
</component>
</project>

12
.idea/misc.xml Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK" />
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

9
CHANGELOG.md Normal file
View File

@ -0,0 +1,9 @@
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
# Changelog for Hello World Service
## [v1.0.0-SNAPSHOT]
- First Version

26
FUNDING.md Normal file
View File

@ -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);

312
LICENSE.md Normal file
View File

@ -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 Licensees 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

48
README.md Normal file
View File

@ -0,0 +1,48 @@
# Hello World 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
[Hello World Service](https://wiki.gcube-system.org/gcube/SmartGears)
## Change log
See [CHANGELOG.md](CHANGELOG.md).
## Authors
* **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 = {{Luca Frosini}},
title = {Hello World Service},
abstract = {This is an Hello World smargears service},
url = {https://doi.org/10.5281/zenodo.7446641},
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)

23
enunciate.xml Normal file
View File

@ -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>

View File

@ -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>

243
pom.xml Normal file
View File

@ -0,0 +1,243 @@
<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.1.0</version>
</parent>
<groupId>org.gcube.social_networking</groupId>
<artifactId>social-service</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>Social Service</name>
<description>This is the social service</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<webappDirectory>
${project.basedir}${file.separator}src${file.separator}main${file.separator}webapp${file.separator}WEB-INF</webappDirectory>
<enunciate.version>2.14.0</enunciate.version>
<cassandra.driver.oss.version>4.13.0</cassandra.driver.oss.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>2.5.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.gcube.distribution</groupId>
<artifactId>maven-portal-bom</artifactId>
<version>3.7.0</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>authorization-utils</artifactId>
<version>[2.2.0, 3.0.0-SNAPSHOT)</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.common.portal</groupId>
<artifactId>portal-manager</artifactId>
<scope>provided</scope>
</dependency>
<!--must be provided -->
<dependency>
<groupId>org.gcube.social-networking</groupId>
<artifactId>social-service-model</artifactId>
<version>[1.2.0-SNAPSHOT, 2.0.0)</version>
</dependency>
<dependency>
<groupId>com.datastax.oss</groupId>
<artifactId>java-driver-query-builder</artifactId>
<version>${cassandra.driver.oss.version}</version>
</dependency>
<dependency>
<groupId>com.datastax.oss</groupId>
<artifactId>java-driver-mapper-runtime</artifactId>
<version>${cassandra.driver.oss.version}</version>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.5.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.gcube.core</groupId>
<artifactId>common-smartgears-app</artifactId>
</dependency>
<!-- Added to support Java 11 JDK -->
<dependency>
<groupId>javax.xml.ws</groupId>
<artifactId>jaxws-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!-- END Added to support Java 11 JDK -->
<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>
</dependencies>
<build>
<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>

View File

@ -0,0 +1,66 @@
package org.gcube.social_networking;
import org.gcube.common.authorization.utils.manager.SecretManagerProvider;
import org.gcube.smartgears.ApplicationManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class HelloWorldInitializator implements ApplicationManager {
/**
* Logger
*/
private static Logger logger = LoggerFactory.getLogger(HelloWorldInitializator.class);
public static boolean initialised;
/**
* {@inheritDoc}
*/
@Override
public synchronized void onInit() {
String context = SecretManagerProvider.instance.get().getContext();
logger.trace(
"\n-------------------------------------------------------\n"
+ "Hello World Service is Starting on context {}\n"
+ "-------------------------------------------------------",
context);
// ApplicationContext applicationContext = ContextProvider.get();
// String helloWorldEServiceID = applicationContext.id();
logger.trace(
"\n-------------------------------------------------------\n"
+ "Hello World Service Started Successfully on context {}\n"
+ "-------------------------------------------------------",
context);
}
/**
* {@inheritDoc}
*/
@Override
public synchronized void onShutdown(){
String context = SecretManagerProvider.instance.get().getContext();
logger.trace(
"\n-------------------------------------------------------\n"
+ "Hello World Service is Stopping on context {}\n"
+ "-------------------------------------------------------",
context);
logger.trace(
"\n-------------------------------------------------------\n"
+ "Hello World Service Stopped Successfully on context {}\n"
+ "-------------------------------------------------------",
context);
}
}

View File

@ -0,0 +1,20 @@
package org.gcube.social_networking;
import javax.ws.rs.ApplicationPath;
import org.gcube.acme.rest.HelloWorld;
import org.gcube.smartgears.annotations.ManagedBy;
import org.glassfish.jersey.server.ResourceConfig;
/**
* @author Luca Frosini (ISTI - CNR)
*/
@ApplicationPath("/")
@ManagedBy(HelloWorldInitializator.class)
public class ResourceInitializer extends ResourceConfig {
public ResourceInitializer() {
packages(HelloWorld.class.getPackage().toString());
}
}

View File

@ -0,0 +1,26 @@
package org.gcube.social_networking.rest;
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 org.gcube.social_networking.socialnetworking.model.shared.Attachment;
import org.gcube.social_networking.socialnetworking.model.shared.Like;
import javax.ws.rs.*;
@Path("attachments")
@ResourceGroup("Attachments APIs")
@ResourceLabel("Attachments 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 Attachments {
@POST
@Path("/")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
@Consumes({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void saveAttachmentEntry(Attachment toSave) {
}
}

View File

@ -0,0 +1,66 @@
package org.gcube.social_networking.rest;
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 org.gcube.social_networking.socialnetworking.model.shared.Comment;
import javax.ws.rs.*;
import java.util.List;
@Path("comments")
@ResourceGroup("Comments APIs")
@ResourceLabel("Comments 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 Comments {
@POST
@Path("/")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
@Consumes({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void addComment(Comment comment) {
}
@GET
@Path("/{id}")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void readComment(@PathParam("id") String id) {
}
@PUT
@Path("/{id}")
@Consumes({"application/json;charset=UTF-8", "application/vnd.api+json"})
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void editComment(@PathParam("id") String id, Comment comment) {
}
@DELETE
@Path("/{id}")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void deleteComment(@PathParam("id") String id) {
}
//the following two methods had vreid why?
@POST
@Path("/{id}/hashtags")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
@Consumes({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void saveHashTagsComment(@PathParam("id") String commentId, List<String> hashtags) {
}
@DELETE
@Path("/{id}/hashtags")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
@Consumes({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void deleteHashTagsComment(@PathParam("id") String commentId, List<String> hashtags) {
}
}

View File

@ -0,0 +1,94 @@
package org.gcube.social_networking.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 javax.ws.rs.core.Response;
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;
import org.gcube.social_networking.server.CassandraConnection;
import org.gcube.social_networking.socialnetworking.model.shared.Comment;
import org.gcube.social_networking.socialnetworking.model.shared.exceptions.CommentIDNotFoundException;
@Path("comments")
@ResourceGroup("Comments APIs")
@ResourceLabel("Comments 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 HelloWorld {
@POST
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
@Consumes({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void addComment(Comment comment) {
}
@GET
@Path("/{id}")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void readComment(@PathParam("id") String id) {
}
@PUT
@Path("/{id}")
@Consumes({"application/json;charset=UTF-8", "application/vnd.api+json"})
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void editComment(@PathParam("id") String id, Comment comment) {
}
@DELETE
@Path("/{id}")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void deleteComment(@PathParam("id") String id) {
}
@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 "{}";
}
}

View File

@ -0,0 +1,38 @@
package org.gcube.social_networking.rest;
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 Luca Frosini (ISTI - CNR)
*/
@Provider
public class HelloWorldExceptionMapper 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();
}
}

View File

@ -0,0 +1,35 @@
package org.gcube.social_networking.rest;
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 org.gcube.social_networking.socialnetworking.model.shared.Invite;
import org.gcube.social_networking.socialnetworking.model.shared.Notification;
import javax.ws.rs.*;
@Path("invites")
@ResourceGroup("Invites APIs")
@ResourceLabel("Invites 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 Invites {
@POST
@Path("/")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
@Consumes({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void saveInvite(Invite invite) {
}
@GET
@Path("/{id}")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void readInvite(@PathParam("id") String inviteid) {
}
}

View File

@ -0,0 +1,35 @@
package org.gcube.social_networking.rest;
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 org.gcube.social_networking.socialnetworking.model.shared.Like;
import org.gcube.social_networking.socialnetworking.model.shared.Notification;
import javax.ws.rs.*;
@Path("likes")
@ResourceGroup("Likes APIs")
@ResourceLabel("Likes 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 Likes {
@POST
@Path("/")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
@Consumes({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void like(Like like) {
}
//had other params why?
@DELETE
@Path("/{id}")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void unlike(@PathParam("id") String likeid) {
}
}

View File

@ -0,0 +1,40 @@
package org.gcube.social_networking.rest;
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 org.gcube.social_networking.socialnetworking.model.shared.Notification;
import org.gcube.social_networking.socialnetworking.model.shared.Post;
import javax.ws.rs.*;
@Path("notifications")
@ResourceGroup("Notifications APIs")
@ResourceLabel("Notifications 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 Notifications {
@POST
@Path("/")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
@Consumes({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void saveNotification(Notification notification) {
}
@PUT
@Path("/{id}")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void setNotificationRead(@PathParam("id") String notid) {
}
@GET
@Path("/{id}")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void readNotification(@PathParam("id") String notid) {
}
}

View File

@ -0,0 +1,113 @@
package org.gcube.social_networking.rest;
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 org.gcube.social_networking.socialnetworking.model.shared.Attachment;
import org.gcube.social_networking.socialnetworking.model.shared.Comment;
import org.gcube.social_networking.socialnetworking.model.shared.Post;
import javax.ws.rs.*;
import java.util.List;
@Path("posts")
@ResourceGroup("Posts APIs")
@ResourceLabel("Posts 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 Posts {
@POST
@Path("/postuser")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
@Consumes({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void saveUserPost(Post post) {
}
@POST
@Path("/postuser")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
@Consumes({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void saveUserPost(Post post, List<Attachment> attachments){
}
@PUT
@Path("/{id}")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void deletePost(@PathParam("id") String postid) {
}
@POST
@Path("/postapp")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
@Consumes({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void saveAppPost(Post post) {
}
@POST
@Path("/postapp/")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
@Consumes({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void saveAppPost(Post post, List<Attachment> attachments){
}
@GET
@Path("/{id}/")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void readPost(@PathParam("id") String postid){
}
@GET
@Path("/portalprivacy")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void getAllPortalPrivacyLevelPosts(){
}
@GET
@Path("/{id}/comments")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void getAllCommentByPost(@PathParam("id") String postid){
}
@GET
@Path("/{id}/likes")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void getAllLikesByPost(@PathParam("id") String postid){
}
//the following two methods had vreid why?
@POST
@Path("/{id}/hashtags")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
@Consumes({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void saveHashTags(@PathParam("id") String postid, List<String> hashtags) {
}
@DELETE
@Path("/{id}/hashtags")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
@Consumes({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void deleteHashTagsComment(@PathParam("id") String postid, List<String> hashtags) {
}
@GET
@Path("/{id}/attachments")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void getAttachmentsByPostId(@PathParam("id") String postid) {
}
}

View File

@ -0,0 +1,149 @@
package org.gcube.social_networking.rest;
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 org.gcube.social_networking.socialnetworking.model.shared.InviteStatus;
import org.gcube.social_networking.socialnetworking.model.shared.NotificationChannelType;
import org.gcube.social_networking.socialnetworking.model.shared.NotificationType;
import org.gcube.social_networking.socialnetworking.model.shared.Post;
import javax.ws.rs.*;
import java.util.Map;
@Path("entities")
@ResourceGroup("Users & Apps APIs")
@ResourceLabel("Users & Apps 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 Users {
@GET
@Path("users/{id}/posts")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void getAllPostsByUser(@PathParam("id") String userid) {
}
@GET
@Path("apps/{id}/posts")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void getAllPostsByApp(@PathParam("id") String appid) {
}
@GET
@Path("users/{id}/posts/comments")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void getRecentCommentedPostsByUserAndDate(@PathParam("id") String userid, @QueryParam("time") long timeInMillis) {
}
@GET
@Path("users/{id}/posts")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void getRecentPostsByUser(@PathParam("id") String userid, @QueryParam("limit") int limit) {
}
@GET
@Path("users/{id}/posts")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void getRecentPostsByUser(@PathParam("id") String userid, @QueryParam("time") long timeInMillis) {
}
@PUT
@Path("users/{id}/notifications")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void setAllNotificationReadByUser(@PathParam("id") String userid) {
}
@GET
@Path("users/{id}/notifications")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void getUnreadNotificationsByUser(@PathParam("id") String userid) {
}
@GET
@Path("users/{id}/notificationchannels")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void getUserNotificationChannels(@PathParam("id") String userid, @QueryParam("type") NotificationType notificationType) {
}
@PUT
@Path("users/{id}/notificationpreferences")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
@Consumes({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void setUserNotificationPreferences(@PathParam("id") String userid, Map<NotificationType, NotificationChannelType[]> enabledChannels) {
}
@GET
@Path("users/{id}/notificationpreferences")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void getUserNotificationPreferences(@PathParam("id") String userid) {
}
@GET
@Path("users/{id}/comments")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void getRecentCommentsByUserAndDate(@PathParam("id") String userid, @QueryParam("time") long timeInMillis) {
}
@GET
@Path("users/{id}/likes")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void getAllLikedPostIdsByUser(@PathParam("id") String userid) {
}
@GET
@Path("users/{id}/likes")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void getAllLikedPostsByUser(@PathParam("id") String userid, @QueryParam("limit") int limit) {
}
@GET
@Path("users/{id}/posts/likes")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void getRecentLikedPostsByUserAndDate(@PathParam("id") String userid, @QueryParam("time") long timeInMillis) {
}
@GET
@Path("users/{id}/notifications")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void getAllNotificationByUser(@PathParam("id") String userid, @QueryParam("limit") int limit) {
}
@GET
@Path("users/{id}/notifications")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void getRangeNotificationsByUser(@PathParam("id") String userid, @QueryParam("limit") int limit, @QueryParam("from") int from) {
}
@GET
@Path("users/{id}/notifications/unread")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void checkUnreadNotifications(@PathParam("id") String userid) {
}
@GET
@Path("users/{id}/notifications/unread/messages")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void checkUnreadMessagesNotifications(@PathParam("id") String userid) {
}
}

View File

@ -0,0 +1,98 @@
package org.gcube.social_networking.rest;
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 org.gcube.social_networking.socialnetworking.model.shared.InviteStatus;
import org.gcube.social_networking.socialnetworking.model.shared.Post;
import javax.ws.rs.*;
@Path("vres")
@ResourceGroup("VREs APIs")
@ResourceLabel("VREs 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 Vres {
@POST
@Path("/{id}/posts")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
@Consumes({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void savePostToVRETimeline(@PathParam("id") String vreid, Post post) {
}
@GET
@Path("/{id}/posts")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void getAllPostsByVRE(@PathParam("id") String vreid) {
}
@GET
@Path("/{id}/posts")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void getRecentPostsByVRE(@PathParam("id") String vreid, @QueryParam("limit") int limit) {
}
@GET
@Path("/{id}/posts")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void getRecentPostsByVREAndRange(@PathParam("id") String vreid, @QueryParam("limit") int limit, @QueryParam("from") int from) {
}
@GET
@Path("/{id}/hashtags")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void getVREHashtagsWithOccurrence(@PathParam("id") String vreid) {
}
@GET
@Path("/{id}/hashtags")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void getVREHashtagsWithOccurrenceFilteredByTime(@PathParam("id") String vreid, @QueryParam("time") long timestamp) {
}
@GET
@Path("/{id}/hashtags/{hashtag}/posts")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void getVREPostsByHashtag(@PathParam("id") String vreid, @PathParam("hashtag") String hashtag) {
}
@GET
@Path("/{id}/email/{email}")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void isExistingInvite(@PathParam("id") String vreid, @PathParam("email") String email) {
}
@PUT
@Path("/{id}/email/{email}")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
@Consumes({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void setInviteStatus(@PathParam("id") String vreid, @PathParam("email") String email, InviteStatus status) {
}
@GET
@Path("/{id}")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
@Consumes({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void getInvitedEmailsByVRE(@PathParam("id") String vreid, InviteStatus... status) {
}
@GET
@Path("/")
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
public void getAllVREIds() {
}
}

View File

@ -0,0 +1,221 @@
package org.gcube.social_networking.server;
import static org.gcube.resources.discovery.icclient.ICFactory.clientFor;
import static org.gcube.resources.discovery.icclient.ICFactory.queryFor;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.Serializable;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.gcube.common.portal.GCubePortalConstants;
import org.gcube.common.portal.PortalContext;
import org.gcube.common.resources.gcore.ServiceEndpoint;
import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.social_networking.socialnetworking.model.shared.exceptions.TooManyRunningClustersException;
import org.gcube.resources.discovery.client.api.DiscoveryClient;
import org.gcube.resources.discovery.client.queries.api.SimpleQuery;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Massimiliano Assante ISTI-CNR
* @author Ahmed Ibrahim ISTI-CNR
*
* @version 2.0.0 October 2023
*
*/
@SuppressWarnings("serial")
class CassandraCluster implements Serializable {
/**
* logger
*/
private static final Logger _log = LoggerFactory.getLogger(CassandraCluster.class);
/**
* properties to read
*/
private static final String HOST_PROPERTY = "host";
private static final String HOST_PORT_PROPERTY = "port";
private static final String DATACENTER_NAME_PROPERTY = "datacenter";
private static final String KEY_SPACE_NAME_PROPERTY = "keyspace";
/**
* other constants
*/
private final static String RUNTIME_RESOURCE_NAME = "SocialDB";
private final static String PLATFORM_NAME = "Cassandra";
private static final String DEFAULT_CONFIGURATION = "/org/gcube/portal/databook/server/resources/databook.properties";
private static CassandraCluster singleton;
/**
* Host
*/
private String host;
/**
* Cluster Name
*/
private String datacenterName;
/**
* Keyspace Name
*/
private String keyspaceName; //to be modified
/**
* @param infrastructureName could be null
* @return an instance of the RunningCluster
*/
public static synchronized CassandraCluster getInstance(String infrastructureName){
if (singleton == null) {
singleton = new CassandraCluster(infrastructureName);
}
return singleton;
}
/**
* private constructor
*/
private CassandraCluster(String infrastructureName){
//Query the IS (for the future)
try{
List<ServiceEndpoint> resources = getConfigurationFromIS(infrastructureName);
if (resources.size() > 1) {
_log.error("Too many Runtime Resource having name " + RUNTIME_RESOURCE_NAME +" in this scope ");
throw new TooManyRunningClustersException("There exist more than 1 Runtime Resource in this scope having name "
+ RUNTIME_RESOURCE_NAME + " and Platform " + PLATFORM_NAME + ". Only one allowed per infrasrtucture.");
}
else if (resources.size() == 0){
_log.error("There is no Runtime Resource having name " + RUNTIME_RESOURCE_NAME +" and Platform " + PLATFORM_NAME + " in this scope. Using default configuration properties: " + DEFAULT_CONFIGURATION);
loadDefaultConfiguration();
}
else {
for (ServiceEndpoint res : resources) {
AccessPoint found = res.profile().accessPoints().iterator().next();
host = found.address();
datacenterName = found.description();
keyspaceName = found.name();
}
}
} catch (Exception e) {
e.printStackTrace();
}
/*host = "10.1.28.55:9042, 10.1.30.142:9042, 10.1.28.100:9042";
datacenterName = "1";
keyspaceName = "dev_mig_consistent";*/
}
/**
*
* @return the
* @throws Exception
*/
private List<ServiceEndpoint> getConfigurationFromIS(String infrastructureName) {
_log.debug("getConfigurationFromIS infrastructureName="+infrastructureName );
String scope = "/";
if(infrastructureName != null && !infrastructureName.isEmpty())
scope += infrastructureName;
else {
scope += readInfrastructureName();
_log.debug("infrastrucute name is null, setting root scope=" + scope);
}
String currScope = ScopeProvider.instance.get();
ScopeProvider.instance.set(scope);
SimpleQuery query = queryFor(ServiceEndpoint.class);
query.addCondition("$resource/Profile/Name/text() eq '"+ RUNTIME_RESOURCE_NAME +"'");
query.addCondition("$resource/Profile/Platform/Name/text() eq '"+ PLATFORM_NAME +"'");
DiscoveryClient<ServiceEndpoint> client = clientFor(ServiceEndpoint.class);
List<ServiceEndpoint> toReturn = client.submit(query);
ScopeProvider.instance.set(currScope);
return toReturn;
}
private String readInfrastructureName() {
Properties props = new Properties();
try {
StringBuilder sb = new StringBuilder(getCatalinaHome());
sb.append(File.separator)
.append(PortalContext.CONFIGURATION_FOLDER)
.append(File.separator)
.append(PortalContext.INFRA_PROPERTY_FILENAME);
String propertyfile = sb.toString();
File propsFile = new File(propertyfile);
FileInputStream fis = new FileInputStream(propsFile);
props.load( fis);
return props.getProperty(GCubePortalConstants.INFRASTRUCTURE_NAME);
}
catch(IOException e) {
_log.error("infrastructure.properties file not found under $CATALINA_HOME/conf/ dir, setting default infrastructure Name " + "gcube");
return "gcube";
}
}
/**
*
*/
private void loadDefaultConfiguration() {
Properties props = new Properties();
try {
props.load(CassandraClusterConnection.class.getResourceAsStream(DEFAULT_CONFIGURATION));
host = props.getProperty(HOST_PROPERTY) + ":" + props.getProperty(HOST_PORT_PROPERTY);
datacenterName = props.getProperty(DATACENTER_NAME_PROPERTY);
keyspaceName = props.getProperty(KEY_SPACE_NAME_PROPERTY);
} catch (IOException e) {
e.printStackTrace();
}
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getKeyspaceName() {
return keyspaceName;
}
public void setKeyspaceName(String keyspaceName) {
this.keyspaceName = keyspaceName;
}
@Override
public String toString() {
return "RunningCluster [host=" + host + ", datacenterName=" + datacenterName
+ ", keyspaceName=" + keyspaceName + "]";
}
/**
*
* @return $CATALINA_HOME
*/
private static String getCatalinaHome() {
return (System.getenv("CATALINA_HOME").endsWith("/") ? System.getenv("CATALINA_HOME") : System.getenv("CATALINA_HOME")+"/");
}
public void setDatacenterName(String datacenterName){
this.datacenterName = datacenterName;
}
public String getDatacenterName() {
return datacenterName;
}
public List<InetSocketAddress> getHosts() {
List<InetSocketAddress> hosts = new ArrayList<>();
String [] ips = host.split(", ");
for (String ip: ips){
String[] ip_port = ip.split(":");
hosts.add(new InetSocketAddress(ip_port[0], Integer.parseInt(ip_port[1])));
}
return hosts;
}
}

View File

@ -0,0 +1,501 @@
package org.gcube.social_networking.server;
import java.net.InetSocketAddress;
import java.time.Duration;
import java.util.List;
import com.datastax.oss.driver.api.core.CqlSession;
import com.datastax.oss.driver.api.core.CqlSessionBuilder;
import com.datastax.oss.driver.api.core.config.DefaultDriverOption;
import com.datastax.oss.driver.api.core.config.DriverConfigLoader;
import com.datastax.oss.driver.api.core.cql.ResultSet;
import com.datastax.oss.driver.api.core.metadata.Metadata;
import com.datastax.oss.driver.api.core.metadata.schema.KeyspaceMetadata;
import com.datastax.oss.driver.api.core.type.DataTypes;
import com.datastax.oss.driver.api.querybuilder.SchemaBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Massimiliano Assante ISTI-CNR
* @author Ahmed Ibrahim ISTI-CNR
*
*/
class CassandraClusterConnection {
/**
* logger
*/
private static final Logger _log = LoggerFactory.getLogger(CassandraClusterConnection.class);
/**
* keyspace location
*/
private static List<InetSocketAddress> hosts;
private static String datacenterName;
private static String keyspaceName;
private CqlSession myKeyspaceSession;
/**
*
* @param dropSchema set true if you want do drop the current and set up new one
* the connection to cassandra cluster
*/
protected CassandraClusterConnection(boolean dropSchema) throws Exception {
if (hosts == null || datacenterName == null || keyspaceName == null) {
CassandraCluster cluster = CassandraCluster.getInstance(null);
hosts = cluster.getHosts();
datacenterName = cluster.getDatacenterName();
keyspaceName = cluster.getKeyspaceName();
}
_log.info(keyspaceName + " KeySpace SetUp ...");
SetUpKeySpaces(dropSchema);
myKeyspaceSession = connect(keyspaceName);
_log.info("CONNECTED! using KeySpace: " + keyspaceName);
}
/**
*
* @param dropSchema set true if you want to drop the current and set up new one
* the connection to cassandra cluster
*/
protected CassandraClusterConnection(boolean dropSchema, String infrastructureName) throws Exception {
if (hosts == null || datacenterName == null || keyspaceName == null) {
CassandraCluster cluster = CassandraCluster.getInstance(infrastructureName);
hosts = cluster.getHosts();
datacenterName = cluster.getDatacenterName();
keyspaceName = cluster.getKeyspaceName();
}
_log.info(keyspaceName + " KeySpace SetUp ...");
SetUpKeySpaces(dropSchema);
myKeyspaceSession = connect(keyspaceName);
_log.info("CONNECTED! using KeySpace: " + keyspaceName);
}
public CqlSession getKeyspaceSession(){
if (myKeyspaceSession.isClosed()){
myKeyspaceSession = connect(keyspaceName);
}
return myKeyspaceSession;
}
/**
* @param dropSchema set true if you want to drop the current and set up new one
* the connection to cassandra cluster
*/
public void SetUpKeySpaces(boolean dropSchema) {
boolean createNew = false;
boolean found = false;
CqlSession session = connect();
Metadata metaData = session.getMetadata();
for (KeyspaceMetadata meta : metaData.getKeyspaces().values()) {
if (meta.getName().toString().equals(keyspaceName)){
found = true;
break;
}
}
try {
if (dropSchema && found) {
_log.info("Dropping Keyspace: " + keyspaceName + " ...");
try {
ResultSet returned = dropKeyspace();
Thread.sleep(2000);
if (returned.wasApplied())
_log.info("Dropped " + keyspaceName);
else
_log.info("Couldn't drop " + keyspaceName);
} catch (Exception e) {
_log.error("Dropping Keyspace operation Failed ... " + keyspaceName + " does NOT exists");
return;
}
createNew = true;
}
if (!found || createNew) {
_log.info("Keyspace does not exist, triggering schema creation ... ");
int replicationFactor = 2;
createKeyspace(keyspaceName, replicationFactor);
closeSession(session);
createTables();
_log.info("Using Keyspace " + keyspaceName);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/*
*
********************** CASSANDRA KEYSPACE CREATION ***********************
*
*/
private static CqlSession connect() {
CqlSession cqlSession = configBuilder(CqlSession.builder())
.addContactPoints(hosts)
.withLocalDatacenter(datacenterName)
.build();
_log.info("[OK] Connected to Cassandra Cluster");
return cqlSession;
}
private static CqlSession connect(String KEYSPACE_NAME) {
CqlSession cqlSession = configBuilder(CqlSession.builder())
.addContactPoints(hosts)
.withKeyspace(KEYSPACE_NAME)
.withLocalDatacenter(datacenterName)
.build();
_log.info("[OK] Connected to Keyspace {} ", KEYSPACE_NAME);
return cqlSession;
}
public static void closeSession(CqlSession session) {
if (session != null) session.close();
_log.info("[OK]Session is now closed");
}
public void closeConnection(){
if(!myKeyspaceSession.isClosed()){
try{
_log.info("Closing connection");
closeSession(myKeyspaceSession);
_log.info("Connection closed!");
}catch(Exception e){
_log.error("Unable to close connection", e);
}
}
}
private static CqlSessionBuilder configBuilder(CqlSessionBuilder cqlSessionBuilder){
return cqlSessionBuilder
.withConfigLoader(DriverConfigLoader.programmaticBuilder()
// Resolves the timeout query 'SELECT * FROM system_schema.tables' timed out after PT2S
.withDuration(DefaultDriverOption.METADATA_SCHEMA_REQUEST_TIMEOUT, Duration.ofMillis(240000))
.withDuration(DefaultDriverOption.CONNECTION_INIT_QUERY_TIMEOUT, Duration.ofMillis(240000))
.withDuration(DefaultDriverOption.REQUEST_TIMEOUT, Duration.ofMillis(240000))
.build());
}
private static void createKeyspace(String keyspaceName, int replicationFactor) {
try (CqlSession cqlSession = configBuilder(CqlSession.builder())
.addContactPoints(hosts)
.withLocalDatacenter(datacenterName)
.build()) {
cqlSession.execute(SchemaBuilder.createKeyspace(keyspaceName)
.ifNotExists()
.withSimpleStrategy(replicationFactor)
.withDurableWrites(true)
.build());
_log.info("+ Keyspace '{}' created.", keyspaceName);
closeSession(cqlSession);
}
}
private static ResultSet dropKeyspace(){
ResultSet toreturn;
try (CqlSession cqlSession = configBuilder(CqlSession.builder())
.addContactPoints(hosts)
.withLocalDatacenter(datacenterName)
.build()) {
toreturn = cqlSession.execute(SchemaBuilder.dropKeyspace(keyspaceName).ifExists().build());
_log.info("Keyspace {} dropped.", keyspaceName);
closeSession(cqlSession);
}
return toreturn;
}
private void createTables(){
try (CqlSession cqlSession = configBuilder(CqlSession.builder())
.addContactPoints(hosts)
.withLocalDatacenter(datacenterName)
.withKeyspace(keyspaceName)
.build()) {
createTableUSERNotificationsPreferences(cqlSession);
createTableUSERNotifications(cqlSession);
createTableVRETimeline(cqlSession);
createTableAppTimeline(cqlSession);
createTableUSERTimeline(cqlSession);
createTableHashtaggedPosts(cqlSession);
createTableHashtaggedComments(cqlSession);
createTableHashtagsCounter(cqlSession);
createTableUSERNotificationsUnread(cqlSession);
createTableUSERLikes(cqlSession);
createTableVREInvites(cqlSession);
createTableEMAILInvites(cqlSession);
createTableAttachments(cqlSession);
createTableInvites(cqlSession);
createTableLikes(cqlSession);
createTableComments(cqlSession);
createTableNotifications(cqlSession);
createTablePosts(cqlSession);
closeSession(cqlSession);
}
}
private void createTableUSERNotificationsPreferences(CqlSession cqlSession) {
cqlSession.execute(SchemaBuilder.createTable("UserNotificationsPreferences")
.ifNotExists()
.withPartitionKey("userid", DataTypes.TEXT)
.withPartitionKey("type", DataTypes.TEXT)
.withColumn("preference", DataTypes.TEXT)
.withCompactStorage()
.build());
_log.info("+ Table '{}' has been created (if needed).", "USERNotificationsPreferences");
}
private void createTableUSERNotifications(CqlSession cqlSession) {
cqlSession.execute(SchemaBuilder.createTable("UserNotifications")
.ifNotExists()
.withPartitionKey("userid", DataTypes.TEXT)
.withPartitionKey("timestamp", DataTypes.TIMESTAMP)
.withColumn("notid", DataTypes.UUID)
.withCompactStorage()
.build());
_log.info("+ Table '{}' has been created (if needed).", "USERNotifications");
}
private void createTableVRETimeline(CqlSession cqlSession) {
cqlSession.execute(SchemaBuilder.createTable("VRETimeline")
.ifNotExists()
.withPartitionKey("vreid", DataTypes.TEXT)
.withPartitionKey("timestamp", DataTypes.TIMESTAMP)
.withColumn("postid", DataTypes.UUID)
.withCompactStorage()
.build());
_log.info("+ Table '{}' has been created (if needed).", "VRETimeline");
}
private void createTableAppTimeline(CqlSession cqlSession) {
cqlSession.execute(SchemaBuilder.createTable("AppTimeline")
.ifNotExists()
.withPartitionKey("appid", DataTypes.TEXT)
.withPartitionKey("timestamp", DataTypes.TIMESTAMP)
.withColumn("postid", DataTypes.UUID)
.withCompactStorage()
.build());
_log.info("+ Table '{}' has been created (if needed).", "AppTimeline");
}
private void createTableUSERTimeline(CqlSession cqlSession) {
cqlSession.execute(SchemaBuilder.createTable("UserTimeline")
.ifNotExists()
.withPartitionKey("userid", DataTypes.TEXT)
.withPartitionKey("timestamp", DataTypes.TIMESTAMP)
.withColumn("postid", DataTypes.UUID)
.withCompactStorage()
.build());
_log.info("+ Table '{}' has been created (if needed).", "USERTimeline");
}
private void createTableHashtaggedPosts(CqlSession cqlSession) {
cqlSession.execute(SchemaBuilder.createTable("HashtaggedPosts")
.ifNotExists()
.withPartitionKey("hashtag", DataTypes.TEXT)
.withPartitionKey("postid", DataTypes.UUID)
.withColumn("vreid", DataTypes.TEXT)
.withCompactStorage()
.build());
_log.info("+ Table '{}' has been created (if needed).", "HashtaggedPosts");
}
private void createTableHashtaggedComments(CqlSession cqlSession) {
cqlSession.execute(SchemaBuilder.createTable("HashtaggedComments")
.ifNotExists()
.withPartitionKey("hashtag", DataTypes.TEXT)
.withPartitionKey("commentid", DataTypes.UUID)
.withColumn("vreid", DataTypes.TEXT)
.withCompactStorage()
.build());
_log.info("+ Table '{}' has been created (if needed).", "HashtaggedComments");
}
private void createTableHashtagsCounter(CqlSession cqlSession) {
cqlSession.execute(SchemaBuilder.createTable("HashtagsCounter")
.ifNotExists()
.withPartitionKey("vreid", DataTypes.TEXT)
.withPartitionKey("hashtag", DataTypes.TEXT)
.withColumn("count", DataTypes.BIGINT)
.withCompactStorage()
.build());
_log.info("+ Table '{}' has been created (if needed).", "HashtagsCounter");
}
private void createTableUSERNotificationsUnread(CqlSession cqlSession) {
cqlSession.execute(SchemaBuilder.createTable("UserUnreadNotifications")
.ifNotExists()
.withPartitionKey("userid", DataTypes.TEXT)
.withPartitionKey("timestamp", DataTypes.TIMESTAMP)
.withColumn("notid", DataTypes.UUID)
.withCompactStorage()
.build());
_log.info("+ Table '{}' has been created (if needed).", "USERNotificationsUnread");
}
private void createTableUSERLikes(CqlSession cqlSession) {
cqlSession.execute(SchemaBuilder.createTable("UserLikes")
.ifNotExists()
.withPartitionKey("userid", DataTypes.TEXT)
.withPartitionKey("likeid", DataTypes.UUID)
.withColumn("postid", DataTypes.UUID)
.withCompactStorage()
.build());
_log.info("+ Table '{}' has been created (if needed).", "USERLikes");
}
private void createTableVREInvites(CqlSession cqlSession) {
cqlSession.execute(SchemaBuilder.createTable("VREInvites")
.ifNotExists()
.withPartitionKey("vreid", DataTypes.TEXT)
.withPartitionKey("inviteid", DataTypes.UUID)
.withColumn("status", DataTypes.TEXT)
.withCompactStorage()
.build());
_log.info("+ Table '{}' has been created (if needed).", "VREInvites");
}
private void createTableEMAILInvites(CqlSession cqlSession) {
cqlSession.execute(SchemaBuilder.createTable("EmailInvites")
.ifNotExists()
.withPartitionKey("email", DataTypes.TEXT)
.withPartitionKey("vreid", DataTypes.TEXT)
.withColumn("inviteid", DataTypes.UUID)
.withCompactStorage()
.build());
_log.info("+ Table '{}' has been created (if needed).", "EMAILInvites");
}
private void createTableAttachments(CqlSession cqlSession) {
cqlSession.execute(SchemaBuilder.createTable("Attachments")
.ifNotExists()
.withPartitionKey("attachid", DataTypes.UUID)
.withColumn("postid", DataTypes.UUID)
.withColumn("uri", DataTypes.TEXT)
.withColumn("name", DataTypes.TEXT)
.withColumn("description", DataTypes.TEXT)
.withColumn("urithumbnail", DataTypes.TEXT)
.withColumn("mimetype", DataTypes.TEXT)
.withCompactStorage()
.build());
cqlSession.execute(SchemaBuilder.createIndex("post_attach")
.ifNotExists()
.onTable("Attachments")
.andColumn("postid")
.build());
_log.info("+ Table '{}' has been created (if needed).", "Attachments");
}
private void createTableInvites(CqlSession cqlSession) {
cqlSession.execute(SchemaBuilder.createTable("Invites")
.ifNotExists()
.withPartitionKey("inviteid", DataTypes.UUID)
.withColumn("senderuserid", DataTypes.TEXT)
.withColumn("vreid", DataTypes.TEXT)
.withColumn("email", DataTypes.TEXT)
.withColumn("controlcode", DataTypes.TEXT)
.withColumn("status", DataTypes.TEXT)
.withColumn("timestamp", DataTypes.TIMESTAMP)
.withColumn("senderfullname", DataTypes.TEXT)
.withCompactStorage()
.build());
cqlSession.execute(SchemaBuilder.createIndex("sender")
.ifNotExists()
.onTable("Invites")
.andColumn("senderuserid")
.build());
_log.info("+ Table '{}' has been created (if needed).", "Invites");
}
private void createTableLikes(CqlSession cqlSession) {
cqlSession.execute(SchemaBuilder.createTable("Likes")
.ifNotExists()
.withPartitionKey("likeid", DataTypes.UUID)
.withColumn("userid", DataTypes.TEXT)
.withColumn("fullname", DataTypes.TEXT)
.withColumn("thumbnailurl", DataTypes.TEXT)
.withColumn("postid", DataTypes.UUID)
.withColumn("timestamp", DataTypes.TIMESTAMP)
.withCompactStorage()
.build());
cqlSession.execute(SchemaBuilder.createIndex("post_likes")
.ifNotExists()
.onTable("Likes")
.andColumn("postid")
.build());
_log.info("+ Table '{}' has been created (if needed).", "Likes");
}
private void createTableComments(CqlSession cqlSession) {
cqlSession.execute(SchemaBuilder.createTable("Comments")
.ifNotExists()
.withPartitionKey("commentid", DataTypes.UUID)
.withColumn("userid", DataTypes.TEXT)
.withColumn("fullname", DataTypes.TEXT)
.withColumn("thumbnailurl", DataTypes.TEXT)
.withColumn("comment", DataTypes.TEXT)
.withColumn("postid", DataTypes.UUID)
.withColumn("timestamp", DataTypes.TIMESTAMP)
.withColumn("isedit", DataTypes.BOOLEAN)
.withColumn("lastedittime", DataTypes.TIMESTAMP)
.withCompactStorage()
.build());
cqlSession.execute(SchemaBuilder.createIndex("post_comments")
.ifNotExists()
.onTable("Comments")
.andColumn("postid")
.build());
_log.info("+ Table '{}' has been created (if needed).", "Comments");
}
private void createTableNotifications(CqlSession cqlSession) {
cqlSession.execute(SchemaBuilder.createTable("Notifications")
.ifNotExists()
.withPartitionKey("notid", DataTypes.UUID)
.withColumn("type", DataTypes.TEXT)
.withColumn("userid", DataTypes.TEXT)
.withColumn("subjectid", DataTypes.TEXT)
.withColumn("timestamp", DataTypes.TIMESTAMP)
.withColumn("description", DataTypes.TEXT)
.withColumn("uri", DataTypes.TEXT)
.withColumn("senderid", DataTypes.TEXT)
.withColumn("senderfullname", DataTypes.TEXT)
.withColumn("senderthumbnailurl", DataTypes.TEXT)
.withColumn("isread", DataTypes.BOOLEAN)
.withCompactStorage()
.build());
cqlSession.execute(SchemaBuilder.createIndex("not_type")
.ifNotExists()
.onTable("Notifications")
.andColumn("type")
.build());
_log.info("+ Table '{}' has been created (if needed).", "Notifications");
}
private void createTablePosts(CqlSession cqlSession) {
cqlSession.execute(SchemaBuilder.createTable("Posts")
.ifNotExists()
.withPartitionKey("postid", DataTypes.UUID)
.withColumn("linkhost", DataTypes.TEXT)
.withColumn("description", DataTypes.TEXT)
.withColumn("email", DataTypes.TEXT)
.withColumn("likesno", DataTypes.BIGINT)
.withColumn("thumbnailurl", DataTypes.TEXT)
.withColumn("linkdescription", DataTypes.TEXT)
.withColumn("timestamp", DataTypes.TIMESTAMP)
.withColumn("uri", DataTypes.TEXT)
.withColumn("isapplicationpost", DataTypes.BOOLEAN)
.withColumn("entityid", DataTypes.TEXT)
.withColumn("privacy", DataTypes.TEXT)
.withColumn("type", DataTypes.TEXT)
.withColumn("urithumbnail", DataTypes.TEXT)
.withColumn("vreid", DataTypes.TEXT)
.withColumn("multifileupload", DataTypes.BOOLEAN)
.withColumn("fullname", DataTypes.TEXT)
.withColumn("commentsno", DataTypes.BIGINT)
.withColumn("linktitle", DataTypes.TEXT)
.withCompactStorage()
.build());
cqlSession.execute(SchemaBuilder.createIndex("posts_privacy")
.ifNotExists()
.onTable("Posts")
.andColumn("privacy")
.build());
_log.info("+ Table '{}' has been created (if needed).", "Posts");
}
}

View File

@ -0,0 +1,49 @@
package org.gcube.social_networking.server;
import org.gcube.smartgears.ContextProvider;
import org.gcube.smartgears.context.application.ApplicationContext;
import org.slf4j.LoggerFactory;
/**
* Cassandra connection class.
* @author Costantino Perciante at ISTI-CNR
*/
public class CassandraConnection {
// Logger
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(CassandraConnection.class);
// databook store (singleton)
private static SocialDBDriver store;
private static CassandraConnection singleton = new CassandraConnection();
private CassandraConnection(){
ApplicationContext ctx = ContextProvider.get(); // get this info from SmartGears
logger.info("Getting connection to cassandra");
store = new SocialDBDatastaxDriver(ctx.container().configuration().infrastructure());
logger.info("Connection to cassandra created");
}
/**
* Returns the object to query the cassandra cluster.
* @return connection pool to cassandra cluster
*/
public SocialDBDriver getDatabookStore(){
return store;
}
/**
* Get the instance
* @return
*/
public static CassandraConnection getInstance(){
return singleton;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,449 @@
package org.gcube.social_networking.server;
import java.util.List;
import java.util.Map;
import javax.mail.internet.AddressException;
import org.gcube.social_networking.socialnetworking.model.shared.Attachment;
import org.gcube.social_networking.socialnetworking.model.shared.Comment;
import org.gcube.social_networking.socialnetworking.model.shared.Invite;
import org.gcube.social_networking.socialnetworking.model.shared.InviteOperationResult;
import org.gcube.social_networking.socialnetworking.model.shared.InviteStatus;
import org.gcube.social_networking.socialnetworking.model.shared.Like;
import org.gcube.social_networking.socialnetworking.model.shared.Notification;
import org.gcube.social_networking.socialnetworking.model.shared.NotificationChannelType;
import org.gcube.social_networking.socialnetworking.model.shared.NotificationType;
import org.gcube.social_networking.socialnetworking.model.shared.Post;
import org.gcube.social_networking.socialnetworking.model.shared.RangePosts;
import org.gcube.social_networking.socialnetworking.model.shared.exceptions.ColumnNameNotFoundException;
import org.gcube.social_networking.socialnetworking.model.shared.exceptions.CommentIDNotFoundException;
import org.gcube.social_networking.socialnetworking.model.shared.exceptions.PostIDNotFoundException;
import org.gcube.social_networking.socialnetworking.model.shared.exceptions.PostTypeNotFoundException;
import org.gcube.social_networking.socialnetworking.model.shared.exceptions.InviteIDNotFoundException;
import org.gcube.social_networking.socialnetworking.model.shared.exceptions.InviteStatusNotFoundException;
import org.gcube.social_networking.socialnetworking.model.shared.exceptions.LikeIDNotFoundException;
import org.gcube.social_networking.socialnetworking.model.shared.exceptions.NotificationChannelTypeNotFoundException;
import org.gcube.social_networking.socialnetworking.model.shared.exceptions.NotificationIDNotFoundException;
import org.gcube.social_networking.socialnetworking.model.shared.exceptions.NotificationTypeNotFoundException;
import org.gcube.social_networking.socialnetworking.model.shared.exceptions.PrivacyLevelTypeNotFoundException;
/**
* @author Massimiliano Assante ISTI-CNR
* @author Costantino Perciante ISTI-CNR
* <class>DatabookStore</class> is the high level interface for querying and adding data to DatabookStore
*/
public interface SocialDBDriver {
/**
* save a Post instance in the store
* @return true if everything went fine
*/
boolean saveUserPost(Post post);
/**
* Save a Post instance in the store having more than one attachment
* Use this if you need to attach more than one file to the post
*
* @param attachments a list of attachments starting from the second
* @return true if everything went fine
*/
boolean saveUserPost(Post post, List<Attachment> attachments);
/**
* delete a post from the store
* @throws PostIDNotFoundException
* @return true if everything went fine
*/
boolean deletePost(String postid) throws PostIDNotFoundException, PrivacyLevelTypeNotFoundException, PostTypeNotFoundException, ColumnNameNotFoundException;
/**
* save a post in the VRES TimeLine in the store
* @param postKey the post id
* @param vreid vre identifier
* @throws PostIDNotFoundException
*/
boolean savePostToVRETimeline(String postKey, String vreid) throws PostIDNotFoundException;
/**
* save a Post instance in the store
* @return true if everything went fine
*/
boolean saveAppPost(Post post);
/**
* Save a Post instance in the store
* Use this if your app needs to attach more than one file to the post
*
* @param attachments a list of attachments starting from the second
* @return true if everything went fine
*/
boolean saveAppPost(Post post, List<Attachment> attachments);
/**
* read a post from a given id
* @throws PrivacyLevelTypeNotFoundException
* @throws PostTypeNotFoundException
* @throws ColumnNameNotFoundException
*/
Post readPost(String postid) throws PrivacyLevelTypeNotFoundException, PostTypeNotFoundException, PostIDNotFoundException, ColumnNameNotFoundException;
/**
* @param userid user identifier
* return all the posts belonging to the userid
* @throws PostTypeNotFoundException
* @throws PrivacyLevelTypeNotFoundException
* @throws ColumnNameNotFoundException
*/
List<Post> getAllPostsByUser(String userid) throws PrivacyLevelTypeNotFoundException, PostTypeNotFoundException, PostIDNotFoundException, ColumnNameNotFoundException;
/**
* @param appid application identifier
* return all the posts belonging to the appid
* @throws PostTypeNotFoundException
* @throws PrivacyLevelTypeNotFoundException
* @throws ColumnNameNotFoundException
*/
List<Post> getAllPostsByApp(String appid) throws PrivacyLevelTypeNotFoundException, PostTypeNotFoundException, PostIDNotFoundException, ColumnNameNotFoundException;
/**
* @param userid the user identifier like andrea.rossi
* @param timeInMillis the initial time in millis to be considered
* @return a list of posts commented by userid starting from timeInMillis
* @throws Exception
*/
List<Post> getRecentCommentedPostsByUserAndDate(String userid, long timeInMillis) throws Exception;
/**
* return all the posts whose Level is PORTAL
* @throws PrivacyLevelTypeNotFoundException
* @throws ColumnNameNotFoundException
* @throws PrivacyLevelTypeNotFoundException
*/
List<Post> getAllPortalPrivacyLevelPosts() throws PostTypeNotFoundException, ColumnNameNotFoundException, PrivacyLevelTypeNotFoundException;
/**
* return the most recent posts for this user up to quantity param
* @param userid user identifier
* @param quantity the number of most recent posts for this user
* @return a <class>List</class> of most recent posts for this user
* @throws PostTypeNotFoundException
* @throws PrivacyLevelTypeNotFoundException
* @throws ColumnNameNotFoundException
*/
List<Post> getRecentPostsByUser(String userid, int quantity) throws PrivacyLevelTypeNotFoundException, PostTypeNotFoundException, ColumnNameNotFoundException, PostIDNotFoundException;
/**
* @param vreid vre identifier
* return all the posts belonging to the userid
* @throws PostTypeNotFoundException
* @throws PrivacyLevelTypeNotFoundException
* @throws ColumnNameNotFoundException
*/
List<Post> getAllPostsByVRE(String vreid) throws PrivacyLevelTypeNotFoundException, PostTypeNotFoundException, ColumnNameNotFoundException, PostIDNotFoundException;
/**
* return the most recent posts for this vre up to quantity param
* @param vreid VRES identifier
* @param quantity the number of most recent posts for this vre
* @return a <class>List</class> of most recent posts for this vre
* @throws PostTypeNotFoundException
* @throws PrivacyLevelTypeNotFoundException
* @throws ColumnNameNotFoundException
*/
List<Post> getRecentPostsByVRE(String vreid, int quantity) throws IllegalArgumentException, PrivacyLevelTypeNotFoundException, PostTypeNotFoundException, ColumnNameNotFoundException, PostIDNotFoundException;
/**
* return the most recent posts for this vre up to quantity param and the last index of the posts in the timeline
* lastReturnedPostTimelineIndex is useful to know from where to start the range the next time you ask, because there are deletions
*
* @param vreid VRES identifier
* @param from the range start (most recent posts for this vre) has to be greater than 0
* @param quantity the number of most recent posts for this vre starting from "from" param
* @return a <class>RangePosts</class> containing of most recent posts for this vre
* @throws PostTypeNotFoundException
* @throws PrivacyLevelTypeNotFoundException
* @throws ColumnNameNotFoundException
*/
RangePosts getRecentPostsByVREAndRange(String vreid, int from, int quantity) throws PrivacyLevelTypeNotFoundException, PostTypeNotFoundException, ColumnNameNotFoundException, PostIDNotFoundException;
/**
* @param userid user identifier
* @param timeInMillis time in milliseconds from which you want to start retrieve the posts
* @return the number of posts in the range from: today to: timeInMillis
*/
List<Post> getRecentPostsByUserAndDate(String userid, long timeInMillis) throws IllegalArgumentException;
/**
* save a Notification instance in the store
* @return true if everything went fine
*/
boolean saveNotification(Notification notification);
/**
* set an existing Notification instance in the to read
* @return true if everything went fine
*/
boolean setNotificationRead(String notificationidToSet) throws NotificationIDNotFoundException, NotificationTypeNotFoundException, ColumnNameNotFoundException;
/**
* read a notification from a given id
* @throws {@link ColumnNameNotFoundException}
* @throws {@link NotificationIDNotFoundException}
* @throws {@link NotificationTypeNotFoundException}
*/
Notification readNotification(String notificationid) throws NotificationIDNotFoundException, NotificationTypeNotFoundException, ColumnNameNotFoundException;
/**
* @param userid user identifier
* @param limit set 0 to get everything, an int to get the most recent -limit- notifications
* return all the notifications belonging to the userid up to limit, set 0 to get everything
* @throws NotificationTypeNotFoundException
* @throws ColumnNameNotFoundException
*/
List<Notification> getAllNotificationByUser(String userid, int limit) throws NotificationTypeNotFoundException, ColumnNameNotFoundException, NotificationIDNotFoundException;
/**
*
* @param userid user identifier
* @param from the range start has to be greater than 0
* @param quantity the number of most recent notifications for this user starting from "from" param
* @return all the notifications for the userid in the range requested
* @throws NotificationTypeNotFoundException
* @throws ColumnNameNotFoundException
* @throws NotificationIDNotFoundException
*/
List<Notification> getRangeNotificationsByUser(String userid, int from, int quantity) throws NotificationTypeNotFoundException, ColumnNameNotFoundException, NotificationIDNotFoundException;
/**
* This is a fast way to set all notification to read quickly
* @param userid
* @return true if everything went fine
* @throws {@link ColumnNameNotFoundException}
* @throws {@link NotificationIDNotFoundException}
* @throws {@link NotificationTypeNotFoundException}
*/
boolean setAllNotificationReadByUser(String userid) throws NotificationIDNotFoundException, NotificationTypeNotFoundException, ColumnNameNotFoundException;
/**
* return the not yet read notifications (not including messages)
* @param userid user identifier
* @return a <class>List</class> of not yet read notifications for this user
* @throws NotificationTypeNotFoundException
* @throws ColumnNameNotFoundException
*/
List<Notification> getUnreadNotificationsByUser(String userid) throws NotificationTypeNotFoundException, ColumnNameNotFoundException, NotificationIDNotFoundException;
/**
*
* @param userid user identifier
* @throws ColumnNameNotFoundException
* @throws NotificationTypeNotFoundException
* @throws NotificationIDNotFoundException
* @return true if there are unread notifications (not including messages), false if they are all read
*/
boolean checkUnreadNotifications(String userid) throws NotificationIDNotFoundException, NotificationTypeNotFoundException, ColumnNameNotFoundException;
/**
*
* @param userid user identifier
* @throws ColumnNameNotFoundException
* @throws NotificationTypeNotFoundException self explaining
* @throws NotificationChannelTypeNotFoundException self explaining
* @throws NotificationIDNotFoundException
* @return true if there are unread messages notifications (including messages), false if they are all read
*/
boolean checkUnreadMessagesNotifications(String userid) throws NotificationIDNotFoundException, NotificationTypeNotFoundException, ColumnNameNotFoundException;
/**
* return the channels a user chose for being notified for a given notification type
* @param userid user identifier
* @param notificationType the type of the notification
* @return a list of <class>NotificationChannelType</class> that represents the channels this user wants to be notified
*/
List<NotificationChannelType> getUserNotificationChannels(String userid, NotificationType notificationType) throws NotificationChannelTypeNotFoundException, NotificationTypeNotFoundException;
/**
* set the notification preferences map (enable or disable the channels to be used for notifying the user)
* @param userid user identifier
* @param enabledChannels a map of the channels to which reach the user per notification, empty array or null values to set the key notification type off
* @return true if everything was fine
*/
boolean setUserNotificationPreferences(String userid, Map<NotificationType, NotificationChannelType[]> enabledChannels);
/**
* get the notification preferences map (enableor disable the channels to be used for notifying the user)
* @param userid user identifier
* @return the map
* @throws NotificationTypeNotFoundException self explaining
* @throws NotificationChannelTypeNotFoundException self explaining
*/
Map<NotificationType, NotificationChannelType[]> getUserNotificationPreferences(String userid) throws NotificationTypeNotFoundException, NotificationChannelTypeNotFoundException;
/**
* @param commentId comment unique identifier
* @return the comment belonging to the commentId
* @throws CommentIDNotFoundException
*/
Comment readCommentById(String commentId) throws CommentIDNotFoundException;
/**
* add a comment to a post
* @param comment the Comment instance to add
*/
boolean addComment(Comment comment) throws PostIDNotFoundException;
/**
* @param postid the post identifier
* return all the comments belonging to the postid
*/
List<Comment> getAllCommentByPost(String postid);
/**
* @param userid user identifier
* @param timeInMillis time in milliseconds from which you want to start retrieve the posts
* @return a list of comments (sorted starting from the most recent one) made by the user since timeInMillis up to now
*/
List<Comment> getRecentCommentsByUserAndDate(String userid, long timeInMillis) throws Exception;
/**
* edit a comment
* @param comment the comment to edit
* @return true if success, false otherwise
*/
boolean editComment(Comment comment) throws PrivacyLevelTypeNotFoundException, PostTypeNotFoundException, ColumnNameNotFoundException, CommentIDNotFoundException, PostIDNotFoundException;
/**
* deletes a comment
* @param commentid the comment identifier to delete
* @param postid the postid to which the comment is associated
* @return true if success, false otherwise
*/
boolean deleteComment(String commentid, String postid) throws PrivacyLevelTypeNotFoundException, PostTypeNotFoundException, ColumnNameNotFoundException, CommentIDNotFoundException, PostIDNotFoundException;
/**
* add a like to a post
* @param like instance
* @throws PostIDNotFoundException
*/
boolean like(Like like) throws PostIDNotFoundException;
/**
* unlike a post
* @param userid user identifier
* @param likeid the like identifier to delete
* @param postid the postid to which the comment is associated
* @return true if success, false otherwise
*/
boolean unlike(String userid, String likeid, String postid) throws PrivacyLevelTypeNotFoundException, PostTypeNotFoundException, ColumnNameNotFoundException, LikeIDNotFoundException, PostIDNotFoundException;
/**
* @param userid user identifier
* return all the postids a user has liked
*/
List<String> getAllLikedPostIdsByUser(String userid);
/**
* @param userid user identifier
* @param limit set 0 to get everything, an int to get the most recent -limit- liked posts
* @throws ColumnNameNotFoundException .
* @throws PostIDNotFoundException .
* @throws PostTypeNotFoundException .
* @throws PrivacyLevelTypeNotFoundException
* return all the posts a user has liked
*/
List<Post> getAllLikedPostsByUser(String userid, int limit) throws PrivacyLevelTypeNotFoundException, PostTypeNotFoundException, PostIDNotFoundException, ColumnNameNotFoundException;
/**
* @param userid user identifier
* @param timeInMillis time in milliseconds from which you want to start retrieve the posts
* @return the likes made to posts in the range from: today to: timeInMillis
*/
List<Post> getRecentLikedPostsByUserAndDate(String userid, long timeInMillis) throws IllegalArgumentException;
/**
* @param postid postid identifier
* return all the likes belonging to the postid
*/
List<Like> getAllLikesByPost(String postid);
/**
*
* @param hashtags the hashtag including the '#'
* @param postid the postid to which the hashtag is associated
* @param vreid VRE identifier
* @return true if success, false otherwise
* @throws PostIDNotFoundException
*/
boolean saveHashTags(String postid, String vreid, List<String> hashtags) throws PostIDNotFoundException;
/**
*
* @param hashtags the hashtag including the '#'
* @param commentId the commentId to which the hashtag is associated
* @param vreid VRE identifier
* @return true if success, false otherwise
* @throws CommentIDNotFoundException
*/
boolean saveHashTagsComment(String commentId, String vreid, List<String> hashtags) throws CommentIDNotFoundException;
/**
*
* @param hashtags the hashtag including the '#'
* @param postid the postid to which the hashtag is associated
* @param vreid VRE identifier
* @return true if success, false otherwise
* @throws PostIDNotFoundException
*/
boolean deleteHashTags(String postid, String vreid, List<String> hashtags) throws PostIDNotFoundException;
/**
*
* @param hashtags the hashtag including the '#'
* @param commentId the commentId to which the hashtag is associated
* @param vreid VRE identifier
* @return true if success, false otherwise
* @throws CommentIDNotFoundException
*/
boolean deleteHashTagsComment(String commentId, String vreid, List<String> hashtags) throws CommentIDNotFoundException;
/**
* get a map of vre hashtags where the key is the hashtag and the value is the occurrence of the hashtag in the VRE
* @param vreid vre identifier (scope)
* @return a HashMap<String, Integer> of vre Hashtags associated with their occurrence
*/
Map<String, Integer> getVREHashtagsWithOccurrence(String vreid);
/**
* get a map of vre hashtags where the key is the hashtag and the value is the occurrence of the hashtag in the VRE
* @param vreid vre identifier (scope)
* @param timestamp do not consider hashtags used before timestamp
* @return a HashMap<String, Integer> of vre Hashtags associated with their occurrence
*/
Map<String, Integer> getVREHashtagsWithOccurrenceFilteredByTime(String vreid, long timestamp);
/**
*
* @param vreid VRE identifier
* @param hashtag the hashtag to look for including the '#', it is case sensitive
* @throws ColumnNameNotFoundException .
* @throws PostIDNotFoundException .
* @throws PostTypeNotFoundException .
* @throws PrivacyLevelTypeNotFoundException
* @return all the posts having the hashtag passed as parameter
*/
List<Post> getVREPostsByHashtag(String vreid, String hashtag) throws PrivacyLevelTypeNotFoundException, PostTypeNotFoundException, PostIDNotFoundException, ColumnNameNotFoundException;
/**
* Save the invite for a given email into a given vre
* @param invite the invite object instanc to save
* @return {@link InviteOperationResult} SUCCESS, FAILED or ALREADY_INVITED (if an invite is sent to en existing email in the same environment more than once)
*/
InviteOperationResult saveInvite(Invite invite) throws AddressException;
/**
*
* @param vreid the environment where you want to check the invite
* @param email the email of the invite to check in the environmnet
* @return the InviteId if present, null otherwise
*/
String isExistingInvite(String vreid, String email);
/**
* read an invite from a given id
* @throws InviteIDNotFoundException
* @throws InviteStatusNotFoundException
*/
Invite readInvite(String inviteid) throws InviteIDNotFoundException, InviteStatusNotFoundException;
/**
* set the status of an invite, see {@link InviteStatus}
* @throws InviteIDNotFoundException
*/
boolean setInviteStatus(String vreid, String email, InviteStatus status) throws InviteIDNotFoundException, InviteStatusNotFoundException;
/**
* Use to get the list of invites per VRE
* @param vreid the vre id
* @param status optional, if you want to restict on the status, e.g. all pending invites
* @return return the list of invites
* @throws InviteIDNotFoundException
* @throws InviteStatusNotFoundException
*/
List<Invite> getInvitedEmailsByVRE(String vreid, InviteStatus... status) throws InviteIDNotFoundException, InviteStatusNotFoundException;
/**
*
* @param postId
* @return the list of attachments of the post postId, starting from the second one (first attachment is included in post instance already)
*/
List<Attachment> getAttachmentsByPostId(String postId) throws PostIDNotFoundException;
/**
* save an attachment
*/
boolean saveAttachmentEntry(String postId, Attachment toSave);
/**
* Retrieve all the ids of the vre
* @return the set of ids of the vre available or empty list in case of errors.
*/
public List<String> getAllVREIds();
/**
* close the connection to the underlying database
*/
void closeConnection();
}

View File

@ -0,0 +1,76 @@
package org.gcube.social_networking.utils;
/**
* @author Massimiliano Assante ISTI-CNR
* @author Ahmed Ibrahim ISTI-CNR
*
* @version 2.0.0 October 2023
*
*/
public class Schema {
//Tables
public static final String NOTIFICATIONS = "Notifications";
public static final String POSTS = "Posts";
public static final String COMMENTS = "Comments";
public static final String LIKES = "Likes";
public static final String INVITES = "Invites";
public static final String VRE_TIMELINE_POSTS = "VRETimeline";
public static final String USER_TIMELINE_POSTS = "UserTimeline";
public static final String APP_TIMELINE_POSTS = "AppTimeline";
public static final String USER_LIKED_POSTS = "UserLikes";
public static final String USER_NOTIFICATIONS = "UserNotifications"; // regular user notifications timeline (both read and unread, messages are included)
public static final String USER_NOTIFICATIONS_UNREAD = "UserUnreadNotifications"; // only unread user notifications/ notifications messages
public static final String USER_NOTIFICATIONS_PREFERENCES = "UserNotificationsPreferences"; // preferences for notifications
public static final String HASHTAGS_COUNTER = "HashtagsCounter"; // count the hashtags per group and type
public static final String HASHTAGGED_POSTS = "HashtaggedPosts"; // contains hashtags per type associated with vre and POST
public static final String HASHTAGGED_COMMENTS = "HashtaggedComments"; // contains hashtags per type associated with vre and comment
public static final String VRE_INVITES = "VREInvites"; //contains the emails that were invited per VRE
public static final String EMAIL_INVITES = "EmailInvites"; //contains the list of invitation per email
public static final String ATTACHMENTS = "Attachments"; //contains the list of all the attachments in a POST
//columns
public static final String USER_ID = "userid"; //text
public static final String TYPE = "type"; //text
public static final String PREFERENCE = "preference"; //text
public static final String TIMESTAMP = "timestamp"; //timestamp
public static final String NOT_ID = "notid"; //UUID
public static final String VRE_ID = "vreid"; //text
public static final String POST_ID = "postid"; //UUID
public static final String APP_ID = "appid"; //text
public static final String HASHTAG = "hashtag"; //text
public static final String COMMENT_ID = "commentid"; //UUID
public static final String COUNT = "count"; //big int
public static final String LIKE_ID = "likeid"; //UUID
public static final String INVITE_ID = "inviteid"; //UUID
public static final String STATUS = "status"; //text
public static final String EMAIL = "email"; //text
public static final String ATTACH_ID = "attachid"; //UUID
public static final String URI = "uri"; //text
public static final String NAME = "name"; //text
public static final String DESCRIPTION = "description"; //text
public static final String URI_THUMBNAIL = "urithumbnail"; //text
public static final String MIME_TYPE = "mimetype"; //text
public static final String SENDER_USER_ID = "senderuserid"; //text
public static final String CONTROL_CODE = "controlcode"; //text
public static final String SENDER_FULL_NAME = "senderfullname"; //text
public static final String FULL_NAME = "fullname"; //text
public static final String THUMBNAIL_URL = "thumbnailurl"; //text
public static final String COMMENT = "comment"; //text
public static final String IS_EDIT = "isedit"; //bool
public static final String LAST_EDIT_TIME = "lastedittime"; //timestamp
public static final String SUBJECT_ID = "subjectid"; //text
public static final String SENDER_ID = "senderid"; //text
public static final String SENDER_THUMBNAIL_URL = "senderthumbnailurl"; //text
public static final String IS_READ = "isread"; //bool
public static final String LINK_HOST = "linkhost"; //text
public static final String LIKES_NO = "likesno"; //big int
public static final String LINK_DESCRIPTION = "linkdescription"; //text
public static final String IS_APPLICATION_POST = "isapplicationpost"; //bool -->
public static final String ENTITY_ID = "entityid"; //text
public static final String PRIVACY = "privacy"; //text
public static final String MULTI_FILE_UPLOAD = "multifileupload"; //bool
public static final String COMMENTS_NO = "commentsno"; //big int
public static final String LINK_TITLE = "linktitle"; //text
}

File diff suppressed because it is too large Load Diff

5
src/main/webapp/WEB-INF/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
/LICENSE.md
/README.md
/changelog.xml
/gcube-app.xml
/CHANGELOG.md

View File

@ -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>

View File

@ -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;
}