Compare commits

...

114 Commits

Author SHA1 Message Date
Francesco Mangiacrapa edd33a5478 Updated README 2024-05-03 10:51:34 +02:00
Francesco Mangiacrapa 44fb5b6360 added `authorization-utils-range` dependency 2024-04-18 11:43:57 +02:00
Francesco Mangiacrapa 5917c08307 updated README 2024-04-17 16:33:12 +02:00
Francesco Mangiacrapa 08592e03e9 updated 2024-04-17 16:19:07 +02:00
Francesco Mangiacrapa 41d37054b6 updated 2024-04-17 16:17:18 +02:00
Francesco Mangiacrapa b567213366 removed unicode character 2024-04-17 16:08:35 +02:00
Francesco Mangiacrapa f28685e9fb updated Concessioni.json test-data 2024-04-17 15:54:19 +02:00
Francesco Mangiacrapa 93576e5b19 updated ItemObserverd. Completed the Notification-Plugin 2024-04-17 15:53:45 +02:00
Francesco Mangiacrapa 6202bb71fe added Notifications_Messages ita version 2024-04-17 15:41:33 +02:00
Francesco Mangiacrapa 8bf15f84c1 updated messages. Added ita version 2024-04-17 15:40:51 +02:00
Francesco Mangiacrapa b93263bab6 renamed to @${user_caller} 2024-04-17 15:26:49 +02:00
Francesco Mangiacrapa cbc63b7e9e updated message 2024-04-17 15:23:56 +02:00
Francesco Mangiacrapa acf307125a renamed JUnit Test class 2024-04-16 17:44:25 +02:00
Francesco Mangiacrapa 0003c9a12c Integrated notifications-plugins config in the Concessioni UCD of
`devVRE`, see #26453
2024-04-16 11:10:55 +02:00
Francesco Mangiacrapa 08cb6eb54e removed some logs 2024-04-16 10:54:16 +02:00
Francesco Mangiacrapa e6fac1f6e1 commented ckan-plugin 2024-04-15 17:48:10 +02:00
Francesco Mangiacrapa 62a4a78d4f improved check events subscribed in the config 2024-04-15 17:46:49 +02:00
Francesco Mangiacrapa 0417e471ac updated toString ItemObserved 2024-04-15 17:01:56 +02:00
Francesco Mangiacrapa a8b931d9ed updated notify to social. Using social client 2.0 2024-04-15 16:39:35 +02:00
Francesco Mangiacrapa 15ad448778 updated test.commons. Updated user to user_caller into Messages 2024-04-15 14:56:50 +02:00
Francesco Mangiacrapa 47670fdac7 renamed StepExecutionRequest to PerformStepRequest 2024-04-15 12:30:49 +02:00
Francesco Mangiacrapa e8346fa8e3 renamed StepExecutionRequest to PerformStepRequest 2024-04-15 12:27:52 +02:00
Francesco Mangiacrapa 40fb99d477 updated imports 2024-04-15 12:16:16 +02:00
Francesco Mangiacrapa 1031fc5a1a updated geoportal-common at [1.1.0-SNAPSHOT,2.0.0-SNAPSHOT) 2024-04-15 11:54:00 +02:00
Francesco Mangiacrapa e39a3e1380 removed StepExecutionInterface 2024-04-15 11:45:06 +02:00
Francesco Mangiacrapa b3d89b7f09 Updated the ItemObserved 2024-04-15 11:32:19 +02:00
Francesco Mangiacrapa 57d4ad2c51 setUseCaseDescriptor in the ItemObserved 2024-04-15 11:28:51 +02:00
Francesco Mangiacrapa cab71df0d2 added message as optional field 2024-04-15 11:26:16 +02:00
Francesco Mangiacrapa 78cd17117c commented setOptionalMessage 2024-04-12 16:04:05 +02:00
Francesco Mangiacrapa ce2aaba503 added debug log 2024-04-12 15:49:29 +02:00
Francesco Mangiacrapa c8785efb0c added interface 2024-04-12 15:37:02 +02:00
Francesco Mangiacrapa 2f6c1d8ad6 updated StepExecutionRequest 2024-04-12 15:33:42 +02:00
Francesco Mangiacrapa 1180fbd8be commented JUnit Tests 2024-04-11 17:21:24 +02:00
Francesco Mangiacrapa 308b016852 added explicit method getMessage() 2024-04-11 17:04:10 +02:00
Francesco Mangiacrapa 18b7b70aaf added more logs 2024-04-11 15:34:40 +02:00
Francesco Mangiacrapa 6205e125d8 toString fixed 2024-04-11 14:38:45 +02:00
Francesco Mangiacrapa a32e90757f updated messages 2024-04-11 11:18:56 +02:00
Francesco Mangiacrapa 732cc92702 Refactored tests 2024-04-11 09:43:09 +02:00
Francesco Mangiacrapa 87570b3e8c removed optionalMessage from performStep interface 2024-04-10 17:53:36 +02:00
Francesco Mangiacrapa 3344c9c024 updated changelog 2024-04-10 16:35:59 +02:00
Francesco Mangiacrapa 2ba9907cd1 added class 2024-04-10 15:21:08 +02:00
Francesco Mangiacrapa 75a964ad09 implemented first version of the notification plugin 2024-04-10 15:20:53 +02:00
Francesco Mangiacrapa 70ec76748e updated the messages 2024-04-10 15:01:11 +02:00
Francesco Mangiacrapa 8c6d7425a5 updated the messages 2024-04-10 14:32:29 +02:00
Francesco Mangiacrapa a3d3470db4 revisited messages 2024-04-10 12:37:32 +02:00
Francesco Mangiacrapa 8f72db0391 added setOptionalMessage and optional Document 2024-04-09 16:10:36 +02:00
Francesco Mangiacrapa 33fcdfef3c updated message 2024-04-09 11:58:21 +02:00
Francesco Mangiacrapa 502d9f0540 added application links as html 2024-04-09 11:27:27 +02:00
Francesco Mangiacrapa 79efab2bd7 added html to application link 2024-04-09 11:06:03 +02:00
Francesco Mangiacrapa 2214f2db27 updated notifications 2024-04-09 11:03:07 +02:00
Francesco Mangiacrapa 22a5a2be49 integrated setOptionalMessage() method 2024-04-09 09:22:49 +02:00
Francesco Mangiacrapa 90e9bc797b - Added optional message when performing lifecycle step [#27192] 2024-04-08 17:34:44 +02:00
Francesco Mangiacrapa cc78007607 updated component version at 1.1.0{-SNAPSHOT} 2024-04-08 17:21:03 +02:00
Francesco Mangiacrapa fdabbe78d8 - Added optional message to performStep method [#27192] 2024-04-08 17:19:37 +02:00
Francesco Mangiacrapa ede76d625b updated notifications management 2024-04-08 12:42:21 +02:00
Francesco Mangiacrapa b502ad0c2d in progress notification plugin 2024-03-26 10:28:21 +01:00
Francesco Mangiacrapa b422fc8b56 updated the messages 2024-03-26 09:21:25 +01:00
Francesco Mangiacrapa 775d623134 updated notifications properties 2024-03-25 15:52:28 +01:00
Francesco Mangiacrapa eb95248699 updated 2024-03-25 12:02:35 +01:00
Francesco Mangiacrapa 5e7ed04ff6 in progress 2024-03-25 12:01:51 +01:00
Francesco Mangiacrapa 876c6d3e91 updated README with LC screenshots 2024-03-25 11:51:49 +01:00
Francesco Mangiacrapa 45164a02da add mapping to CatalogueEvent 2024-03-25 11:16:40 +01:00
Francesco Mangiacrapa 27126d1c9f starting mapping to catalogue 2024-03-22 17:04:33 +01:00
Francesco Mangiacrapa 894748fb53 Updated visibility of phases and steps 2024-03-22 16:54:06 +01:00
Francesco Mangiacrapa d8838a176b in progress 2024-03-22 16:26:40 +01:00
Francesco Mangiacrapa 3913019df3 updated send notification checks 2024-03-22 16:22:22 +01:00
Francesco Mangiacrapa bab16ad14d updated ItemObserved 2024-03-22 15:43:06 +01:00
Francesco Mangiacrapa 32d3f2fbb3 updated the ItemObserved 2024-03-22 15:41:57 +01:00
Francesco Mangiacrapa 122fd7c882 string replace test 2024-03-21 15:54:09 +01:00
Francesco Mangiacrapa 01bad9d30f in progress 2024-03-21 15:53:54 +01:00
Francesco Mangiacrapa 1e50bd74ca ItemObserved updated 2024-03-21 15:53:09 +01:00
Francesco Mangiacrapa c5b031f6c8 pushing notifications message files 2024-03-21 09:33:21 +01:00
Francesco Mangiacrapa c44421fc32 updated placeholders 2024-03-20 17:36:01 +01:00
Francesco Mangiacrapa e08c03cd04 in progress 2024-03-20 17:04:43 +01:00
Francesco Mangiacrapa 6c26aa65cc in progress 2024-03-20 17:03:04 +01:00
Francesco Mangiacrapa 60cb48c098 Updated the README 2024-02-28 16:12:52 +01:00
Francesco Mangiacrapa 43bdff46e1 updated the concessioni model 2024-02-06 16:55:16 +01:00
Francesco Mangiacrapa 0b416cfcda added convertAcceptStringAsNull 2024-02-06 16:54:45 +01:00
Francesco Mangiacrapa a45afc6424 in progress 2024-02-01 16:28:03 +01:00
Francesco Mangiacrapa a0c77b4e68 in progess 2024-02-01 16:00:01 +01:00
Francesco Mangiacrapa a2c3f44dcd in progess on defining the config 2024-02-01 12:22:34 +01:00
Francesco Mangiacrapa 49f7b248fb in progress on defining the configuration 2024-01-31 18:09:38 +01:00
Francesco Mangiacrapa fb5b527a13 added "Catalogue-Binding-Plugin" config 2024-01-19 18:27:25 +01:00
Francesco Mangiacrapa 0d957c35a6 aggiornato UCD, vedi #26456 2024-01-19 18:25:14 +01:00
Francesco Mangiacrapa 6cce1399a3 updated README 2024-01-19 17:39:36 +01:00
Francesco Mangiacrapa 81531c2ab3 updated doAction log 2024-01-19 15:30:13 +01:00
Francesco Mangiacrapa e724da933e updated plugin 2024-01-19 14:36:43 +01:00
Francesco Mangiacrapa bcb4b5d6e0 updated artifactId at 'catalogue-binding-plugins' 2024-01-19 14:13:03 +01:00
Francesco Mangiacrapa cccad98c12 added notification-plugin in the module 2024-01-19 13:06:37 +01:00
Francesco Mangiacrapa b2d48aa780 Added EventListenerPluginInterface 2024-01-19 11:12:57 +01:00
Francesco Mangiacrapa 94bb1b9315 updated logs 2024-01-18 16:57:17 +01:00
Francesco Mangiacrapa 82e8505bdc reviseted the classes 2024-01-18 16:16:12 +01:00
Francesco Mangiacrapa 768cfcd523 refactored package to 'org.gcube.application.cms' 2024-01-18 15:58:35 +01:00
Francesco Mangiacrapa c9bd636ab2 renamed the plugin 2024-01-17 17:57:12 +01:00
Francesco Mangiacrapa ce790387cc fixed compilation error 2024-01-17 17:37:04 +01:00
Francesco Mangiacrapa 0415d41c10 added catalogue-binding-plugin 2024-01-17 17:34:55 +01:00
Francesco Mangiacrapa b5126cb189 created prototype of the plugin and configured it 2024-01-17 17:32:34 +01:00
Francesco Mangiacrapa 413f6516d9 Component refactored. Changed Event Manager 2024-01-17 16:09:48 +01:00
Francesco Mangiacrapa 01db0ae870 added logs to trace notified events 2024-01-16 14:34:46 +01:00
Francesco Mangiacrapa 669a5a913d new enhancements #26320 2024-01-12 14:42:12 +01:00
Francesco Mangiacrapa 79ad6a3476 merged with master, fixed quota_min 2024-01-11 17:10:35 +01:00
Francesco Mangiacrapa 77e4e3dafd fixed quota_min 2024-01-11 17:09:45 +01:00
Francesco Mangiacrapa 9fac05e248 fixed quota_min 2024-01-11 17:08:27 +01:00
Francesco Mangiacrapa 70653b6d5c added regex test 2024-01-10 17:35:15 +01:00
Francesco Mangiacrapa edbb165851 Updated the UCD according to new GNA data model, see #26350 2024-01-10 15:13:06 +01:00
Francesco Mangiacrapa daaef8328f added 'apply_regex' rule, see at #26322#note-2 2024-01-09 12:49:44 +01:00
Francesco Mangiacrapa c8a75ed10b Updated the Concessioni profile according to new data model, see #26350 2024-01-09 12:18:55 +01:00
Francesco Mangiacrapa 1ebb7a3aef updated profiledConcessioni with "apply_regex" config 2023-12-21 16:40:58 +01:00
Francesco Mangiacrapa b1e4f70afb Added apply regex business logic [#26322] 2023-12-21 16:38:49 +01:00
Francesco Mangiacrapa 07d74c68e4 moved plugin-framework-version at 1.0.5-SNAPSHOT 2023-12-21 12:26:03 +01:00
Francesco Mangiacrapa c7968a50b0 Passed to 1.2.0-SNAPSHOT 2023-12-21 12:21:13 +01:00
Francesco Mangiacrapa 6a4babd6ea Integrated EventManager and notifies 2023-12-21 10:49:37 +01:00
Francesco Mangiacrapa a39f8cc8d6 Added EventManager 2023-12-21 10:48:06 +01:00
Francesco Mangiacrapa eee0e50061 created the project 2023-12-21 10:42:56 +01:00
125 changed files with 5616 additions and 1073 deletions

View File

@ -2,6 +2,10 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
# Changelog for org.gcube.spatial.data.gcube-sdi-suite
## [v1.0.6-SNAPSHOT]
- Integrated an EventManager centrally [#26321]
- sdi-plugins: add the logic to apply a regex to the value that must be added to index [#26322]
## [v1.0.5]
- Added maven profiles `geoportal-release-profile` and `geoportal-snapshot-profile` [#25570]
- Moved to maven-parent.v1.2.0 [#25570]

View File

@ -94,7 +94,7 @@
"_description": "Embedded profile for concessioni [mibac] management",
"_creationInfo": {
"_user": {
"_username": "fabio.sinibaldi"
"_username": "francesco.mangiacrapa"
}
},
"_dataAccessPolicies": [
@ -212,21 +212,11 @@
"path": "$._theDocument.descrizioneContenuto",
"type": "TEXT"
},
{
"name": "autore",
"path": "$._theDocument.authors",
"type": "TEXT"
},
{
"name": "contributore",
"path": "$._theDocument.contributore",
"type": "TEXT"
},
{
"name": "titolare",
"path": "$._theDocument.titolari",
"type": "TEXT"
},
{
"name": "responsabile",
"path": "$._theDocument.responsabile",
@ -237,6 +227,16 @@
"path": "$._theDocument.editore",
"type": "TEXT"
},
{
"name": "ufficio_mic_competente",
"path": "$._theDocument.ufficioMic",
"type": "TEXT"
},
{
"name": "funzionario_responsabile",
"path": "$._theDocument.funzionarioResponsabile",
"type": "TEXT"
},
{
"name": "finanziamento",
"path": "$._theDocument.fontiFinanziamento",
@ -272,11 +272,6 @@
"path": "$._info._access._license",
"type": "TEXT"
},
{
"name": "titolare_licenza",
"path": "$._theDocument.titolareLicenza",
"type": "TEXT"
},
{
"name": "accesso",
"path": "$._info._access._license",
@ -286,6 +281,56 @@
"name": "parole_chiave",
"path": "$._theDocument.paroleChiaveLibere",
"type": "TEXT"
},
{
"name": "modalita_individuazione",
"path": "$._theDocument.modalitaIndividuazione",
"type": "TEXT"
},
{
"name": "contesto_indagine",
"path": "$._theDocument.contestoIndagine",
"type": "TEXT"
},
{
"name": "denominazione",
"path": "$._theDocument.denominazione",
"type": "TEXT"
},
{
"name": "stato_attuale",
"path": "$._theDocument.statoAttuale",
"type": "TEXT"
},
{
"name": "accessibilita",
"path": "$._theDocument.accessibilita",
"type": "TEXT"
},
{
"name": "cronologia_macrofase",
"path": "$._theDocument.cronologiaMacrofase",
"type": "TEXT",
"apply_regex": {
"type": "replaceAll",
"regex": "(\\s)?\\([\\s\\S]*",
"replacement": ""
}
},
{
"name": "specifiche_cronologia",
"path": "$._theDocument.specificheCronologia",
"type": "TEXT"
},
{
"name": "quota_max",
"path": "$._theDocument.quotaMax",
"type": "TEXT"
},
{
"name": "quota_min",
"path": "$._theDocument.quotaMin",
"type": "TEXT"
}
],
"jslt": {},
@ -299,6 +344,101 @@
]
}
},
{
"_id": "Notifications-Plugin",
"_type": "EventListener",
"_configuration": {
"subscribeNotifications": [
{
"event": "LIFECYCLE_STEP_PERFORMED",
"notificationFor": [
{
"roles": [
"Data-Manager"
],
"when": [
{
"target_phase": [
"Pending Approval"
],
"last_invoked_step": "SUBMIT-FOR-REVIEW",
"notify": [
{
"type": "USER_NOTIFICATION",
"send": true,
"placeholder_title": "TITLE_REVIEW_REQUIRED",
"placeholder_msg": "MSG_REVIEW_REQUIRED"
}
]
},
{
"target_phase": [
"DRAFT"
],
"last_invoked_step": "REJECT-DRAFT",
"notify": [
{
"type": "USER_NOTIFICATION",
"send": true,
"placeholder_title": "TITLE_ITEM_REJECTED",
"placeholder_msg": "MSG_ITEM_REJECTED"
}
]
}
]
},
{
"roles": [
"Item_Creator"
],
"when": [
{
"target_phase": [
"DRAFT"
],
"last_invoked_step": "REJECT-DRAFT",
"notify": [
{
"type": "USER_NOTIFICATION",
"send": true,
"placeholder_title": "TITLE_ITEM_REJECTED_REVIEW_REQUIRED",
"placeholder_msg": "MSG_ITEM_REJECTED_REVIEW_REQUIRED"
}
]
}
]
},
{
"roles": [
"Any"
],
"when": [
{
"target_phase": [
"Published"
],
"last_invoked_step": "APPROVE-SUBMITTED",
"notify": [
{
"type": "VRE_POST",
"send": true,
"placeholder_msg": "MSG_ITEM_PUBLISHED",
"export_as_pdf": {
"export": true,
"placeholder_msg": "MSG_GO_TO_PDF"
}
}
]
}
]
}
]
}
],
"enabled": true,
"link_to_notifications_messages": "https://code-repo.d4science.org/gCubeSystem/gcube-cms-suite/raw/branch/event_manager/D4S_UCDs/DEV/devVRE/notifications/Notifications_Messages_ita.properties"
}
},
{
"_id": "org.gcube.portlets.user.geoportal-data-entry-app",
"_type": "DATA_ENTRY_GUI",
@ -399,17 +539,16 @@
"_configuration": {
"itemFields": [
{
"label": "Descriptive Fields",
"label": "Any Field",
"paths": [
"_theDocument.nome",
"_theDocument.introduzione",
"_theDocument.authors",
"_theDocument.contributore",
"_theDocument.titolari",
"_theDocument.dataInizioProgetto",
"_theDocument.editore",
"_theDocument.responsabile",
"_theDocument.paroleChiaveLibere",
"_theDocument.cronologiaMacrofase",
"_theDocument.contestoIndagine",
"_theDocument.paroleChiaveICCD"
],
"operator": "$or",
@ -437,16 +576,6 @@
"sortable": false,
"asResult": true
},
{
"label": "Author/s",
"paths": [
"_theDocument.authors"
],
"operator": "$and",
"searchable": false,
"sortable": true,
"asResult": true
},
{
"label": "Project Start (yyyy-mm-dd)",
"paths": [
@ -460,11 +589,9 @@
{
"label": "Director/Staff",
"paths": [
"_theDocument.authors",
"_theDocument.contributore",
"_theDocument.titolari",
"_theDocument.editore",
"_theDocument.responsabile"
"_theDocument.responsabile",
"_theDocument.editore"
],
"operator": "$or",
"searchable": true,
@ -475,6 +602,7 @@
"label": "Keywords",
"paths": [
"_theDocument.paroleChiaveLibere",
"_theDocument.cronologiaMacrofase",
"_theDocument.paroleChiaveICCD"
],
"operator": "$or",
@ -535,12 +663,12 @@
"paths": [
"_theDocument.nome",
"_theDocument.introduzione",
"_theDocument.authors",
"_theDocument.contributore",
"_theDocument.titolari",
"_theDocument.editore",
"_theDocument.responsabile",
"_theDocument.paroleChiaveLibere",
"_theDocument.cronologiaMacrofase",
"_theDocument.contestoIndagine",
"_theDocument.paroleChiaveICCD"
],
"operator": "$or",
@ -591,11 +719,9 @@
{
"label": "Director/Staff",
"paths": [
"_theDocument.authors",
"_theDocument.contributore",
"_theDocument.titolari",
"_theDocument.editore",
"_theDocument.responsabile"
"_theDocument.responsabile",
"_theDocument.editore"
],
"operator": "$or",
"searchable": true,
@ -606,6 +732,7 @@
"label": "Keywords",
"paths": [
"_theDocument.paroleChiaveLibere",
"_theDocument.cronologiaMacrofase",
"_theDocument.paroleChiaveICCD"
],
"operator": "$or",

View File

@ -0,0 +1,23 @@
# REVIEW ACTION
TITLE_REVIEW_REQUIRED=Review required for ${project_name}
MSG_REVIEW_REQUIRED=@${user_caller} submitted the project ${project_name}. You are kindly requested to review it and decide either to APPROVE or REJECT it. See the Project at ${private_data_entry_link}
# REJECTED ACTION
TITLE_ITEM_REJECTED=Rejected ${project_name}
MSG_ITEM_REJECTED=The project ${project_name} (id: ${project_id}) has just been rejected by @${user_caller}. See the Project at ${private_data_entry_link}
# REJECTED ACTION
TITLE_ITEM_REJECTED_REVIEW_REQUIRED=Rejected ${project_name}
MSG_ITEM_REJECTED_REVIEW_REQUIRED=The project ${project_name} has just been rejected. You are kindly requested to review it. See the Project at ${private_data_entry_link}
# PUBLISHED ACTION
TITLE_ITEM_PUBLISHED=Published ${project_name}
MSG_ITEM_PUBLISHED=The project ${project_name} created by @${item_creator} has just been published. See the Project at ${public_data_viewer_link}
# CREATED ACTION
TITLE_ITEM_CREATED=Created ${project_name}
MSG_ITEM_CREATED=The project ${project_name} has just been created. See the Project at ${private_data_entry_link}
# DELETED ACTION
TITLE_ITEM_DELETED=Deleted ${project_name}
MSG_ITEM_DELETED=The project ${project_name} has just been deleted
# UPDATED ACTION
TITLE_ITEM_UPDATED=Updated ${project_name}
MSG_ITEM_UPDATED=The project ${project_name} (id: ${project_id}) has just been updated. See the Project at ${private_data_entry_link}
# GO TO PDF ACTION
MSG_GO_TO_PDF=Go to PDF report at ${project_as_pdf_link}

View File

@ -0,0 +1,23 @@
# REVIEW ACTION
TITLE_REVIEW_REQUIRED=Richiesta di revisione per ${project_name}
MSG_REVIEW_REQUIRED=@${user_caller} ho sottomesso il progetto ${project_name}. Si prega di esaminarlo e decidere se APPROVARLO o RIFIUTARLO. Vedi il progetto ${private_data_entry_link}
# REJECTED ACTION
TITLE_ITEM_REJECTED=Rigettato ${project_name}
MSG_ITEM_REJECTED=Il progetto ${project_name} (id: ${project_id}) è stato rigettato da @${user_caller}. Vedi il progetto ${private_data_entry_link}
# REJECTED ACTION
TITLE_ITEM_REJECTED_REVIEW_REQUIRED=Rigettato ${project_name}
MSG_ITEM_REJECTED_REVIEW_REQUIRED=Il progetto ${project_name} è stato rigettato. Si prega di rivederlo. Vedi il progetto ${private_data_entry_link}
# PUBLISHED ACTION
TITLE_ITEM_PUBLISHED=Pubblicato ${project_name}
MSG_ITEM_PUBLISHED=Il progetto ${project_name} creato da @${item_creator} è stato pubblicato. Vedi il progetto ${public_data_viewer_link}
# CREATED ACTION
TITLE_ITEM_CREATED=Creato ${project_name}
MSG_ITEM_CREATED=Il progetto ${project_name} è stato creato. Vedi il progetto ${private_data_entry_link}
# DELETED ACTION
TITLE_ITEM_DELETED=Cancellato ${project_name}
MSG_ITEM_DELETED=Il progetto ${project_name} è stato cancellato
# UPDATED ACTION
TITLE_ITEM_UPDATED=Aggiornato ${project_name}
MSG_ITEM_UPDATED=Il progetto ${project_name} (id: ${project_id}) è stato aggiornato. Vedi il progetto ${private_data_entry_link}
# GO TO PDF ACTION
MSG_GO_TO_PDF=Vai al report PDF ${project_as_pdf_link}

View File

@ -94,7 +94,7 @@
"_description": "Embedded profile for concessioni [mibac] management",
"_creationInfo": {
"_user": {
"_username": "fabio.sinibaldi"
"_username": "francesco.mangiacrapa"
}
},
"_dataAccessPolicies": [
@ -212,21 +212,11 @@
"path": "$._theDocument.descrizioneContenuto",
"type": "TEXT"
},
{
"name": "autore",
"path": "$._theDocument.authors",
"type": "TEXT"
},
{
"name": "contributore",
"path": "$._theDocument.contributore",
"type": "TEXT"
},
{
"name": "titolare",
"path": "$._theDocument.titolari",
"type": "TEXT"
},
{
"name": "responsabile",
"path": "$._theDocument.responsabile",
@ -237,6 +227,16 @@
"path": "$._theDocument.editore",
"type": "TEXT"
},
{
"name": "ufficio_mic_competente",
"path": "$._theDocument.ufficioMic",
"type": "TEXT"
},
{
"name": "funzionario_responsabile",
"path": "$._theDocument.funzionarioResponsabile",
"type": "TEXT"
},
{
"name": "finanziamento",
"path": "$._theDocument.fontiFinanziamento",
@ -272,11 +272,6 @@
"path": "$._info._access._license",
"type": "TEXT"
},
{
"name": "titolare_licenza",
"path": "$._theDocument.titolareLicenza",
"type": "TEXT"
},
{
"name": "accesso",
"path": "$._info._access._license",
@ -286,6 +281,56 @@
"name": "parole_chiave",
"path": "$._theDocument.paroleChiaveLibere",
"type": "TEXT"
},
{
"name": "modalita_individuazione",
"path": "$._theDocument.modalitaIndividuazione",
"type": "TEXT"
},
{
"name": "contesto_indagine",
"path": "$._theDocument.contestoIndagine",
"type": "TEXT"
},
{
"name": "denominazione",
"path": "$._theDocument.denominazione",
"type": "TEXT"
},
{
"name": "stato_attuale",
"path": "$._theDocument.statoAttuale",
"type": "TEXT"
},
{
"name": "accessibilita",
"path": "$._theDocument.accessibilita",
"type": "TEXT"
},
{
"name": "cronologia_macrofase",
"path": "$._theDocument.cronologiaMacrofase",
"type": "TEXT",
"apply_regex": {
"type": "replaceAll",
"regex": "(\\s)?\\([\\s\\S]*",
"replacement": ""
}
},
{
"name": "specifiche_cronologia",
"path": "$._theDocument.specificheCronologia",
"type": "TEXT"
},
{
"name": "quota_max",
"path": "$._theDocument.quotaMax",
"type": "TEXT"
},
{
"name": "quota_min",
"path": "$._theDocument.quotaMin",
"type": "TEXT"
}
],
"jslt": {},
@ -403,12 +448,12 @@
"paths": [
"_theDocument.nome",
"_theDocument.introduzione",
"_theDocument.authors",
"_theDocument.contributore",
"_theDocument.titolari",
"_theDocument.editore",
"_theDocument.responsabile",
"_theDocument.paroleChiaveLibere",
"_theDocument.cronologiaMacrofase",
"_theDocument.contestoIndagine",
"_theDocument.paroleChiaveICCD"
],
"operator": "$or",
@ -436,16 +481,6 @@
"sortable": false,
"asResult": true
},
{
"label": "Author/s",
"paths": [
"_theDocument.authors"
],
"operator": "$and",
"searchable": false,
"sortable": true,
"asResult": true
},
{
"label": "Project Start (yyyy-mm-dd)",
"paths": [
@ -459,11 +494,9 @@
{
"label": "Director/Staff",
"paths": [
"_theDocument.authors",
"_theDocument.contributore",
"_theDocument.titolari",
"_theDocument.editore",
"_theDocument.responsabile"
"_theDocument.responsabile",
"_theDocument.editore"
],
"operator": "$or",
"searchable": true,
@ -474,6 +507,7 @@
"label": "Keywords",
"paths": [
"_theDocument.paroleChiaveLibere",
"_theDocument.cronologiaMacrofase",
"_theDocument.paroleChiaveICCD"
],
"operator": "$or",
@ -534,12 +568,12 @@
"paths": [
"_theDocument.nome",
"_theDocument.introduzione",
"_theDocument.authors",
"_theDocument.contributore",
"_theDocument.titolari",
"_theDocument.editore",
"_theDocument.responsabile",
"_theDocument.paroleChiaveLibere",
"_theDocument.cronologiaMacrofase",
"_theDocument.contestoIndagine",
"_theDocument.paroleChiaveICCD"
],
"operator": "$or",
@ -590,11 +624,9 @@
{
"label": "Director/Staff",
"paths": [
"_theDocument.authors",
"_theDocument.contributore",
"_theDocument.titolari",
"_theDocument.editore",
"_theDocument.responsabile"
"_theDocument.responsabile",
"_theDocument.editore"
],
"operator": "$or",
"searchable": true,
@ -605,6 +637,7 @@
"label": "Keywords",
"paths": [
"_theDocument.paroleChiaveLibere",
"_theDocument.cronologiaMacrofase",
"_theDocument.paroleChiaveICCD"
],
"operator": "$or",

View File

@ -98,15 +98,43 @@
}
},
"_dataAccessPolicies": [
{"_policy": {"_read": "any","_write": "any"},
"_roles": ["Data-Manager"]},
{"_policy": {"_read": "own","_write": "own"},
"_roles": ["Data-Editor"]},
{"_policy": {"_read": "any","_write": "none"},
"_roles": ["Member"],
"_enforcer": {"_filter": "{\"_lifecycleInformation._phase\" : {\"$eq\" : \"Published\"}}"}},
{"_policy": {"_read": "none","_write": "none"},
"_roles": []}
{
"_policy": {
"_read": "any",
"_write": "any"
},
"_roles": [
"Data-Manager"
]
},
{
"_policy": {
"_read": "own",
"_write": "own"
},
"_roles": [
"Data-Editor"
]
},
{
"_policy": {
"_read": "any",
"_write": "none"
},
"_roles": [
"Member"
],
"_enforcer": {
"_filter": "{\"_lifecycleInformation._phase\" : {\"$eq\" : \"Published\"}}"
}
},
{
"_policy": {
"_read": "none",
"_write": "none"
},
"_roles": []
}
],
"_handlers": [
{
@ -184,21 +212,11 @@
"path": "$._theDocument.descrizioneContenuto",
"type": "TEXT"
},
{
"name": "autore",
"path": "$._theDocument.authors",
"type": "TEXT"
},
{
"name": "contributore",
"path": "$._theDocument.contributore",
"type": "TEXT"
},
{
"name": "titolare",
"path": "$._theDocument.titolari",
"type": "TEXT"
},
{
"name": "responsabile",
"path": "$._theDocument.responsabile",
@ -209,6 +227,16 @@
"path": "$._theDocument.editore",
"type": "TEXT"
},
{
"name": "ufficio_competente",
"path": "$._theDocument.ufficioCompetente",
"type": "TEXT"
},
{
"name": "funzionario_responsabile",
"path": "$._theDocument.funzionarioResponsabile",
"type": "TEXT"
},
{
"name": "finanziamento",
"path": "$._theDocument.fontiFinanziamento",
@ -244,11 +272,6 @@
"path": "$._info._access._license",
"type": "TEXT"
},
{
"name": "titolare_licenza",
"path": "$._theDocument.titolareLicenza",
"type": "TEXT"
},
{
"name": "accesso",
"path": "$._info._access._license",
@ -258,6 +281,56 @@
"name": "parole_chiave",
"path": "$._theDocument.paroleChiaveLibere",
"type": "TEXT"
},
{
"name": "modalita_individuazione",
"path": "$._theDocument.modalitaIndividuazione",
"type": "TEXT"
},
{
"name": "contesto_indagine",
"path": "$._theDocument.contestoIndagine",
"type": "TEXT"
},
{
"name": "denominazione",
"path": "$._theDocument.denominazione",
"type": "TEXT"
},
{
"name": "stato_attuale",
"path": "$._theDocument.statoAttuale",
"type": "TEXT"
},
{
"name": "accessibilita",
"path": "$._theDocument.accessibilita",
"type": "TEXT"
},
{
"name": "cronologia_macrofase",
"path": "$._theDocument.cronologiaMacrofase",
"type": "TEXT",
"apply_regex": {
"type": "replaceAll",
"regex": "(\\s)?\\([\\s\\S]*",
"replacement": ""
}
},
{
"name": "specifiche_cronologia",
"path": "$._theDocument.specificheCronologia",
"type": "TEXT"
},
{
"name": "quota_max",
"path": "$._theDocument.quotaMax",
"type": "TEXT"
},
{
"name": "quota_min",
"path": "$._theDocument.quotaMin",
"type": "TEXT"
}
],
"jslt": {},
@ -271,323 +344,310 @@
]
}
},
{
"_id": "org.gcube.portlets.user.geoportal-data-entry-app",
"_type": "DATA_ENTRY_GUI",
"_configuration": {
"gcubeProfiles": [
{
"gcubeSecondaryType": "GeoNaMetadata",
"gcubeName": "Informazioni_di_progetto",
"sectionName": "$.",
"sectionTitle": "Informazioni di Progetto"
},
{
"gcubeSecondaryType": "GeoNaMetadata",
"gcubeName": "Abstract_Relazione_di_Scavo",
"sectionName": "abstractRelazione",
"sectionTitle": "Abstract della Relazione Scientifica",
"parentName": "$.",
"filePaths": [
{
"gcubeProfileFieldName": "Carica Abstract Ita (in PDF)",
"fieldDefinition": "$.abstractRelazione._children[?(@.filesetIta)]",
"fieldName": "filesetIta"
},
{
"gcubeProfileFieldName": "Carica Abstract Eng (in PDF)",
"fieldDefinition": "$.abstractRelazione._children[?(@.filesetEng)]",
"fieldName": "filesetEng"
}
]
},
{
"gcubeSecondaryType": "GeoNaMetadata",
"gcubeName": "Relazione_di_Scavo",
"sectionName": "relazioneScavo",
"sectionTitle": "Relazione Scientifica",
"parentName": "$.",
"filePaths": [
{
"gcubeProfileFieldName": "Relazione scientifica (in PDF)",
"fieldDefinition": "$.relazioneScavo._children[?(@.fileset)]",
"fieldName": "fileset"
}
]
},
{
"gcubeSecondaryType": "GeoNaMetadata",
"gcubeName": "Immagine_Rappresentativa_di_Scavo",
"sectionName": "immaginiRappresentative",
"sectionTitle": "Immagini Rappresentative",
"minOccurs": 1,
"maxOccurs": 4,
"parentName": "$.",
"filePaths": [
{
"gcubeProfileFieldName": "Immagine",
"fieldDefinition": "$.immaginiRappresentative._children[?(@.fileset)]",
"fieldName": "fileset"
}
]
},
{
"gcubeSecondaryType": "GeoNaMetadata",
"gcubeName": "Posizionamento_dell_area_di_indagine",
"sectionName": "posizionamentoScavo",
"sectionTitle": "Posizionamento dell'Area di Indagine",
"parentName": "$.",
"filePaths": [
{
"gcubeProfileFieldName": "File",
"fieldDefinition": "$.posizionamentoScavo._children[?(@.fileset)]",
"fieldName": "fileset"
}
]
},
{
"gcubeSecondaryType": "GeoNaMetadata",
"gcubeName": "Pianta_di_fine_Scavo",
"sectionName": "pianteFineScavo",
"sectionTitle": "Piante di Fine Indagine",
"parentName": "$.",
"minOccurs": 0,
"maxOccurs": 0,
"filePaths": [
{
"gcubeProfileFieldName": "File",
"fieldDefinition": "$.pianteFineScavo._children[?(@.fileset)]",
"fieldName": "fileset"
}
]
}
],
"saveStep": ""
}
},
{
"_id": "org.gcube.portlets.user.geoportal-data-list",
"_type": "DATA_LIST_GUI",
"_configuration": {
"itemFields": [
{
"label": "Any Field",
"paths": [
"_theDocument.nome",
"_theDocument.introduzione",
"_theDocument.authors",
"_theDocument.contributore",
"_theDocument.titolari",
"_theDocument.editore",
"_theDocument.responsabile",
"_theDocument.paroleChiaveLibere",
"_theDocument.paroleChiaveICCD"
"_id": "org.gcube.portlets.user.geoportal-data-entry-app",
"_type": "DATA_ENTRY_GUI",
"_configuration": {
"gcubeProfiles": [
{
"gcubeSecondaryType": "GeoNaMetadata",
"gcubeName": "Informazioni_di_progetto_estero",
"sectionName": "$.",
"sectionTitle": "Informazioni di Progetto per l'Estero"
},
{
"gcubeSecondaryType": "GeoNaMetadata",
"gcubeName": "Abstract_Relazione_di_Scavo",
"sectionName": "abstractRelazione",
"sectionTitle": "Abstract della Relazione Scientifica",
"parentName": "$.",
"filePaths": [
{
"gcubeProfileFieldName": "Carica Abstract Ita (in PDF)",
"fieldDefinition": "$.abstractRelazione._children[?(@.filesetIta)]",
"fieldName": "filesetIta"
},
{
"gcubeProfileFieldName": "Carica Abstract Eng (in PDF)",
"fieldDefinition": "$.abstractRelazione._children[?(@.filesetEng)]",
"fieldName": "filesetEng"
}
]
},
{
"gcubeSecondaryType": "GeoNaMetadata",
"gcubeName": "Relazione_di_Scavo",
"sectionName": "relazioneScavo",
"sectionTitle": "Relazione Scientifica",
"parentName": "$.",
"filePaths": [
{
"gcubeProfileFieldName": "Relazione scientifica (in PDF)",
"fieldDefinition": "$.relazioneScavo._children[?(@.fileset)]",
"fieldName": "fileset"
}
]
},
{
"gcubeSecondaryType": "GeoNaMetadata",
"gcubeName": "Immagine_Rappresentativa_di_Scavo",
"sectionName": "immaginiRappresentative",
"sectionTitle": "Immagini Rappresentative",
"minOccurs": 1,
"maxOccurs": 4,
"parentName": "$.",
"filePaths": [
{
"gcubeProfileFieldName": "Immagine",
"fieldDefinition": "$.immaginiRappresentative._children[?(@.fileset)]",
"fieldName": "fileset"
}
]
},
{
"gcubeSecondaryType": "GeoNaMetadata",
"gcubeName": "Posizionamento_dell_area_di_indagine",
"sectionName": "posizionamentoScavo",
"sectionTitle": "Posizionamento dell'Area di Indagine",
"parentName": "$.",
"filePaths": [
{
"gcubeProfileFieldName": "File",
"fieldDefinition": "$.posizionamentoScavo._children[?(@.fileset)]",
"fieldName": "fileset"
}
]
},
{
"gcubeSecondaryType": "GeoNaMetadata",
"gcubeName": "Pianta_di_fine_Scavo",
"sectionName": "pianteFineScavo",
"sectionTitle": "Piante di Fine Indagine",
"parentName": "$.",
"minOccurs": 0,
"maxOccurs": 0,
"filePaths": [
{
"gcubeProfileFieldName": "File",
"fieldDefinition": "$.pianteFineScavo._children[?(@.fileset)]",
"fieldName": "fileset"
}
]
}
],
"operator": "$or",
"searchable": true,
"sortable": false,
"asResult": false
},
{
"label": "Name",
"paths": [
"_theDocument.nome"
],
"operator": "$and",
"searchable": true,
"sortable": true,
"asResult": true
},
{
"label": "Introduction",
"paths": [
"_theDocument.introduzione"
],
"operator": "$and",
"searchable": true,
"sortable": false,
"asResult": true
},
{
"label": "Author/s",
"paths": [
"_theDocument.authors"
],
"operator": "$and",
"searchable": false,
"sortable": true,
"asResult": true
},
{
"label": "Project Start (yyyy-mm-dd)",
"paths": [
"_theDocument.dataInizioProgetto"
],
"operator": "$and",
"searchable": true,
"sortable": true,
"asResult": true
},
{
"label": "Director/Staff",
"paths": [
"_theDocument.authors",
"_theDocument.contributore",
"_theDocument.titolari",
"_theDocument.editore",
"_theDocument.responsabile"
],
"operator": "$or",
"searchable": true,
"sortable": false,
"asResult": true
},
{
"label": "Keywords",
"paths": [
"_theDocument.paroleChiaveLibere",
"_theDocument.paroleChiaveICCD"
],
"operator": "$or",
"searchable": true,
"sortable": false,
"asResult": true
},
{
"label": "Creator",
"paths": [
"_info._creationInfo._user._username"
],
"operator": "$or",
"searchable": true,
"sortable": false,
"asResult": false
},
{
"label": "Updated",
"paths": [
"_info._lastEditInfo._instant"
],
"operator": "$or",
"searchable": false,
"sortable": true,
"asResult": false
},
{
"label": "Phase",
"paths": [
"_lifecycleInformation._phase"
],
"operator": "$or",
"searchable": true,
"sortable": true,
"asResult": false
},
{
"label": "Status",
"paths": [
"_lifecycleInformation._lastOperationStatus"
],
"operator": "$or",
"searchable": true,
"sortable": true,
"asResult": false
"saveStep": ""
}
]
}
},
},
{
"_id": "org.gcube.portlets.user.geoportal-basic-data-list",
"_type": "BASIC_DATA_LIST_GUI",
"_configuration": {
"itemFields": [
{
"label": "Any Field",
"paths": [
"_theDocument.nome",
"_theDocument.introduzione",
"_theDocument.authors",
"_theDocument.contributore",
"_theDocument.titolari",
"_theDocument.editore",
"_theDocument.responsabile",
"_theDocument.paroleChiaveLibere",
"_theDocument.paroleChiaveICCD"
],
"operator": "$or",
"searchable": true,
"sortable": false,
"asResult": false
},
{
"label": "Name",
"paths": [
"_theDocument.nome"
],
"operator": "$and",
"searchable": true,
"sortable": true,
"asResult": true
},
{
"label": "Introduction",
"paths": [
"_theDocument.introduzione"
],
"operator": "$and",
"searchable": true,
"sortable": false,
"asResult": true
},
{
"label": "Project Start",
"paths": [
"_theDocument.dataInizioProgetto"
],
"operator": "$and",
"searchable": false,
"sortable": false,
"asResult": true
},
{
"label": "Project Start (YEAR)",
"paths": [
"_theDocument.dataInizioProgetto"
],
"operator": "$and",
"searchable": true,
"sortable": false,
"asResult": false
},
{
"label": "Director/Staff",
"paths": [
"_theDocument.authors",
"_theDocument.contributore",
"_theDocument.titolari",
"_theDocument.editore",
"_theDocument.responsabile"
],
"operator": "$or",
"searchable": true,
"sortable": false,
"asResult": true
},
{
"label": "Keywords",
"paths": [
"_theDocument.paroleChiaveLibere",
"_theDocument.paroleChiaveICCD"
],
"operator": "$or",
"searchable": true,
"sortable": false,
"asResult": true
"_id": "org.gcube.portlets.user.geoportal-data-list",
"_type": "DATA_LIST_GUI",
"_configuration": {
"itemFields": [
{
"label": "Any Field",
"paths": [
"_theDocument.nome",
"_theDocument.introduzione",
"_theDocument.contributore",
"_theDocument.editore",
"_theDocument.responsabile",
"_theDocument.paroleChiaveLibere",
"_theDocument.cronologiaMacrofase",
"_theDocument.contestoIndagine",
"_theDocument.paroleChiaveICCD"
],
"operator": "$or",
"searchable": true,
"sortable": false,
"asResult": false
},
{
"label": "Name",
"paths": [
"_theDocument.nome"
],
"operator": "$and",
"searchable": true,
"sortable": true,
"asResult": true
},
{
"label": "Introduction",
"paths": [
"_theDocument.introduzione"
],
"operator": "$and",
"searchable": true,
"sortable": false,
"asResult": true
},
{
"label": "Project Start (yyyy-mm-dd)",
"paths": [
"_theDocument.dataInizioProgetto"
],
"operator": "$and",
"searchable": true,
"sortable": true,
"asResult": true
},
{
"label": "Director/Staff",
"paths": [
"_theDocument.contributore",
"_theDocument.responsabile",
"_theDocument.editore"
],
"operator": "$or",
"searchable": true,
"sortable": false,
"asResult": true
},
{
"label": "Keywords",
"paths": [
"_theDocument.paroleChiaveLibere",
"_theDocument.cronologiaMacrofase",
"_theDocument.paroleChiaveICCD"
],
"operator": "$or",
"searchable": true,
"sortable": false,
"asResult": true
},
{
"label": "Creator",
"paths": [
"_info._creationInfo._user._username"
],
"operator": "$or",
"searchable": true,
"sortable": false,
"asResult": false
},
{
"label": "Updated",
"paths": [
"_info._lastEditInfo._instant"
],
"operator": "$or",
"searchable": false,
"sortable": true,
"asResult": false
},
{
"label": "Phase",
"paths": [
"_lifecycleInformation._phase"
],
"operator": "$or",
"searchable": true,
"sortable": true,
"asResult": false
},
{
"label": "Status",
"paths": [
"_lifecycleInformation._lastOperationStatus"
],
"operator": "$or",
"searchable": true,
"sortable": true,
"asResult": false
}
]
}
]
}
}
,
},
{
"_id": "org.gcube.portlets.user.geoportal-basic-data-list",
"_type": "BASIC_DATA_LIST_GUI",
"_configuration": {
"itemFields": [
{
"label": "Any Field",
"paths": [
"_theDocument.nome",
"_theDocument.introduzione",
"_theDocument.contributore",
"_theDocument.editore",
"_theDocument.responsabile",
"_theDocument.paroleChiaveLibere",
"_theDocument.cronologiaMacrofase",
"_theDocument.contestoIndagine",
"_theDocument.paroleChiaveICCD"
],
"operator": "$or",
"searchable": true,
"sortable": false,
"asResult": false
},
{
"label": "Name",
"paths": [
"_theDocument.nome"
],
"operator": "$and",
"searchable": true,
"sortable": true,
"asResult": true
},
{
"label": "Introduction",
"paths": [
"_theDocument.introduzione"
],
"operator": "$and",
"searchable": true,
"sortable": false,
"asResult": true
},
{
"label": "Project Start",
"paths": [
"_theDocument.dataInizioProgetto"
],
"operator": "$and",
"searchable": false,
"sortable": false,
"asResult": true
},
{
"label": "Project Start (YEAR)",
"paths": [
"_theDocument.dataInizioProgetto"
],
"operator": "$and",
"searchable": true,
"sortable": false,
"asResult": false
},
{
"label": "Director/Staff",
"paths": [
"_theDocument.contributore",
"_theDocument.responsabile",
"_theDocument.editore"
],
"operator": "$or",
"searchable": true,
"sortable": false,
"asResult": true
},
{
"label": "Keywords",
"paths": [
"_theDocument.paroleChiaveLibere",
"_theDocument.cronologiaMacrofase",
"_theDocument.paroleChiaveICCD"
],
"operator": "$or",
"searchable": true,
"sortable": false,
"asResult": true
}
]
}
},
{
"_id": "org.gcube.portlets.user.geoportal-timeline-json-template",
"_type": "TIMELINE_JSON_TEMPLATE",
@ -660,10 +720,16 @@
}
}
],
"_relationshipDefinitions" : [
{"_id": "precedes", "_label" : "Precede",
"_reverseRelationId" : "follows"},
{"_id": "follows", "_label" : "Segue",
"_reverseRelationId" : "precedes"}
"_relationshipDefinitions": [
{
"_id": "precedes",
"_label": "Precede",
"_reverseRelationId": "follows"
},
{
"_id": "follows",
"_label": "Segue",
"_reverseRelationId": "precedes"
}
]
}
}

View File

@ -83,7 +83,7 @@
"Member"
],
"_enforcer": {
"_filter": "{\"_lifecycleInformation._phase\" : {\"$eq\" : \"PUBLISHED\"}}"
"_filter": "{\"_lifecycleInformation._phase\" : {\"$eq\" : \"Published\"}}"
}
},
{
@ -123,7 +123,7 @@
"registeredFileSetPaths": [
{
"schemaField": "datiAltimetrici",
"documentPath": "datiAltimetrici[*].fileset"
"documentPath": "datiAltimetrici.fileset"
},
{
"schemaField": "planimetria",

View File

@ -3,7 +3,7 @@ gCube CMS Suite
gCube CMS Suite is a distributed full stack application for publication management in a gCube Hybrid e-infrastructure. Check wiki [here](https://sublime-and-sphinx-guide.readthedocs.io)
[<img src="https://gcube.wiki.gcube-system.org/images_gcube/e/e4/Geo_Portale%281%29.png">](https://www.sphinx-doc.org/en/master/)
[<img src="https://gcube.wiki.gcube-system.org/images_gcube/e/e4/Geo_Portale%281%29.png">](https://geoportal.cloud.d4science.org/geoportal-service/docs/index.html)
Rationale :
@ -14,6 +14,9 @@ High modularity of plugins allows for the composition of ad hoc use cases with m
The suite comes with a set of pre-built plugins and GUIs that communities can easily extend and / or reuse.
## General Architecture
[<img src="https://gcube.wiki.gcube-system.org/images_gcube/c/ce/Geoportal_General_Architecture.jpg">](https://geoportal.cloud.d4science.org/geoportal-service/docs/architecture.html)
## Use Case
##### D4GNA: component diagram

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="test" value="true"/>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

1
catalogue-binding-plugin/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target/

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>ckan-plugin</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,8 @@
# Changelog for org.gcube.application.cms.catalogue-binding-plugin
## [v1.0.0-SNAPSHOT] - 2023-12-21
- First release
- This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

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

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

View File

@ -0,0 +1,79 @@
gCube CMS Suite : Catalogue Binding Plugin
--------------------------------------------------
The "Catalogue Binding Plugin" implements the binding from
(the products registered in) the Geoportal system to the D4Science Catalogue system.
## Built with
* [gCube SmartGears] (https://gcube.wiki.gcube-system.org/gcube/SmartGears) - The gCube SmartGears framework
* [OpenJDK](https://openjdk.java.net/) - The JDK used
* [JAX-RS](https://github.com/eclipse-ee4j/jaxrs-api) - Java™ API for RESTful Web Services
* [Jersey](https://jersey.github.io/) - JAX-RS runtime
* [Maven](https://maven.apache.org/) - Dependency Management
## Documentation
[gCube CMS Suite](../) parent module containing references, documentation, guides ad utilities.
The "Catalogue Binding Plugin" requires a handler registered in the UCD so defined:
{
"_id": "Catalogue-Binding-Plugin",
"_type": "EventListener",
"_configuration": {
"subscribeEvents": [
{
"event": "{EVENT_NAME_1}"
},
{
"event": "{EVENT_NAME_2}"
}
]
}
}
where the supported events are:
"PROJECT_CREATED"
"PROJECT_UPDATED"
"PROJECT_DELETED"
"LIFECYCLE_STEP_PERFORMED"
## Change log
See [CHANGELOG.md](CHANGELOG.md).
## Authors
* **Francesco Mangiacrapa** ([ORCID](https://orcid.org/0000-0002-6528-664X)) Computer Scientist at [ISTI-CNR Infrascience Group](http://nemis.isti.cnr.it/groups/infrascience)
## License
This project is licensed under the EUPL V.1.1 License - see the [LICENSE.md](LICENSE.md) file for details.
## About the gCube Framework
This software is part of the [gCubeFramework](https://www.gcube-system.org/ "gCubeFramework"): an
open-source software toolkit used for building and operating Hybrid Data
Infrastructures enabling the dynamic deployment of Virtual Research Environments
by favouring the realisation of reuse oriented policies.
The projects leading to this software have received funding from a series of European Union programmes including:
- the Sixth Framework Programme for Research and Technological Development
- DILIGENT (grant no. 004260).
- the Seventh Framework Programme for research, technological development and demonstration
- D4Science (grant no. 212488);
- D4Science-II (grant no.239019);
- ENVRI (grant no. 283465);
- iMarine(grant no. 283644);
- EUBrazilOpenBio (grant no. 288754).
- the H2020 research and innovation programme
- SoBigData (grant no. 654024);
- PARTHENOS (grant no. 654119);
- EGIEngage (grant no. 654142);
- ENVRIplus (grant no. 654182);
- BlueBRIDGE (grant no. 675680);
- PerformFish (grant no. 727610);
- AGINFRAplus (grant no. 731001);
- DESIRA (grant no. 818194);
- ARIADNEplus (grant no. 823914);
- RISIS2 (grant no. 824091);

View File

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>catalogue-binding-plugins</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>gCube CMS - Catalogue Binding Plugin</name>
<parent>
<groupId>org.gcube.application.cms</groupId>
<artifactId>gcube-cms-suite</artifactId>
<version>[1.0.0, 2.0.0-SNAPSHOT)</version>
</parent>
<properties>
<gitBaseUrl>https://code-repo.d4science.org/gCubeSystem</gitBaseUrl>
</properties>
<scm>
<connection>scm:git:${gitBaseUrl}/gcube-cms-suite</connection>
<developerConnection>scm:git:${gitBaseUrl}/gcube-cms-suite</developerConnection>
<url>${gitBaseUrl}/gcube-cms-suite</url>
</scm>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.gcube.distribution</groupId>
<artifactId>gcube-smartgears-bom</artifactId>
<version>${gcube-smartgears-bom-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.gcube.application.cms</groupId>
<artifactId>cms-plugin-framework</artifactId>
<version>${plugin-framework-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.gcube.application.cms</groupId>
<artifactId>cms-plugin-framework</artifactId>
</dependency>
<dependency>
<groupId>org.gcube.application.cms</groupId>
<artifactId>default-lc-managers</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.gcube.application.cms</groupId>
<artifactId>cms-test-commons</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>make-uberjar</id>
<phase>package</phase>
</execution>
<execution>
<id>make-servicearchive</id>
<phase>package</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,320 @@
package org.gcube.application.cms.cataloguebinding;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.bson.Document;
import org.gcube.application.cms.cataloguebinding.doaction.BindingAction;
import org.gcube.application.cms.implementations.utils.UserUtils;
import org.gcube.application.cms.plugins.EventListenerPluginInterface;
import org.gcube.application.cms.plugins.events.EventListener;
import org.gcube.application.cms.plugins.events.EventManager;
import org.gcube.application.cms.plugins.events.EventManager.Event;
import org.gcube.application.cms.plugins.events.ItemObserved;
import org.gcube.application.cms.plugins.faults.InitializationException;
import org.gcube.application.cms.plugins.faults.InvalidProfileException;
import org.gcube.application.cms.plugins.faults.MaterializationException;
import org.gcube.application.cms.plugins.faults.ShutDownException;
import org.gcube.application.cms.plugins.implementations.AbstractPlugin;
import org.gcube.application.cms.plugins.reports.InitializationReport;
import org.gcube.application.cms.plugins.reports.Report;
import org.gcube.application.cms.plugins.reports.Report.Status;
import org.gcube.application.cms.serialization.Serialization;
import org.gcube.application.geoportal.common.model.document.Project;
import org.gcube.application.geoportal.common.model.plugins.PluginDescriptor;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor;
import com.vdurmont.semver4j.Semver;
import lombok.Data;
import lombok.Synchronized;
import lombok.extern.slf4j.Slf4j;
/**
* The Class CatalogueBindingPlugin.
*
* @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it
*
* Jan 19, 2024
*/
@Slf4j
public class CatalogueBindingPlugin extends AbstractPlugin implements EventListenerPluginInterface {
public static final String SUBSCRIBE_EVENTS_CONFIG = "subscribeEvents";
public static final String PLUGIN_ID = "Catalogue-Binding-Plugin";
public static final String PLUGIN_TYPE = "EventListener";
public static final PluginDescriptor DESCRIPTOR = new PluginDescriptor(PLUGIN_ID, PLUGIN_TYPE);
static {
DESCRIPTOR.setVersion(new Semver("1.0.0"));
DESCRIPTOR.setDescription("Manage the data binding from geoportal to catalogue");
}
/**
* Gets the descriptor.
*
* @return the descriptor
*/
@Override
public PluginDescriptor getDescriptor() {
return DESCRIPTOR;
}
@Data
public class SubscribeEventsConfig {
private String event;
}
/**
* Inits the.
*
* @return the initialization report
* @throws InitializationException the initialization exception
*/
@Override
public InitializationReport init() throws InitializationException {
log.debug("Called init");
InitializationReport report = null;
try {
// Creating all listeners
EventListener<ItemObserved<Project>> listenerCreated = new EventListener<ItemObserved<Project>>() {
@Override
public void updated(ItemObserved<Project> observerd) {
log.info("listenerCreated fired on item: {} " + observerd);
boolean subscribed = checkIfSubscribedEvent(observerd);
if (subscribed) {
doAction(observerd);
}
}
};
EventListener<ItemObserved<Project>> listenerUpdated = new EventListener<ItemObserved<Project>>() {
@Override
public void updated(ItemObserved<Project> observerd) {
log.info("listenerUpdated fired on item: {} " + observerd);
boolean subscribed = checkIfSubscribedEvent(observerd);
if (subscribed) {
doAction(observerd);
}
}
};
EventListener<ItemObserved<Project>> listenerDeleted = new EventListener<ItemObserved<Project>>() {
@Override
public void updated(ItemObserved<Project> observerd) {
log.info("listenerDeleted fired on item: {} " + observerd);
boolean subscribed = checkIfSubscribedEvent(observerd);
if (subscribed) {
doAction(observerd);
}
}
};
EventListener<ItemObserved<Project>> listenerLCStepPerformed = new EventListener<ItemObserved<Project>>() {
@Override
public void updated(ItemObserved<Project> observerd) {
log.info("listenerLCStepPerformed fired on item: {} " + observerd);
boolean subscribed = checkIfSubscribedEvent(observerd);
if (subscribed) {
doAction(observerd);
}
}
};
// Subscribing all events
EventManager eventMngInst = EventManager.getInstance();
eventMngInst.subscribe(Event.PROJECT_CREATED, listenerCreated);
eventMngInst.subscribe(Event.PROJECT_UPDATED, listenerUpdated);
eventMngInst.subscribe(Event.PROJECT_DELETED, listenerDeleted);
eventMngInst.subscribe(Event.LIFECYCLE_STEP_PERFORMED, listenerLCStepPerformed);
report = new InitializationReport(Status.OK, PLUGIN_ID + " init performed");
} catch (Exception e) {
InitializationException exc = new InitializationException("Unable to initialize " + DESCRIPTOR.getId(), e);
log.error("init error: {} ", exc);
throw exc;
}
return report;
}
/**
* Inits the in context.
*
* @return the initialization report
* @throws InitializationException the initialization exception
*/
@Override
@Synchronized
public InitializationReport initInContext() throws InitializationException {
InitializationReport report = new InitializationReport();
try {
String context = UserUtils.getCurrent().getContext();
if (getCatalogueBindingMapPerContext() == null) {
log.info("Initializing in " + context);
catalogueBindingMap.put(context, new EventsSubscribed());
}
report.setStatus(Report.Status.OK);
report.putMessage("Initialized " + DESCRIPTOR.getId() + " in the " + context);
} catch (Exception e) {
InitializationException exc = new InitializationException("Unable to initialize " + DESCRIPTOR.getId(), e);
log.error("initInContext error: {} ", exc);
throw exc;
}
return report;
}
protected Map<String, EventsSubscribed> catalogueBindingMap = null;
/**
* Gets the catalogue binding map per context.
*
* @return the catalogue binding map per context
*/
protected EventsSubscribed getCatalogueBindingMapPerContext() {
String context = UserUtils.getCurrent().getContext();
log.debug("Getting {} from cache map for context {}", CatalogueBindingPlugin.PLUGIN_ID, context);
if (catalogueBindingMap == null)
catalogueBindingMap = new LinkedHashMap<String, EventsSubscribed>();
return catalogueBindingMap.get(context);
}
/**
* Read events subscribed from configuration in the UCD.
*
* @param useCaseDescriptor the use case descriptor
* @return the events subscribed
* @throws Exception the exception
*/
public EventsSubscribed readEventsSubscribedFromConfigurationInTheUCD(UseCaseDescriptor useCaseDescriptor)
throws Exception {
log.debug("Reading subscribed events from UCD");
EventsSubscribed eventsSubscrInTheUCD = new EventsSubscribed();
if (useCaseDescriptor == null)
throw new Exception("Error reading UCD null found");
try {
String context = UserUtils.getCurrent().getContext();
eventsSubscrInTheUCD = getCatalogueBindingMapPerContext();
List<Event> listEventsSubscribedPerUCD = new ArrayList<EventManager.Event>();
if (eventsSubscrInTheUCD == null || listEventsSubscribedPerUCD.isEmpty()) {
Document profileConfiguration = getConfigurationFromProfile(useCaseDescriptor).getConfiguration();
log.debug("UseCaseDescriptor Configuration is {} ", profileConfiguration);
// JSONPathWrapper schemaNavigator = new
// JSONPathWrapper(useCaseDescriptor.getSchema().toJson());
for (Object fsConfigObj : profileConfiguration.get(SUBSCRIBE_EVENTS_CONFIG, List.class)) {
log.debug("Managing {} ", fsConfigObj);
SubscribeEventsConfig fsConfig = Serialization.convert(fsConfigObj, SubscribeEventsConfig.class);
log.debug("Converted config {}", fsConfig);
String theEventSubsribed = fsConfig.getEvent();
if (theEventSubsribed == null || theEventSubsribed.isEmpty())
throw new MaterializationException(
"Invalid Field Definition path in configuration [NO MATCH] : " + fsConfig.getEvent());
Event event = Serialization.convert(theEventSubsribed, Event.class);
log.debug("Added event {} to list ", event);
listEventsSubscribedPerUCD.add(event);
}
eventsSubscrInTheUCD = new EventsSubscribed();
eventsSubscrInTheUCD.setContext(context);
eventsSubscrInTheUCD.setListEventSubscribed(listEventsSubscribedPerUCD);
catalogueBindingMap.put(context, eventsSubscrInTheUCD);
log.info("Events subscribed read from config {} ", eventsSubscrInTheUCD);
}
} catch (InvalidProfileException e) {
log.warn("Unable to read configuration for {} in the UCD {}", CatalogueBindingPlugin.PLUGIN_ID,
useCaseDescriptor.getId());
} catch (Exception e) {
log.error("Unable to read configuration ", e);
} catch (Throwable t) {
log.error("Exception, Unable to read configuration ", t);
}
return eventsSubscrInTheUCD;
}
/**
* Check if subscribed event.
*
* @param observerd the observerd
* @return true, if successful
*/
public boolean checkIfSubscribedEvent(ItemObserved<Project> observerd) {
log.info("Checking if {} is an subscribed event", observerd.getEvent());
try {
EventsSubscribed eventsSub = readEventsSubscribedFromConfigurationInTheUCD(
observerd.getUseCaseDescriptor());
List<Event> listEvents = eventsSub.getListEventSubscribed();
log.info("List events is {}", listEvents);
if(listEvents==null) {
log.info("no event subscribed, returing false");
return false;
}
if (listEvents.contains(observerd.getEvent())) {
log.info("the event {} is subscribed from config ", observerd.getEvent());
return true;
}
log.info("the event {} is not subscribed from config ", observerd.getEvent());
return false;
} catch (Exception e) {
log.error("Exception, Error on checking subscribed events", e);
return false;
}
}
/**
* Shutdown.
*
* @throws ShutDownException the shut down exception
*/
@Override
public void shutdown() throws ShutDownException {
// TODO Auto-generated method stub
}
/**
* Do action.
*
* @param observerd the observerd
*/
@Override
public void doAction(ItemObserved<Project> observerd) {
new BindingAction().doAction(observerd);
}
}

View File

@ -0,0 +1,13 @@
package org.gcube.application.cms.cataloguebinding;
import java.util.List;
import org.gcube.application.cms.plugins.events.EventManager.Event;
import lombok.Data;
@Data
public class EventsSubscribed {
String context;
List<Event> listEventSubscribed;
}

View File

@ -0,0 +1,32 @@
package org.gcube.application.cms.cataloguebinding.doaction;
import org.gcube.application.cms.plugins.events.ItemObserved;
import org.gcube.application.geoportal.common.model.document.Project;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class BindingAction {
public void doAction(ItemObserved<Project> itemObserved) {
log.info("Do action called on: {}", itemObserved.getEvent());
switch (itemObserved.getEvent()) {
case PROJECT_CREATED:
break;
case PROJECT_DELETED:
break;
case PROJECT_UPDATED:
break;
case LIFECYCLE_STEP_PERFORMED:
break;
default:
break;
}
}
}

View File

@ -0,0 +1,60 @@
import org.gcube.application.cms.cataloguebinding.CatalogueBindingPlugin;
import org.gcube.application.cms.cataloguebinding.EventsSubscribed;
import org.gcube.application.cms.plugins.faults.InitializationException;
import org.gcube.application.cms.tests.TestProfiles;
import org.gcube.application.cms.tests.plugins.BasicPluginTest;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor;
import org.gcube.application.geoportal.common.utils.tests.GCubeTest;
import org.junit.Test;
public class CatalogueBindingPluginTest extends BasicPluginTest {
//@Test
public void checkPlugin() {
org.junit.Assume.assumeTrue(GCubeTest.isTestInfrastructureEnabled());
CatalogueBindingPlugin plugin = (CatalogueBindingPlugin) plugins.get(CatalogueBindingPlugin.DESCRIPTOR.getId());
try {
plugin.init();
} catch (InitializationException e1) {
e1.printStackTrace();
}
try {
plugin.initInContext();
} catch (InitializationException e1) {
e1.printStackTrace();
}
System.out.println("Plugin check: " + plugin);
}
@Test
public void checkPluginConfig() {
org.junit.Assume.assumeTrue(GCubeTest.isTestInfrastructureEnabled());
CatalogueBindingPlugin plugin = (CatalogueBindingPlugin) plugins.get(CatalogueBindingPlugin.DESCRIPTOR.getId());
UseCaseDescriptor descriptor = TestProfiles.profiles.get("profiledConcessioni");
try {
plugin.init();
} catch (InitializationException e1) {
e1.printStackTrace();
}
try {
plugin.initInContext();
} catch (InitializationException e1) {
e1.printStackTrace();
}
EventsSubscribed events;
try {
events = plugin.readEventsSubscribedFromConfigurationInTheUCD(descriptor);
System.out.println("Events: " + events);
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1 @@
/tokens.properties

View File

@ -1,5 +1,8 @@
# Changelog for org.gcube.application.cms-plugin-framework
## [v1.0.5-SNAPSHOT] - 2023-12-21
- Added Event Manager
## [v1.0.4] - 2023-09-06
- Using parent range version [#25572]

View File

@ -6,6 +6,9 @@ Basic and abstract implementations are provided in different module default-lc-m
Basic providers (e.g. WSProvider, ISProvider) used both in test and by the service are implemented here for simplicity.
Morover, this module provides an `EventManager` to notify the events {`PROJECT_CREATED`, `PROJECT_UPDATED`, `PROJECT_DELETED` `LIFECYCLE_STEP_PERFORMED`}
to the plugins that subscribe to them.
## Built with
* [gCube SDI] (https://gcube.wiki.gcube-system.org/gcube/) - The gCube SDI
* [gCube SmartGears] (https://gcube.wiki.gcube-system.org/gcube/SmartGears) - The gCube SmartGears framework

View File

@ -4,7 +4,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>cms-plugin-framework</artifactId>
<version>1.0.4</version>
<version>1.0.5-SNAPSHOT</version>
<parent>
<groupId>org.gcube.application.cms</groupId>
@ -70,7 +70,7 @@
<dependency>
<groupId>org.gcube.common</groupId>
<artifactId>authorization-utils</artifactId>
<version>[2.0.0, 3.0.0-SNAPSHOT)</version>
<version>${authorization-utils-range}</version>
</dependency>
<dependency>

View File

@ -1,10 +1,10 @@
package org.gcube.application.cms.caches;
import org.gcube.application.cms.implementations.utils.UserUtils;
import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.gcube.application.cms.implementations.utils.UserUtils;
import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
import org.gcube.application.geoportal.common.utils.ContextUtils;
@Slf4j
/**

View File

@ -1,11 +1,11 @@
package org.gcube.application.cms.caches;
import java.time.LocalDateTime;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;
import java.time.LocalDateTime;
@Getter
@ToString
@AllArgsConstructor

View File

@ -1,15 +1,16 @@
package org.gcube.application.cms.caches;
import java.time.LocalDateTime;
import java.time.temporal.TemporalAmount;
import java.util.concurrent.ConcurrentHashMap;
import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
import lombok.Getter;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
import java.time.LocalDateTime;
import java.time.temporal.TemporalAmount;
import java.util.concurrent.ConcurrentHashMap;
@Slf4j
@RequiredArgsConstructor

View File

@ -1,5 +1,7 @@
package org.gcube.application.cms.implementations;
import java.util.List;
import org.gcube.application.cms.caches.Engine;
import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
import org.gcube.application.geoportal.common.model.rest.DatabaseConnection;
@ -7,8 +9,6 @@ import org.gcube.application.geoportal.common.utils.ISUtils;
import org.gcube.common.resources.gcore.GenericResource;
import org.gcube.common.resources.gcore.ServiceEndpoint;
import java.util.List;
public class DefaultISProvider implements ISInterface, Engine<ISInterface> {

View File

@ -1,12 +1,12 @@
package org.gcube.application.cms.implementations;
import java.util.List;
import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
import org.gcube.application.geoportal.common.model.rest.DatabaseConnection;
import org.gcube.common.resources.gcore.GenericResource;
import org.gcube.common.resources.gcore.ServiceEndpoint;
import java.util.List;
public interface ISInterface {
public DatabaseConnection queryForDatabase(String category, String platform,String flagName, String flagValue) throws ConfigurationException;

View File

@ -1,17 +1,18 @@
package org.gcube.application.cms.implementations;
import lombok.Synchronized;
import lombok.extern.slf4j.Slf4j;
import org.gcube.application.cms.caches.Engine;
import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
import org.gcube.common.storagehub.client.dsl.StorageHubClient;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.gcube.application.cms.caches.Engine;
import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
import org.gcube.common.storagehub.client.dsl.StorageHubClient;
import lombok.Synchronized;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class ImplementationProvider {

View File

@ -1,5 +1,7 @@
package org.gcube.application.cms.implementations;
import java.util.List;
import org.bson.Document;
import org.gcube.application.cms.implementations.faults.InvalidUserRoleException;
import org.gcube.application.cms.implementations.faults.ProjectNotFoundException;
@ -10,8 +12,6 @@ import org.gcube.application.geoportal.common.model.document.relationships.Relat
import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
import org.gcube.application.geoportal.common.model.rest.QueryRequest;
import java.util.List;
public interface ProjectAccess {

View File

@ -1,7 +1,7 @@
package org.gcube.application.cms.implementations;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import java.io.InputStream;
import org.gcube.application.geoportal.common.model.configuration.Archive;
import org.gcube.application.geoportal.common.model.document.filesets.RegisteredFile;
import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
@ -11,7 +11,13 @@ import org.gcube.common.storagehub.client.dsl.FolderContainer;
import org.gcube.common.storagehub.client.dsl.StorageHubClient;
import org.gcube.common.storagehub.model.exceptions.StorageHubException;
import java.io.InputStream;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.Synchronized;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class WorkspaceManager {

View File

@ -1,8 +1,11 @@
package org.gcube.application.cms.implementations.utils;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.gcube.application.geoportal.common.model.document.accounting.AccountingInfo;
import org.gcube.application.geoportal.common.model.document.accounting.Context;
import org.gcube.application.geoportal.common.model.document.accounting.User;
@ -11,11 +14,9 @@ import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
import org.gcube.common.authorization.utils.manager.SecretManager;
import org.gcube.common.authorization.utils.manager.SecretManagerProvider;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class UserUtils {

View File

@ -0,0 +1,10 @@
package org.gcube.application.cms.plugins;
import org.gcube.application.cms.plugins.events.ItemObserved;
import org.gcube.application.geoportal.common.model.document.Project;
public interface EventListenerPluginInterface extends InitializablePlugin {
public void doAction(ItemObserved<Project> itemObserved);
}

View File

@ -1,6 +1,10 @@
package org.gcube.application.cms.plugins;
import org.gcube.application.cms.plugins.faults.*;
import org.gcube.application.cms.plugins.faults.EventException;
import org.gcube.application.cms.plugins.faults.InsufficientPrivileges;
import org.gcube.application.cms.plugins.faults.InvalidPluginRequestException;
import org.gcube.application.cms.plugins.faults.InvalidProfileException;
import org.gcube.application.cms.plugins.faults.StepException;
import org.gcube.application.cms.plugins.reports.EventExecutionReport;
import org.gcube.application.cms.plugins.reports.StepExecutionReport;
import org.gcube.application.cms.plugins.requests.BaseRequest;

View File

@ -1,9 +1,9 @@
package org.gcube.application.cms.plugins;
import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
import java.util.Map;
import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
public interface PluginManagerInterface {
public Plugin getById(String pluginID) throws ConfigurationException;

View File

@ -1,14 +1,15 @@
package org.gcube.application.cms.plugins;
import lombok.extern.slf4j.Slf4j;
import org.reflections.Reflections;
import org.reflections.util.ConfigurationBuilder;
import org.reflections.util.FilterBuilder;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import org.reflections.Reflections;
import org.reflections.util.ConfigurationBuilder;
import org.reflections.util.FilterBuilder;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class PluginsReflections {
@ -25,7 +26,7 @@ public class PluginsReflections {
.filterInputsBy(new FilterBuilder().includePackage("org.gcube.application.cms")));
reflections.getSubTypesOf(Plugin.class).iterator().forEachRemaining(pluginClass->{
log.trace("Evaluating class {}",pluginClass);
log.debug("Evaluating class {}",pluginClass);
if(!pluginClass.isInterface() && !Modifier.isAbstract(pluginClass.getModifiers())){
try {
log.debug("Found implementation {} ",pluginClass);

View File

@ -0,0 +1,7 @@
package org.gcube.application.cms.plugins.events;
public interface EventListener<T extends ItemObservable> {
public void updated(T observerd);
}

View File

@ -0,0 +1,132 @@
package org.gcube.application.cms.plugins.events;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.gcube.application.geoportal.common.model.document.Project;
/**
* The Class EventManager.
*
* @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it
*
* Dec 11, 2023
*/
public class EventManager implements EventManagerInterface<ItemObserved<Project>> {
private HashMap<Event, List<EventListener<ItemObserved<Project>>>> listeners = new HashMap<Event, List<EventListener<ItemObserved<Project>>>>();
/**
* The Class Event.
*
* @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it
*
* Nov 29, 2023
*/
public static enum Event {
PROJECT_CREATED("PROJECT_CREATED"),
PROJECT_UPDATED("PROJECT_UPDATED"),
PROJECT_DELETED("PROJECT_DELETED"),
LIFECYCLE_STEP_PERFORMED("LIFECYCLE_STEP_PERFORMED");
String name;
/**
* Instantiates a new event.
*
* @param name the name
*/
Event(String name) {
this.name = name;
}
/**
* Gets the name.
*
* @return the name
*/
public String getName() {
return name;
}
}
// private instance, so that it can be
// accessed by only by getInstance() method
private static EventManager instance;
/**
* Instantiates a new event manager.
*/
private EventManager() {
// private constructor
}
/**
* Gets the single instance of EventManager.
*
* @return single instance of EventManager
*/
public static EventManager getInstance() {
if (instance == null) {
// synchronized block to remove overhead
synchronized (EventManager.class) {
if (instance == null) {
// if instance is null, initialize
instance = new EventManager();
}
}
}
return instance;
}
/**
* Subscribe.
*
* @param eventType the event type
* @param listener the listener
*/
public void subscribe(Event eventType, EventListener<ItemObserved<Project>> listener) {
List<EventListener<ItemObserved<Project>>> list = listeners.get(eventType);
if (list == null)
list = new ArrayList<EventListener<ItemObserved<Project>>>();
list.add(listener);
listeners.put(eventType, list);
}
/**
* Unsubscribe.
*
* @param eventType the event type
* @param listener the listener
*/
public void unsubscribe(Event eventType, EventListener<ItemObserved<Project>> listener) {
List<EventListener<ItemObserved<Project>>> list = listeners.get(eventType);
if (list == null)
return;
list.remove(listener);
listeners.put(eventType, list);
}
/**
* Notify.
*
* @param eventType the event type
* @param item the item
*/
public void notify(Event eventType, ItemObserved<Project> item) {
for (EventManager.Event event : listeners.keySet()) {
if (event.equals(eventType)) {
for (EventListener<ItemObserved<Project>> eventListner : listeners.get(eventType)) {
eventListner.updated(item);
}
}
}
}
}

View File

@ -0,0 +1,13 @@
package org.gcube.application.cms.plugins.events;
import org.gcube.application.cms.plugins.events.EventManager.Event;
public interface EventManagerInterface<T extends ItemObservable> {
public void subscribe(Event eventType, EventListener<T> listener);
public void unsubscribe(Event eventType, EventListener<T> listener);
public void notify(Event eventType, T item);
}

View File

@ -0,0 +1,9 @@
package org.gcube.application.cms.plugins.events;
public interface ItemObservable {
public String getProjectId();
public String getUCD_Id();
}

View File

@ -0,0 +1,110 @@
package org.gcube.application.cms.plugins.events;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map.Entry;
import org.bson.Document;
import org.gcube.application.geoportal.common.model.document.Project;
import org.gcube.application.geoportal.common.model.document.accounting.Context;
import org.gcube.application.geoportal.common.model.document.accounting.User;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Slf4j
public class ItemObserved<T extends Project> implements ItemObservable {
private User userCaller;
private Context context;
private UseCaseDescriptor useCaseDescriptor;
private T project;
private EventManager.Event event;
private Document optional;
public static enum OPTIONAL_FIELD {
message, preview_url
}
public String getProjectId() {
log.debug("Called getProjectId");
if (project == null)
return null;
return project.getId();
}
@Override
public String getUCD_Id() {
log.debug("Called getUCD_Id");
if (useCaseDescriptor == null)
return null;
return useCaseDescriptor.getId();
}
public LinkedHashMap<String, Object> getDocumentEntries(int limit) {
LinkedHashMap<String, Object> documentAsMap = new LinkedHashMap<>();
try {
Iterator<Entry<String, Object>> entrySetsIt = project.getTheDocument().entrySet().iterator();
int i = 0;
while (entrySetsIt.hasNext()) {
if (i + 1 > limit)
break;
Entry<String, Object> entry = entrySetsIt.next();
documentAsMap.put(entry.getKey(), entry.getValue() != null ? entry.getValue().toString() : null);
i++;
}
} catch (Exception e) {
throw e;
}
return documentAsMap;
}
public void setOptional(OPTIONAL_FIELD optionalField, String value) {
this.optional = new Document();
if (optional == null)
this.optional = new Document();
this.optional.put(optionalField.name(), value);
}
public String getOptionalValue(OPTIONAL_FIELD optionalField) {
if (this.optional != null) {
return this.optional.getString(optionalField.name());
}
return null;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("ItemObserved [userCaller=");
builder.append(userCaller);
builder.append(", context=");
builder.append(context);
builder.append(", useCaseDescriptor id=");
builder.append(useCaseDescriptor != null ? useCaseDescriptor.getId() : null);
builder.append(", project id=");
builder.append(project != null ? project.getId() : null);
builder.append(", event=");
builder.append(event);
builder.append(", optional=");
builder.append(optional);
builder.append("]");
return builder.toString();
}
}

View File

@ -1,5 +1,15 @@
package org.gcube.application.cms.plugins.model;
import java.math.BigInteger;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Deque;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -18,11 +28,11 @@ package org.gcube.application.cms.plugins.model;
* specific language governing permissions and limitations
* under the License.
*/
import lombok.*;
import java.math.BigInteger;
import java.util.*;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
/**
* <p>

View File

@ -1,9 +1,8 @@
package org.gcube.application.cms.plugins.reports;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.Data;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.List;
import org.bson.Document;
import org.gcube.application.cms.plugins.faults.InvalidPluginRequestException;
import org.gcube.application.cms.plugins.faults.PluginExecutionException;
@ -12,8 +11,11 @@ import org.gcube.application.geoportal.common.model.document.Project;
import org.gcube.application.geoportal.common.model.document.identification.IdentificationReference;
import org.gcube.application.geoportal.common.model.document.lifecycle.LifecycleInformation;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.Data;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
@Data

View File

@ -1,11 +1,12 @@
package org.gcube.application.cms.plugins.reports;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import org.gcube.application.cms.plugins.faults.InvalidPluginRequestException;
import org.gcube.application.cms.plugins.requests.EventExecutionRequest;
import org.gcube.application.geoportal.common.model.document.lifecycle.LifecycleInformation;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
@ToString(callSuper = true)
@Slf4j
public class EventExecutionReport extends DocumentHandlingReport<EventExecutionRequest>{

View File

@ -1,10 +1,11 @@
package org.gcube.application.cms.plugins.reports;
import org.gcube.application.cms.plugins.faults.InvalidPluginRequestException;
import org.gcube.application.cms.plugins.requests.IndexDocumentRequest;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
import org.gcube.application.cms.plugins.faults.InvalidPluginRequestException;
import org.gcube.application.cms.plugins.requests.IndexDocumentRequest;
@Getter
@Setter

View File

@ -1,9 +1,10 @@
package org.gcube.application.cms.plugins.reports;
import lombok.NonNull;
import org.gcube.application.cms.plugins.faults.InvalidPluginRequestException;
import org.gcube.application.cms.plugins.requests.MaterializationRequest;
import lombok.NonNull;
public class MaterializationReport extends DocumentHandlingReport<MaterializationRequest>{

View File

@ -1,12 +1,13 @@
package org.gcube.application.cms.plugins.reports;
import java.util.ArrayList;
import java.util.List;
import org.gcube.application.cms.plugins.faults.PluginExecutionException;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.gcube.application.cms.plugins.faults.PluginExecutionException;
import java.util.ArrayList;
import java.util.List;
@Getter
@Setter

View File

@ -1,18 +1,20 @@
package org.gcube.application.cms.plugins.reports;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
import lombok.ToString;
import java.util.ArrayList;
import java.util.List;
import org.gcube.application.cms.plugins.faults.InvalidPluginRequestException;
import org.gcube.application.cms.plugins.faults.PluginExecutionException;
import org.gcube.application.cms.plugins.requests.EventExecutionRequest;
import org.gcube.application.cms.plugins.requests.StepExecutionRequest;
import org.gcube.application.geoportal.common.model.document.Project;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter

View File

@ -1,15 +1,16 @@
package org.gcube.application.cms.plugins.requests;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
import lombok.ToString;
import org.gcube.application.cms.plugins.faults.InvalidPluginRequestException;
import org.gcube.application.geoportal.common.model.document.Project;
import org.gcube.application.geoportal.common.model.document.accounting.Context;
import org.gcube.application.geoportal.common.model.document.accounting.User;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString(callSuper = true)

View File

@ -1,6 +1,5 @@
package org.gcube.application.cms.plugins.requests;
import lombok.*;
import org.bson.Document;
import org.gcube.application.cms.plugins.faults.InvalidPluginRequestException;
import org.gcube.application.cms.serialization.Serialization;
@ -8,6 +7,12 @@ import org.gcube.application.geoportal.common.model.document.accounting.Context;
import org.gcube.application.geoportal.common.model.document.accounting.User;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor;
import lombok.Getter;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString(callSuper = true)

View File

@ -1,13 +1,14 @@
package org.gcube.application.cms.plugins.requests;
import org.gcube.application.geoportal.common.model.document.Project;
import org.gcube.application.geoportal.common.model.document.accounting.Context;
import org.gcube.application.geoportal.common.model.document.accounting.User;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
import lombok.ToString;
import org.gcube.application.geoportal.common.model.document.Project;
import org.gcube.application.geoportal.common.model.document.accounting.Context;
import org.gcube.application.geoportal.common.model.document.accounting.User;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor;
@Getter
@Setter

View File

@ -1,12 +1,13 @@
package org.gcube.application.cms.plugins.requests;
import lombok.NonNull;
import lombok.ToString;
import org.gcube.application.geoportal.common.model.document.Project;
import org.gcube.application.geoportal.common.model.document.accounting.Context;
import org.gcube.application.geoportal.common.model.document.accounting.User;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor;
import lombok.NonNull;
import lombok.ToString;
@ToString(callSuper = true)
public class IndexDocumentRequest extends BaseExecutionRequest{
public IndexDocumentRequest(@NonNull UseCaseDescriptor useCaseDescriptor, @NonNull User caller, @NonNull Context context, Project document) {

View File

@ -1,12 +1,13 @@
package org.gcube.application.cms.plugins.requests;
import lombok.NonNull;
import lombok.ToString;
import org.gcube.application.geoportal.common.model.document.Project;
import org.gcube.application.geoportal.common.model.document.accounting.Context;
import org.gcube.application.geoportal.common.model.document.accounting.User;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor;
import lombok.NonNull;
import lombok.ToString;
@ToString(callSuper = true)
public class MaterializationRequest extends BaseExecutionRequest{
public MaterializationRequest(@NonNull UseCaseDescriptor useCaseDescriptor, @NonNull User caller, @NonNull Context context, Project document) {

View File

@ -1,13 +1,14 @@
package org.gcube.application.cms.plugins.requests;
import org.gcube.application.geoportal.common.model.document.Project;
import org.gcube.application.geoportal.common.model.document.accounting.Context;
import org.gcube.application.geoportal.common.model.document.accounting.User;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
import lombok.ToString;
import org.gcube.application.geoportal.common.model.document.Project;
import org.gcube.application.geoportal.common.model.document.accounting.Context;
import org.gcube.application.geoportal.common.model.document.accounting.User;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor;
@Getter
@Setter

View File

@ -1,15 +1,16 @@
package org.gcube.application.cms.serialization;
import java.util.EnumSet;
import java.util.Set;
import org.gcube.application.geoportal.common.JSONSerializationProvider;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.Option;
import com.jayway.jsonpath.spi.json.JacksonJsonProvider;
import com.jayway.jsonpath.spi.json.JsonProvider;
import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider;
import com.jayway.jsonpath.spi.mapper.MappingProvider;
import org.gcube.application.geoportal.common.JSONSerializationProvider;
import java.util.EnumSet;
import java.util.Set;
public class JacksonProvider implements JSONSerializationProvider {

View File

@ -1,22 +1,30 @@
package org.gcube.application.cms.serialization;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.vdurmont.semver4j.Semver;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.time.format.DateTimeFormatter;
import java.util.Iterator;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.gcube.application.cms.plugins.model.ComparableVersion;
import org.gcube.application.geoportal.common.model.document.Project;
import org.gcube.application.geoportal.common.model.rest.QueryRequest;
import java.io.IOException;
import java.time.format.DateTimeFormatter;
import java.util.Iterator;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.vdurmont.semver4j.Semver;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class Serialization {
@ -79,6 +87,13 @@ public class Serialization {
public static final <T> T convert(Object d,Class<T> clazz){
return mapper.convertValue(d,clazz);
}
public static final <T> T convertAcceptStringAsNull(Object d,Class<T> clazz){
mapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT,true);
T converted = mapper.convertValue(d,clazz);
mapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT,false);
return converted;
}
public static final Document asDocument(Object obj) throws JsonProcessingException {
return Document.parse(mapper.writeValueAsString(obj));

View File

@ -1,144 +1,144 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>cms-test-commons</artifactId>
<version>1.0.4</version>
<name>CMS Test Commons</name>
<modelVersion>4.0.0</modelVersion>
<artifactId>cms-test-commons</artifactId>
<version>1.0.4</version>
<name>CMS Test Commons</name>
<parent>
<groupId>org.gcube.application.cms</groupId>
<artifactId>gcube-cms-suite</artifactId>
<version>1.0.4</version>
</parent>
<parent>
<groupId>org.gcube.application.cms</groupId>
<artifactId>gcube-cms-suite</artifactId>
<version>[1.0.0, 2.0.0-SNAPSHOT)</version>
</parent>
<properties>
<gitBaseUrl>https://code-repo.d4science.org/gCubeSystem</gitBaseUrl>
<sis.version>1.0</sis.version>
</properties>
<properties>
<gitBaseUrl>https://code-repo.d4science.org/gCubeSystem</gitBaseUrl>
<sis.version>1.0</sis.version>
</properties>
<scm>
<connection>scm:git:${gitBaseUrl}/gcube-cms-suite</connection>
<developerConnection>scm:git:${gitBaseUrl}/gcube-cms-suite</developerConnection>
<url>${gitBaseUrl}/gcube-cms-suite</url>
</scm>
<scm>
<connection>scm:git:${gitBaseUrl}/gcube-cms-suite</connection>
<developerConnection>scm:git:${gitBaseUrl}/gcube-cms-suite</developerConnection>
<url>${gitBaseUrl}/gcube-cms-suite</url>
</scm>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.gcube.distribution</groupId>
<artifactId>gcube-bom</artifactId>
<version>${gcube-bom-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.gcube.distribution</groupId>
<artifactId>gcube-smartgears-bom</artifactId>
<version>${gcube-smartgears-bom-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.gcube.distribution</groupId>
<artifactId>gcube-bom</artifactId>
<version>${gcube-bom-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.gcube.distribution</groupId>
<artifactId>gcube-smartgears-bom</artifactId>
<version>${gcube-smartgears-bom-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependencies>
<dependency>
<groupId>org.gcube.application.cms</groupId>
<artifactId>geoportal-common</artifactId>
</dependency>
<dependency>
<groupId>org.gcube.application.cms</groupId>
<artifactId>geoportal-common</artifactId>
</dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
</dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
</dependency>
<dependency>
<groupId>org.gcube.application.cms</groupId>
<artifactId>cms-plugin-framework</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.gcube.application.cms</groupId>
<artifactId>cms-plugin-framework</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>org.gcube.common</groupId>
<artifactId>storagehub-client-library</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>org.gcube.common</groupId>
<artifactId>storagehub-client-library</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>org.gcube.common</groupId>
<artifactId>authorization-utils</artifactId>
<version>[2.0.0, 3.0.0-SNAPSHOT)</version>
</dependency>
<dependency>
<groupId>org.gcube.common</groupId>
<artifactId>authorization-utils</artifactId>
<version>[2.0.0, 3.0.0-SNAPSHOT)</version>
</dependency>
<dependency>
<groupId>org.gcube.common</groupId>
<artifactId>authorization-client</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.gcube.common</groupId>
<artifactId>authorization-client</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.gcube.common</groupId>
<artifactId>common-authorization</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.gcube.common</groupId>
<artifactId>common-authorization</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.gcube.core</groupId>
<artifactId>common-encryption</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.gcube.core</groupId>
<artifactId>common-encryption</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j18-impl</artifactId>
<version>2.13.3</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j18-impl</artifactId>
<version>2.13.3</version>
</dependency>
<!-- Missing in JDK 11 -->
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
</dependency>
<!-- Missing in JDK 11 -->
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
</dependency>
</dependencies>
</dependencies>
</project>

View File

@ -37,9 +37,9 @@ public class TokenSetter {
static{
try {
props.load(TokenSetter.class.getResourceAsStream("/tokens.properties"));
props.load(TokenSetter.class.getResourceAsStream("./tokens.properties"));
} catch (Exception e) {
throw new RuntimeException("YOU NEED TO SET TOKEN FILE IN CONFIGURATION",e);
throw new RuntimeException("YOU NEED TO SET tokens.properties TOKEN FILE IN CONFIGURATION",e);
}
}

View File

@ -1,5 +1,8 @@
# Changelog for org.gcube.application.cms.ckan-plugin
## [v1.3.0-SNAPSHOT]- 2024-03-22
- Updated visibility of phases and steps
## [v1.2.2]- 2023-09-06
- Using parent version range [#25572]

View File

@ -25,6 +25,15 @@ Plugins SHOULD be defined extending the definitions provided in this module.
## Documentation
[gCube CMS Suite](../) parent module containing references, documentation, guides ad utilities.
#### Default Lifecycle Managements
##### Single Step (no moderation)
<img src="https://gcube.wiki.gcube-system.org/images_gcube/8/8c/SingleStep_LC.png" style="max-width:800px;" alt="Default Single Step lifecycle">
##### 3 Phases (content moderation)
<img src="https://gcube.wiki.gcube-system.org/images_gcube/d/d8/Default3Phases_LC.png" style="max-width:800px;" alt="Default 3 Phases lifecycle">
## Change log

View File

@ -5,7 +5,7 @@
<modelVersion>4.0.0</modelVersion>
<artifactId>default-lc-managers</artifactId>
<version>1.2.2</version>
<version>1.3.0-SNAPSHOT</version>
<name>gCube CMS - Default LC Managers</name>
<parent>

View File

@ -132,7 +132,9 @@ public abstract class AbstractLifeCycleManager extends AbstractPlugin implements
request.getUseCaseDescriptor().getId(),
request.getDocument().getId(),
request.getStep());
log.debug("Serving Request full log {}",request);
log.trace("Serving Request full log {}", request);
log.debug("Serving Request on document {}", request.getDocument());
log.debug("Checking is STEP {} is supported by {}",request.getStep(),DESCRIPTOR.getId());
if(!registeredSteps.containsKey(request.getStep()))

View File

@ -29,7 +29,7 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
public class Default3PhaseManager extends SimpleLifeCycleManager implements LifecycleManager {
protected static class Phases {
public static final class Phases {
public static final String PENDING_APPROVAL="Pending Approval";
public static final String PUBLISHED=SimpleLifeCycleManager.Phases.PUBLISHED;

View File

@ -49,14 +49,14 @@ public class SimpleLifeCycleManager extends AbstractLifeCycleManager implements
}
//Updated by Francesco
protected static class Phases {
public static final class Phases {
public static final String PUBLISHED="Published";
public static final String UNPUBLISHED="UnPublished";
}
//Updated by Francesco
private static class Steps {
public static final class Steps {
public static final OperationDescriptor PUBLISH = new OperationDescriptor("PUBLISH","Materialize & index project");
public static final OperationDescriptor UNPUBLISH = new OperationDescriptor("UNPUBLISH","UnPublish the project. DeMaterialize and DeIndex the project");

View File

@ -14,7 +14,7 @@ public class SimpleLifecycleTests {
// public void testFullCycle(){
// SimpleLifeCycleManager manager = plugins.get(SimpleLifeCycleManager.PLUGIN_ID);
//
// StepExecutionRequest request = new StepExecutionRequest();
// PerformStepRequest request = new PerformStepRequest();
//
// Project p = null;
//

View File

@ -1,5 +1,8 @@
# Changelog for org.gcube.application.geoportal-client
## [v1.2.2-SNAPSHOT] - 2024-04-11
- Refactored
## [v1.2.1] - 2023-09-06
- Using parent version range [#25572]

View File

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.gcube.application</groupId>
<artifactId>geoportal-client</artifactId>
<version>1.2.1</version>
<version>1.2.2-SNAPSHOT</version>
<name>Geoportal Client</name>
<parent>

View File

@ -20,7 +20,7 @@ import org.gcube.application.geoportal.common.model.rest.CreateRelationshipReque
import org.gcube.application.geoportal.common.model.rest.DeleteRelationshipRequest;
import org.gcube.application.geoportal.common.model.rest.QueryRequest;
import org.gcube.application.geoportal.common.model.rest.RegisterFileSetRequest;
import org.gcube.application.geoportal.common.model.rest.StepExecutionRequest;
import org.gcube.application.geoportal.common.model.rest.PerformStepRequest;
import org.gcube.application.geoportal.common.rest.InterfaceConstants;
import org.gcube.application.geoportal.common.rest.Projects;
import org.gcube.common.clients.Call;
@ -253,7 +253,7 @@ public class DefaultDocumentsClient<T extends Project> implements Projects<T> {
* @throws RemoteException the remote exception
*/
@Override
public T performStep(String id, StepExecutionRequest request) throws RemoteException {
public T performStep(String id, PerformStepRequest request) throws RemoteException {
try {
log.debug("Executing step on {} (class {}, useCaseDescriptor {}) with request {} ", id, getManagedClass(),
profileID, request);

View File

@ -1,10 +1,10 @@
package org.gcube.application.geoportal;
import java.io.IOException;
import org.gcube.application.cms.tests.TokenSetter;
import org.gcube.application.geoportal.common.utils.StorageUtils;
import java.io.IOException;
public class StorageTests {
public static void main(String[] args) throws IOException {

View File

@ -1,11 +1,11 @@
package org.gcube.application.geoportal.clients;
import static org.junit.Assume.assumeTrue;
import org.gcube.application.cms.tests.TokenSetter;
import org.gcube.application.geoportal.common.utils.tests.GCubeTest;
import org.junit.BeforeClass;
import static org.junit.Assume.assumeTrue;
public class BasicVreTests extends GCubeTest {
@BeforeClass

View File

@ -1,6 +1,11 @@
package org.gcube.application.geoportal.clients;
import com.fasterxml.jackson.core.JsonProcessingException;
import static org.gcube.application.geoportal.client.plugins.GeoportalAbstractPlugin.projects;
import java.io.File;
import java.io.FileNotFoundException;
import java.rmi.RemoteException;
import org.bson.Document;
import org.gcube.application.cms.tests.Tests;
import org.gcube.application.geoportal.client.utils.Serialization;
@ -12,11 +17,7 @@ import org.gcube.application.geoportal.common.utils.FileSets;
import org.gcube.application.geoportal.common.utils.StorageUtils;
import org.junit.Test;
import java.io.File;
import java.io.FileNotFoundException;
import java.rmi.RemoteException;
import static org.gcube.application.geoportal.client.plugins.GeoportalAbstractPlugin.projects;
import com.fasterxml.jackson.core.JsonProcessingException;
public abstract class GenericUseCases extends BasicVreTests{

View File

@ -1,8 +1,15 @@
package org.gcube.application.geoportal.clients;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
import java.io.File;
import java.io.FileNotFoundException;
import java.nio.charset.Charset;
import java.rmi.RemoteException;
import java.util.Iterator;
import org.bson.Document;
import org.gcube.application.cms.tests.TestDocuments;
import org.gcube.application.cms.tests.Tests;
@ -17,7 +24,7 @@ import org.gcube.application.geoportal.common.model.document.relationships.Relat
import org.gcube.application.geoportal.common.model.rest.CreateRelationshipRequest;
import org.gcube.application.geoportal.common.model.rest.DeleteRelationshipRequest;
import org.gcube.application.geoportal.common.model.rest.RegisterFileSetRequest;
import org.gcube.application.geoportal.common.model.rest.StepExecutionRequest;
import org.gcube.application.geoportal.common.model.rest.PerformStepRequest;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.Field;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.HandlerDeclaration;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor;
@ -28,16 +35,10 @@ import org.gcube.application.geoportal.common.utils.StorageUtils;
import org.gcube.application.geoportal.common.utils.tests.GCubeTest;
import org.junit.Test;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.Charset;
import java.rmi.RemoteException;
import java.util.Iterator;
import com.fasterxml.jackson.core.JsonProcessingException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class ProfiledConcessioniTest <M extends Project,C extends Projects<M>> extends GenericUseCases{
@ -66,8 +67,8 @@ public class ProfiledConcessioniTest <M extends Project,C extends Projects<M>> e
Project p=client.createNew(getNewDocument());
p=prepareWithFileSet(p);
p = getClient().performStep(p.getId(), new StepExecutionRequest("SUBMIT-FOR-REVIEW",new Document()));
String optionalMessage = null;
p = getClient().performStep(p.getId(), new PerformStepRequest("SUBMIT-FOR-REVIEW", optionalMessage, new Document()));
System.out.println("Result is "+Serialization.write(p));
}

View File

@ -1,9 +1,15 @@
package org.gcube.application.geoportal.clients;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.extern.slf4j.Slf4j;
import static org.gcube.application.geoportal.client.utils.Serialization.write;
import static org.junit.Assert.assertEquals;
import static org.junit.Assume.assumeTrue;
import java.io.FileNotFoundException;
import java.rmi.RemoteException;
import java.time.LocalDateTime;
import java.util.concurrent.atomic.AtomicLong;
import org.bson.Document;
import org.gcube.application.cms.tests.Tests;
import org.gcube.application.geoportal.client.utils.Serialization;
import org.gcube.application.geoportal.common.faults.InvalidRequestException;
import org.gcube.application.geoportal.common.model.JSONPathWrapper;
@ -12,28 +18,15 @@ import org.gcube.application.geoportal.common.model.document.Project;
import org.gcube.application.geoportal.common.model.document.access.Access;
import org.gcube.application.geoportal.common.model.document.access.AccessPolicy;
import org.gcube.application.geoportal.common.model.document.filesets.RegisteredFileSet;
import org.gcube.application.geoportal.common.model.document.relationships.RelationshipNavigationObject;
import org.gcube.application.geoportal.common.model.rest.CreateRelationshipRequest;
import org.gcube.application.geoportal.common.model.rest.DeleteRelationshipRequest;
import org.gcube.application.geoportal.common.model.rest.QueryRequest;
import org.gcube.application.geoportal.common.model.rest.RegisterFileSetRequest;
import org.gcube.application.geoportal.common.rest.Projects;
import org.gcube.application.geoportal.common.utils.FileSets;
import org.gcube.application.geoportal.common.utils.StorageUtils;
import org.gcube.application.geoportal.common.utils.tests.GCubeTest;
import org.junit.Test;
import java.io.File;
import java.io.FileNotFoundException;
import java.rmi.RemoteException;
import java.time.LocalDateTime;
import java.util.Iterator;
import java.util.concurrent.atomic.AtomicLong;
import com.fasterxml.jackson.core.JsonProcessingException;
import static org.gcube.application.geoportal.client.utils.Serialization.write;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class ProfiledDocumentsTest<M extends Project,C extends Projects<M>> extends GenericUseCases {

View File

@ -1,5 +1,13 @@
package org.gcube.application.geoportal.clients;
import static org.gcube.application.geoportal.client.plugins.GeoportalAbstractPlugin.useCaseDescriptors;
import static org.junit.Assert.assertEquals;
import static org.junit.Assume.assumeTrue;
import java.util.Arrays;
import java.util.HashSet;
import java.util.concurrent.atomic.AtomicLong;
import org.bson.Document;
import org.gcube.application.cms.tests.TokenSetter;
import org.gcube.application.geoportal.client.utils.Serialization;
@ -12,15 +20,6 @@ import org.gcube.application.geoportal.common.utils.tests.GCubeTest;
import org.junit.Assert;
import org.junit.Test;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.concurrent.atomic.AtomicLong;
import static org.gcube.application.geoportal.client.plugins.GeoportalAbstractPlugin.useCaseDescriptors;
import static org.junit.Assert.assertEquals;
import static org.junit.Assume.assumeTrue;
public class UCDTests{

View File

@ -1,12 +1,13 @@
package org.gcube.application.geoportal.clients.serialization;
import lombok.extern.slf4j.Slf4j;
import org.gcube.application.geoportal.client.utils.Serialization;
import org.junit.Test;
import java.io.IOException;
import java.time.LocalDateTime;
import org.gcube.application.geoportal.client.utils.Serialization;
import org.junit.Test;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class SerializationTests {

View File

@ -1,5 +1,14 @@
package org.gcube.application.geoportal.clients.serialization;
import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertTrue;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;
import org.gcube.application.cms.tests.TestProfiles;
import org.gcube.application.geoportal.client.utils.Serialization;
import org.gcube.application.geoportal.common.model.JSONPathWrapper;
@ -9,15 +18,6 @@ import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDes
import org.gcube.application.geoportal.common.utils.Files;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;
import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertTrue;
public class UseCaseDescriptors {
private static UseCaseDescriptor readProfile(String file) throws IOException {

View File

@ -1,5 +1,8 @@
# Changelog for org.gcube.application.geoportal-common
## [v1.1.0-SNAPSHOT] - 2024-04-08
- Added message to StepExecutionRequest [#27192]
## [v1.0.13] - 2023-09-06
- Using parent range version [#25572]

View File

@ -3,7 +3,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>geoportal-common</artifactId>
<version>1.0.13</version>
<version>1.1.0-SNAPSHOT</version>
<name>Geoportal Common</name>
<parent>

View File

@ -1,5 +1,6 @@
package org.gcube.application.geoportal.common.model.rest;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import org.bson.Document;
@ -12,8 +13,10 @@ import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class StepExecutionRequest {
public class PerformStepRequest {
private String stepID;
@XmlAttribute(required = false)
private String message;
private Document options;
}

View File

@ -13,7 +13,7 @@ import org.gcube.application.geoportal.common.model.rest.CreateRelationshipReque
import org.gcube.application.geoportal.common.model.rest.DeleteRelationshipRequest;
import org.gcube.application.geoportal.common.model.rest.QueryRequest;
import org.gcube.application.geoportal.common.model.rest.RegisterFileSetRequest;
import org.gcube.application.geoportal.common.model.rest.StepExecutionRequest;
import org.gcube.application.geoportal.common.model.rest.PerformStepRequest;
public interface Projects<P extends Project> {
@ -39,7 +39,7 @@ public interface Projects<P extends Project> {
public String queryForJSON(QueryRequest request)throws RemoteException;
//Execution
public P performStep(String id, StepExecutionRequest request) throws RemoteException;
public P performStep(String id, PerformStepRequest request) throws RemoteException;
//FileSets
public P registerFileSet(String id, RegisterFileSetRequest req) throws RemoteException, InvalidRequestException;

View File

@ -18,7 +18,7 @@ public class FilesTests {
static File baseFolder=new File("../test-data/concessioni");
@Test
//@Test
public void testNames(){
ArrayList<String> toTestStrings=new ArrayList<>(Arrays.asList(baseFolder.list()));
@ -36,7 +36,7 @@ public class FilesTests {
}
}
@Test
//@Test
public void testClustering() throws IOException {
Map<String, List<File>> map=Files.getAllShapeSet(baseFolder.getParentFile(),true);
map.forEach((k, v)->{

View File

@ -29,7 +29,7 @@ public class StorageUtilsTest {
IClient client= null;
@Before
//@Before
public void init(){
assumeTrue(GCubeTest.isTestInfrastructureEnabled());
TokenSetter.set(GCubeTest.getContext());
@ -47,7 +47,7 @@ public class StorageUtilsTest {
return client.getHttpsUrl().RFile(id);
}
@Test
//@Test
public void testParallelStorage() throws FileNotFoundException, InterruptedException {
assumeTrue(GCubeTest.isTestInfrastructureEnabled());
ExecutorService service = Executors.newFixedThreadPool(10);
@ -81,7 +81,7 @@ public class StorageUtilsTest {
}
}
@Test
//@Test
public void testSerialStorage() throws FileNotFoundException {
assumeTrue(GCubeTest.isTestInfrastructureEnabled());
//get client

View File

@ -11,14 +11,14 @@ import static org.junit.Assert.assertEquals;
public class DefaultsTests {
@Test
//@Test
public void checkConstraints(){
assertEquals(AccessPolicy.OPEN,ConstraintCheck.defaultFor(null,AccessPolicy.OPEN).evaluate());
assertEquals(AccessPolicy.EMBARGOED,ConstraintCheck.defaultFor(AccessPolicy.EMBARGOED,AccessPolicy.OPEN).evaluate());
}
@Test
//@Test
public void checkDefaults(){
Concessione c= new Concessione();

View File

@ -35,7 +35,7 @@ public class JSONPathTests {
}
@Test
//@Test
public void readElements() throws IOException {
JSONPathWrapper documentNavigator=getNavigator("profiledConcessioniExample.json");
@ -54,7 +54,7 @@ public class JSONPathTests {
}
@Test
//@Test
public void writeTest() throws IOException {
JSONPathWrapper wrapper =getNavigator("emptyProfiledDocument.json");
checkSetValue(wrapper,"firstField","value1");
@ -112,7 +112,7 @@ public class JSONPathTests {
assertTrue(foundElements.size()==sizeBefore+1);
}
@Test
//@Test
public void testTokenizer(){
assertTrue(JSONPathWrapper.tokenizePath("$.firstField").size()==1);
assertTrue(JSONPathWrapper.tokenizePath("$.firstField.child").size()==2);
@ -129,7 +129,7 @@ public class JSONPathTests {
}
@Test
//@Test
public void testGetFieldNameFromPathElement(){
assertEquals(JSONPathWrapper.extractFieldNameFromPathElement("$.firstField"),"firstField");
assertEquals(JSONPathWrapper.extractFieldNameFromPathElement("firstField"),"firstField");
@ -137,7 +137,7 @@ public class JSONPathTests {
assertEquals(JSONPathWrapper.extractFieldNameFromPathElement("$['book'][?(@.isbn)]"),"book");
}
@Test
//@Test
public void testDefinitePath(){
assertTrue(JsonPath.isPathDefinite("$.firstField"));
assertTrue(JsonPath.isPathDefinite("$.firstField.child"));

View File

@ -1,5 +1,10 @@
# Changelog for org.gcube.application.geoportal-service
## [v1.2.0-SNAPSHOT] - 2024-04-08
- Integrated the EventManager of the cms-plugin-framework
- Added optional message when performing lifecycle step [#27192]
## [v1.1.1] - 2023-09-06
- Fixed data accounting issue [#25571]

View File

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.gcube.application</groupId>
<artifactId>geoportal-service</artifactId>
<version>1.1.1</version>
<version>1.2.0-SNAPSHOT</version>
<name>Geoportal Service</name>
<packaging>war</packaging>

View File

@ -1,5 +1,10 @@
package org.gcube.application.geoportal.service.rest;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
@ -15,14 +20,22 @@ import javax.ws.rs.core.MediaType;
import org.bson.Document;
import org.gcube.application.cms.implementations.ImplementationProvider;
import org.gcube.application.cms.implementations.utils.UserUtils;
import org.gcube.application.cms.plugins.events.EventManager;
import org.gcube.application.cms.plugins.events.EventManager.Event;
import org.gcube.application.cms.plugins.events.ItemObserved;
import org.gcube.application.cms.plugins.events.ItemObserved.OPTIONAL_FIELD;
import org.gcube.application.cms.serialization.Serialization;
import org.gcube.application.geoportal.common.model.configuration.Configuration;
import org.gcube.application.geoportal.common.model.document.Project;
import org.gcube.application.geoportal.common.model.document.access.Access;
import org.gcube.application.geoportal.common.model.document.accounting.AccountingInfo;
import org.gcube.application.geoportal.common.model.document.lifecycle.LifecycleInformation;
import org.gcube.application.geoportal.common.model.document.lifecycle.LifecycleInformation.Status;
import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
import org.gcube.application.geoportal.common.model.rest.QueryRequest;
import org.gcube.application.geoportal.common.model.rest.RegisterFileSetRequest;
import org.gcube.application.geoportal.common.model.rest.StepExecutionRequest;
import org.gcube.application.geoportal.common.model.rest.PerformStepRequest;
import org.gcube.application.geoportal.common.rest.InterfaceConstants;
import org.gcube.application.geoportal.service.engine.mongo.ProfiledMongoManager;
import org.gcube.application.geoportal.service.engine.providers.ConfigurationCache;
@ -38,8 +51,8 @@ import lombok.extern.slf4j.Slf4j;
* The Class ProfiledDocuments.
*
* @author created by Fabio Sinibaldi
* @author new manager/developer and mantainer - Francesco Mangiacrapa at ISTI-CNR
* francesco.mangiacrapa@isti.cnr.it
* @author new manager/developer and mantainer - Francesco Mangiacrapa at
* ISTI-CNR francesco.mangiacrapa@isti.cnr.it
*
* Apr 18, 2023
*/
@ -51,6 +64,7 @@ import lombok.extern.slf4j.Slf4j;
public class ProfiledDocuments {
private ProfiledMongoManager manager;
private EventManager eventManager = EventManager.getInstance(); // as singleton
/**
* Instantiates a new profiled documents.
@ -99,7 +113,7 @@ public class ProfiledDocuments {
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Project createNew(Document d) {
return new GuardedMethod<Project>() {
Project theNewProject = new GuardedMethod<Project>() {
@Override
protected Project run() throws Exception, WebApplicationException {
log.info("Creating new Project ({})", manager.getUseCaseDescriptor().getId());
@ -108,6 +122,25 @@ public class ProfiledDocuments {
return toReturn;
}
}.execute().getResult();
Status status = theNewProject.getLifecycleInformation().getLastOperationStatus();
// If latest operation status is not ERROR, notify PROJECT_CREATED event
if (status != null && !status.equals(LifecycleInformation.Status.ERROR)) {
// notifying the Event.PROJECT_CREATED;
ItemObserved<Project> item = new ItemObserved<Project>();
EventManager.Event event = Event.PROJECT_CREATED;
AccountingInfo user = UserUtils.getCurrent().asInfo();
item.setUserCaller(user.getUser());
item.setContext(user.getContext());
item.setOptional(null);
item.setEvent(event);
item.setProject(theNewProject);
item.setUseCaseDescriptor(manager.getUseCaseDescriptor());
log.info("By notifying event ({}, ID {})", event, item.getProjectId());
eventManager.notify(event, item);
}
return theNewProject;
}
/**
@ -122,13 +155,32 @@ public class ProfiledDocuments {
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Project update(@PathParam(InterfaceConstants.Parameters.PROJECT_ID) String documentId, Document d) {
return new GuardedMethod<Project>() {
Project theUpdatedProject = new GuardedMethod<Project>() {
@Override
protected Project run() throws Exception, WebApplicationException {
log.info("Updating Project ({}, ID {})", manager.getUseCaseDescriptor().getId(), documentId);
return manager.update(documentId, d);
}
}.execute().getResult();
Status status = theUpdatedProject.getLifecycleInformation().getLastOperationStatus();
// If latest operation status is not ERROR, notify PROJECT_UPDATED event
if (status != null && !status.equals(LifecycleInformation.Status.ERROR)) {
ItemObserved<Project> item = new ItemObserved<Project>();
EventManager.Event event = Event.PROJECT_UPDATED;
AccountingInfo user = UserUtils.getCurrent().asInfo();
item.setUserCaller(user.getUser());
item.setContext(user.getContext());
item.setOptional(null);
item.setEvent(event);
item.setProject(theUpdatedProject);
item.setUseCaseDescriptor(manager.getUseCaseDescriptor());
log.info("By notifying event ({}, ID {})", event, item.getProjectId());
eventManager.notify(event, item);
}
return theUpdatedProject;
}
/**
@ -165,7 +217,7 @@ public class ProfiledDocuments {
@Path("{" + InterfaceConstants.Parameters.PROJECT_ID + "}")
public Boolean delete(@PathParam(InterfaceConstants.Parameters.PROJECT_ID) String id,
@DefaultValue("false") @QueryParam(InterfaceConstants.Parameters.FORCE) Boolean force) {
return new GuardedMethod<Boolean>() {
Boolean deleted = new GuardedMethod<Boolean>() {
@Override
protected Boolean run() throws Exception, WebApplicationException {
log.info("Deleting Project ({}, ID {}). Force is {}", manager.getUseCaseDescriptor().getId(), id,
@ -174,6 +226,26 @@ public class ProfiledDocuments {
return true;
}
}.execute().getResult();
// If deleted, notify PROJECT_DELETED event
if (deleted) {
ItemObserved<Project> item = new ItemObserved<Project>();
EventManager.Event event = Event.PROJECT_DELETED;
AccountingInfo user = UserUtils.getCurrent().asInfo();
item.setUserCaller(user.getUser());
item.setContext(user.getContext());
item.setEvent(event);
item.setUseCaseDescriptor(manager.getUseCaseDescriptor());
// Referencing delete project
Project deletedProject = new Project();
deletedProject.setId(id);
deletedProject.setProfileID(manager.getUseCaseDescriptor().getId());
item.setProject(deletedProject);
log.info("By notifying event ({}, ID {})", event, item.getProjectId());
eventManager.notify(event, item);
}
return deleted;
}
/**
@ -217,7 +289,8 @@ public class ProfiledDocuments {
@Path("/" + InterfaceConstants.Methods.DELETE_FILES_PATH + "/{" + InterfaceConstants.Parameters.PROJECT_ID + "}")
public Project deleteFileSet(@PathParam(InterfaceConstants.Parameters.PROJECT_ID) String id,
@DefaultValue("false") @QueryParam(InterfaceConstants.Parameters.FORCE) Boolean force,
@DefaultValue("false") @QueryParam(InterfaceConstants.Parameters.IGNORE_ERRORS) Boolean ignore_errors, String path) {
@DefaultValue("false") @QueryParam(InterfaceConstants.Parameters.IGNORE_ERRORS) Boolean ignore_errors,
String path) {
return new GuardedMethod<Project>() {
@Override
protected Project run() throws Exception, WebApplicationException {
@ -240,15 +313,34 @@ public class ProfiledDocuments {
@Produces(MediaType.APPLICATION_JSON)
@Path("/" + InterfaceConstants.Methods.STEP + "/{" + InterfaceConstants.Parameters.PROJECT_ID + "}")
public Project performStep(@PathParam(InterfaceConstants.Parameters.PROJECT_ID) String id,
StepExecutionRequest request) {
return new GuardedMethod<Project>() {
PerformStepRequest performStepRequest) {
Project theProject = new GuardedMethod<Project>() {
@Override
protected Project run() throws Exception, WebApplicationException {
log.info("Executing step {} on Project ({},ID,{}) with options {}", request.getStepID(),
manager.getUseCaseDescriptor().getId(), id, request.getOptions());
return manager.performStep(id, request.getStepID(), request.getOptions());
log.info("Executing step {} on Project ({},ID,{}) with options {}", performStepRequest.getStepID(),
manager.getUseCaseDescriptor().getId(), id, performStepRequest.getOptions());
return manager.performStep(id, performStepRequest.getStepID(), performStepRequest.getOptions());
}
}.execute().getResult();
Status status = theProject.getLifecycleInformation().getLastOperationStatus();
// If latest operation status is not ERROR, notify LIFECYCLE_STEP_PERFORMED
// event
if (status != null && !status.equals(LifecycleInformation.Status.ERROR)) {
ItemObserved<Project> item = new ItemObserved<Project>();
EventManager.Event event = Event.LIFECYCLE_STEP_PERFORMED;
AccountingInfo user = UserUtils.getCurrent().asInfo();
item.setUserCaller(user.getUser());
item.setContext(user.getContext());
item.setEvent(event);
item.setOptional(OPTIONAL_FIELD.message, performStepRequest.getMessage());
item.setUseCaseDescriptor(manager.getUseCaseDescriptor());
item.setProject(theProject);
log.info("By notifying event ({}, ID {})", event, item.getProjectId());
eventManager.notify(event, item);
}
return theProject;
}
/**
@ -457,4 +549,4 @@ public class ProfiledDocuments {
}.execute().getResult();
}
}
}

View File

@ -21,7 +21,7 @@ import org.gcube.application.geoportal.common.model.document.access.Access;
import org.gcube.application.geoportal.common.model.document.lifecycle.LifecycleInformation;
import org.gcube.application.geoportal.common.model.rest.QueryRequest;
import org.gcube.application.geoportal.common.model.rest.RegisterFileSetRequest;
import org.gcube.application.geoportal.common.model.rest.StepExecutionRequest;
import org.gcube.application.geoportal.common.model.rest.PerformStepRequest;
import org.gcube.application.geoportal.common.rest.InterfaceConstants;
import org.gcube.application.geoportal.common.utils.FileSets;
import org.gcube.application.geoportal.common.utils.StorageUtils;
@ -180,7 +180,7 @@ public abstract class AbstractProfiledDocumentsTests extends BasicServiceTestUni
}
protected Project step(String id, StepExecutionRequest request) throws Exception {
protected Project step(String id, PerformStepRequest request) throws Exception {
Project toReturn= check(baseTarget().
path(InterfaceConstants.Methods.STEP).path(id).request(MediaType.APPLICATION_JSON).
post(Entity.entity(Serialization.write(request),

View File

@ -9,7 +9,7 @@ import org.gcube.application.geoportal.common.model.document.access.Access;
import org.gcube.application.geoportal.common.model.document.identification.SpatialReference;
import org.gcube.application.geoportal.common.model.document.lifecycle.LifecycleInformation;
import org.gcube.application.geoportal.common.model.rest.RegisterFileSetRequest;
import org.gcube.application.geoportal.common.model.rest.StepExecutionRequest;
import org.gcube.application.geoportal.common.model.rest.PerformStepRequest;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.Field;
import org.gcube.application.geoportal.common.utils.StorageUtils;
import org.gcube.application.geoportal.common.utils.tests.GCubeTest;
@ -69,7 +69,7 @@ public class ProfiledConcessioniTests extends AbstractProfiledDocumentsTests{
System.out.println("Registered posizionamento, result is "+ Serialization.write(doc));
// invoke step SUBMIT-FOR-REVIEW
StepExecutionRequest submitReq=new StepExecutionRequest();
PerformStepRequest submitReq=new PerformStepRequest();
submitReq.setStepID("SUBMIT-FOR-REVIEW");
// doc=step(doc.getId(),submitReq);
doc=step(doc.getId(),submitReq);
@ -79,7 +79,7 @@ public class ProfiledConcessioniTests extends AbstractProfiledDocumentsTests{
// invoke step Publish
StepExecutionRequest approveDraftReq=new StepExecutionRequest();
PerformStepRequest approveDraftReq=new PerformStepRequest();
approveDraftReq.setStepID("APPROVE-SUBMITTED");
doc=step(doc.getId(),approveDraftReq);
System.out.println(doc);
@ -137,7 +137,7 @@ public class ProfiledConcessioniTests extends AbstractProfiledDocumentsTests{
assertEquals(doc2.getRelationships().get(0).getTargetUCD(),doc1.getProfileID());
assertEquals(doc2.getRelationships().get(0).getRelationshipName(),reverse);
StepExecutionRequest stepReq = new StepExecutionRequest();
PerformStepRequest stepReq = new PerformStepRequest();
stepReq.setStepID("SUBMIT-FOR-REVIEW");
step(doc1.getId(),stepReq);

View File

@ -1,6 +1,9 @@
# Changelog for org.gcube.application.cms.notifications-plugins
## [v1.0.4-SNAPSHOT] - 2023-09-06
## [v1.0.5-SNAPSHOT] - 2024-04-10
- Implemented the notification-plugin [#26453]
## [v1.0.4] - 2023-09-06
- Using parent version range [#25572]
## [v1.0.3] - 2023-03-06

View File

@ -16,11 +16,115 @@ This module is expected to contain plugin definitions for the generations of not
## Documentation
[gCube CMS Suite](../) parent module containing references, documentation, guides ad utilities.
This plugin requires a configuration of type:
```json
{
"subscribeNotifications": [
{
"event": "EVENT_NAME",
"notificationFor": [
{
"roles": [
"USER_ROLE"
],
"when": [
{
"target_phase": [
"TARGET_PHASE"
],
"last_invoked_step": LAST_INVOKED_STEP_1,
"notify": [
{
"type": "NOTIFICATION_TYPE",
"send": "true/false",
"placeholder_title": "PLACEHOLDER_TITLE_1",
"placeholder_msg": "PLACEHOLDER_MESSAGE_1",
"export_as_pdf": {
"placeholder_msg": "Export as PDF placeholder",
"export": true
}
}
]
},
{
"target_phase": [
"TARGET_PHASE"
],
"last_invoked_step": LAST_INVOKED_STEP_2,
"notify": [
{
"type": "NOTIFICATION_TYPE",
"send": "true/false",
"placeholder_title": "PLACEHOLDER_TITLE_2",
"placeholder_msg": "PLACEHOLDER_MESSAGE_2",
"export_as_pdf": {
"placeholder_msg": "Export as PDF placeholder",
"export": true
}
}
]
}
]
}
]
}
],
"enabled":true/false,
"link_to_notifications_messages": "link to file containing the messages as properties like PLACEHOLDER_MESSAGE_{N} = value"
}
```
Where:
* `enabled` (optional) can be: true/false. Default is true. It enables or not the plugin.
* `link_to_notifications_messages` (mandatory): it is the URL to Notifications Messages file with placeholder values. A property file like PLACEHOLDER_MESSAGE_{N} = value
and
* `EVENT_NAME` (mandatory) can be: `PROJECT_CREATED`, `PROJECT_UPDATED`, `PROJECT_DELETED`, `LIFECYCLE_STEP_PERFORMED`;
* `USER_ROLE` (mandatory) can be: `Data-Manager`, `Data-Editor`, `Member`, `Item_Creator`, `Any`;
* `TARGET_PHASE` (mandatory) can be: `DRAFT`, `Pending Approval`, `Published`, `Any`;
* `LAST_INVOKED_STEP` (optional) can be: `SUBMIT-FOR-REVIEW`, `APPROVE-SUBMITTED`, `REJECT-DRAFT`, `UNPUBLISH`;
* `NOTIFICATION_TYPE` (mandatory) can be: `USER_NOTIFICATION`, `VRE_POST`, `EMAIL`;
**PLACEHOLDER_MESSAGE_{N}.properties** managed/known placeholders:
* `${project_name}`
* `${project_id}`
* `${private_data_entry_link}`
* `${public_data_entry_link}`
* `${private_data_viewer_link}`
* `${public_data_viewer_link}`
* `${project_as_pdf_link}`
* `${user_caller}`
e.g. Messages using the placeholders:
```txt
# REVIEW ACTION
TITLE_REVIEW_REQUIRED=Review required for ${project_name}
MSG_REVIEW_REQUIRED=@${user_caller} submitted the project ${project_name}. You are kindly requested to review it and decide either to APPROVE or REJECT it. See the Project at ${private_data_entry_link}
# REJECTED ACTION
TITLE_ITEM_REJECTED=Rejected ${project_name}
MSG_ITEM_REJECTED=The project ${project_name} (id: ${project_id}) has just been rejected by @${user_caller}. See the Project at ${private_data_entry_link}
# REJECTED ACTION
TITLE_ITEM_REJECTED_REVIEW_REQUIRED=Rejected ${project_name}
MSG_ITEM_REJECTED_REVIEW_REQUIRED=The project ${project_name} has just been rejected. You are kindly requested to review it. See the Project at ${private_data_entry_link}
```
[See here a full file with messages](https://code-repo.d4science.org/gCubeSystem/gcube-cms-suite/raw/branch/event_manager/D4S_UCDs/DEV/devVRE/notifications/Notifications_Messages.properties)
## Change log
See [CHANGELOG.md](CHANGELOG.md).
## Authors
* **Francesco Mangiacrapa** ([ORCID](https://orcid.org/0000-0002-6528-664X)) Computer Scientist at [ISTI-CNR Infrascience Group](http://nemis.isti.cnr.it/groups/infrascience)
## License
This project is licensed under the EUPL V.1.1 License - see the [LICENSE.md](LICENSE.md) file for details.

View File

@ -1,85 +1,120 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>notifications-plugins</artifactId>
<version>1.0.5-SNAPSHOT</version>
<name>gCube CMS - Notifications Plugins</name>
<artifactId>notifications-plugins</artifactId>
<version>1.0.4-SNAPSHOT</version>
<name>gCube CMS - Notifications Plugins</name>
<parent>
<groupId>org.gcube.application.cms</groupId>
<artifactId>gcube-cms-suite</artifactId>
<version>[1.0.0, 2.0.0-SNAPSHOT)</version>
</parent>
<properties>
<gitBaseUrl>https://code-repo.d4science.org/gCubeSystem</gitBaseUrl>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.gcube.distribution</groupId>
<artifactId>gcube-smartgears-bom</artifactId>
<version>${gcube-smartgears-bom-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.gcube.application.cms</groupId>
<artifactId>cms-plugin-framework</artifactId>
<version>${plugin-framework-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<properties>
<gitBaseUrl>https://code-repo.d4science.org/gCubeSystem</gitBaseUrl>
</properties>
<scm>
<connection>scm:git:${gitBaseUrl}/gcube-cms-suite</connection>
<developerConnection>scm:git:${gitBaseUrl}/gcube-cms-suite</developerConnection>
<url>${gitBaseUrl}/gcube-cms-suite</url>
</scm>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.gcube.distribution</groupId>
<artifactId>gcube-smartgears-bom</artifactId>
<version>${gcube-smartgears-bom-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.gcube.application.cms</groupId>
<artifactId>cms-plugin-framework</artifactId>
<version>${plugin-framework-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<scm>
<connection>scm:git:${gitBaseUrl}/gcube-cms-suite</connection>
<developerConnection>scm:git:${gitBaseUrl}/gcube-cms-suite</developerConnection>
<url>${gitBaseUrl}/gcube-cms-suite</url>
</scm>
<dependencies>
<dependency>
<groupId>org.gcube.application.cms</groupId>
<artifactId>cms-plugin-framework</artifactId>
</dependency>
<dependency>
<groupId>org.gcube.application.cms</groupId>
<artifactId>default-lc-managers</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.gcube.application.cms</groupId>
<artifactId>cms-test-commons</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<dependencies>
<dependency>
<groupId>org.gcube.application.cms</groupId>
<artifactId>cms-plugin-framework</artifactId>
</dependency>
<dependency>
<groupId>org.gcube.application.cms</groupId>
<artifactId>default-lc-managers</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.gcube.social-networking</groupId>
<artifactId>social-service-client</artifactId>
<version>[2.0.0-SNAPSHOT, 3.0.0-SNAPSHOT)</version>
</dependency>
<dependency>
<groupId>org.gcube.portlets.user</groupId>
<artifactId>uri-resolver-manager</artifactId>
<version>[1.0.0,2.0.0-SNAPSHOT)</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.11.0</version>
</dependency>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>make-uberjar</id>
<phase>package</phase>
</execution>
<execution>
<id>make-servicearchive</id>
<phase>package</phase>
</execution>
</executions>
</plugin>
<dependency>
<groupId>org.gcube.common</groupId>
<artifactId>authorization-utils</artifactId>
<version>${authorization-utils-range}</version>
</dependency>
<!-- Fix the issue with JUnit tests: java.lang.NoClassDefFoundError : javax/xml/soap/SOAPException -->
<!-- <dependency> -->
<!-- <groupId>javax.xml.soap</groupId> -->
<!-- <artifactId>javax.xml.soap-api</artifactId> -->
<!-- <version>1.4.0</version> -->
<!-- </dependency> -->
</plugins>
</build>
<dependency>
<groupId>javax.xml.ws</groupId>
<artifactId>jaxws-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.gcube.application.cms</groupId>
<artifactId>cms-test-commons</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>make-uberjar</id>
<phase>package</phase>
</execution>
<execution>
<id>make-servicearchive</id>
<phase>package</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,18 @@
package org.gcube.application.cms.notifications;
import java.util.List;
import org.gcube.application.cms.notifications.config.SubscribeNotificationEvent;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor;
import org.gcube.com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class NotificationEventsSubscribedConfig {
UseCaseDescriptor ucd;
List<SubscribeNotificationEvent> listNotificationEventSubscribed;
String linkToNotificationsMessages;
boolean enabled = true;
}

View File

@ -0,0 +1,17 @@
package org.gcube.application.cms.notifications;
public class NotificationGenericConstants {
public static enum CUSTOM_TARGET_PHASE {
Any
};
public static enum CUSTOM_USER_ROLES {
Item_Creator, Any
};
public static enum NOTIFICATION_TYPE {
USER_NOTIFICATION, EMAIL, VRE_POST
};
}

View File

@ -1,30 +1,415 @@
package org.gcube.application.cms.notifications;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.bson.Document;
import org.gcube.application.cms.implementations.utils.UserUtils;
import org.gcube.application.cms.notifications.config.SubscribeNotificationEvent;
import org.gcube.application.cms.notifications.manage.ManageDoActionNotification;
import org.gcube.application.cms.notifications.substitutor.NMessagesPlaceholdersSubstitutorUtil;
import org.gcube.application.cms.plugins.EventListenerPluginInterface;
import org.gcube.application.cms.plugins.events.EventListener;
import org.gcube.application.cms.plugins.events.EventManager;
import org.gcube.application.cms.plugins.events.EventManager.Event;
import org.gcube.application.cms.plugins.events.ItemObserved;
import org.gcube.application.cms.plugins.faults.InitializationException;
import org.gcube.application.cms.plugins.faults.InvalidProfileException;
import org.gcube.application.cms.plugins.faults.MaterializationException;
import org.gcube.application.cms.plugins.faults.ShutDownException;
import org.gcube.application.cms.plugins.implementations.AbstractPlugin;
import org.gcube.application.cms.plugins.reports.InitializationReport;
import org.gcube.application.cms.plugins.reports.Report;
import org.gcube.application.cms.plugins.reports.Report.Status;
import org.gcube.application.cms.serialization.Serialization;
import org.gcube.application.geoportal.common.model.document.Project;
import org.gcube.application.geoportal.common.model.plugins.PluginDescriptor;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor;
public class NotificationsPlugin extends AbstractPlugin {
import com.vdurmont.semver4j.Semver;
import lombok.Synchronized;
import lombok.extern.slf4j.Slf4j;
@Override
public PluginDescriptor getDescriptor() {
/*
Should basically perform something like
curl --location --request POST 'https://api.dev.d4science.org/social-networking-library-ws/rest/2/notifications/catalogue' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJSSklZNEpoNF9qdDdvNmREY0NlUDFfS1l0akcxVExXVW9oMkQ2Tzk1bFNBIn0.eyJleHAiOjE2NTEyMzY2MzgsImlhdCI6MTY1MTIzNjMzOCwiYXV0aF90aW1lIjoxNjUxMjM2MzM0LCJqdGkiOiI5OGE5NjliMy04N2EzLTRiZWYtOWQ1Yi0yYTUwMmM5YWNmZTEiLCJpc3MiOiJodHRwczovL2FjY291bnRzLmRldi5kNHNjaWVuY2Uub3JnL2F1dGgvcmVhbG1zL2Q0c2NpZW5jZSIsImF1ZCI6IiUyRmdjdWJlJTJGZGV2c2VjJTJGZGV2VlJFIiwic3ViIjoiNmE4MmY1ODctYzgwZS00OWUzLTg4YzYtYzExN2U5ZDhkM2Y3IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoibmV4dC5kNHNjaWVuY2Uub3JnIiwic2Vzc2lvbl9zdGF0ZSI6IjA2NzQ2ZDNkLTExNjYtNGVjMC1hZWZmLTBiY2Q2YTEzMTI0MiIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiLyoiXSwicmVzb3VyY2VfYWNjZXNzIjp7ImNvbmR1Y3Rvci1zZXJ2ZXIiOnsicm9sZXMiOlsiY29uZHVjdG9yLW1hbmFnZXIiXX0sIiUyRmdjdWJlJTJGZGV2c2VjJTJGZGV2VlJFIjp7InJvbGVzIjpbIkRhdGEtTWFuYWdlciIsIlZSRS1NYW5hZ2VyIiwiTWVtYmVyIl19fSwiYXV0aG9yaXphdGlvbiI6eyJwZXJtaXNzaW9ucyI6W3sicnNpZCI6IjU3Mjg1NTEwLTM5MzktNGRlNy04ZmMxLWUzYTlkM2NjZTI4MSIsInJzbmFtZSI6IkRlZmF1bHQgUmVzb3VyY2UifV19LCJzY29wZSI6ImVtYWlsIHByb2ZpbGUiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwibmFtZSI6Ik1hc3NpbWlsaWFuIEFzc2FudGUiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJtYXNzaW1pbGlhbm8uYXNzYW50ZSIsImdpdmVuX25hbWUiOiJNYXNzaW1pbGlhbiIsImxvY2FsZSI6ImVuIiwiZmFtaWx5X25hbWUiOiJBc3NhbnRlIiwiZW1haWwiOiJtYXNzaW1pbGlhbm8uYXNzYW50ZUBpc3RpLmNuci5pdCJ9.b7TBRgsW0__3kl2H_ljcL7fSI9I1QaIqQq0Y7S90bWHtkRvmPkPyzWuGq9hhyN1kRg52Ue_3tEEDEkGgtceBEoZ0RAbpppkum7AJvjX6tKHF79k7wpnbxl7ED65VZFk0EazfC2w_n0WvPHQsb67zdwFeZk97G0pbjsVxYUBrhmnEMtXNzmAWaC0cc_-DriE5BBn3DjuWnaxXDxp3DB74YZoJmYR9HYN94c7Y0IV1XZxGFXLZ8V7UTfcJrGqulhF7HU79jd8hccZniam3NEfTZV-knJ4uEnupRHfMLBhnn1MGzxYFPN1xPIPgwiLSvRef7lK2sjI_bi6GAcT0sg5zwA' \
--data-raw ' {
"idsToNotify" : ["leonardo.candela", "luca.frosini"],
"itemId" : "Conversational search dataset with labels",
"notifyText" : "published the test item '\''Conversational search dataset with labels'\''",
"itemURL" : "https://data.d4science.org/ctlg/ResourceCatalogue/conversational_dataset_with_labels",
"idsAsGroup" : false,
"type" : "ITEM_PUBLISHED"
}
*/
return null;
}
/**
* The Class NotificationsPlugin.
*
* @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it
*
* Jan 30, 2024
*/
@Slf4j
public class NotificationsPlugin extends AbstractPlugin implements EventListenerPluginInterface {
public static final String SUBSCRIBE_NOTIFICATIONS_CONFIG = "subscribeNotifications";
public static final String PLUGIN_ID = "Notifications-Plugin";
public static final String PLUGIN_TYPE = "EventListener";
private static final String CONFIG_ENABLED = "enabled";
private static final String CONFIG_LINK_TO_NOTIFICATIONS_MESSAGES = "link_to_notifications_messages";
public static final PluginDescriptor DESCRIPTOR = new PluginDescriptor(PLUGIN_ID, PLUGIN_TYPE);
static {
DESCRIPTOR.setVersion(new Semver("1.0.0"));
DESCRIPTOR.setDescription("Manage the notification from Geoportal engine");
}
// This is a map "<Context,<UCD_ID,NotificationEventsSubscribedConfig>"
protected Map<String, Map<String, NotificationEventsSubscribedConfig>> notificationEventsBindingMap = null;
/**
* Inits the.
*
* @return the initialization report
* @throws InitializationException the initialization exception
*/
@Override
public InitializationReport init() throws InitializationException {
log.debug("Called init");
InitializationReport report = null;
try {
// Creating all listeners
EventListener<ItemObserved<Project>> listenerCreated = new EventListener<ItemObserved<Project>>() {
@Override
public void updated(ItemObserved<Project> observerd) {
log.info("listenerCreated fired on item: {} ", observerd);
boolean subscribed = checkIfSubscribedEvent(observerd);
if (subscribed) {
doAction(observerd);
}
}
};
EventListener<ItemObserved<Project>> listenerUpdated = new EventListener<ItemObserved<Project>>() {
@Override
public void updated(ItemObserved<Project> observerd) {
log.info("listenerUpdated fired on item: {} ", observerd);
boolean subscribed = checkIfSubscribedEvent(observerd);
if (subscribed) {
doAction(observerd);
}
}
};
EventListener<ItemObserved<Project>> listenerDeleted = new EventListener<ItemObserved<Project>>() {
@Override
public void updated(ItemObserved<Project> observerd) {
log.info("listenerDeleted fired on item: {} ", observerd);
boolean subscribed = checkIfSubscribedEvent(observerd);
if (subscribed) {
doAction(observerd);
}
}
};
EventListener<ItemObserved<Project>> listenerLCStepPerformed = new EventListener<ItemObserved<Project>>() {
@Override
public void updated(ItemObserved<Project> observerd) {
log.info("listenerLCStepPerformed fired on item: {} ", observerd);
boolean subscribed = checkIfSubscribedEvent(observerd);
if (subscribed) {
doAction(observerd);
}
}
};
// Subscribing all events
EventManager eventMngInst = EventManager.getInstance();
eventMngInst.subscribe(Event.PROJECT_CREATED, listenerCreated);
eventMngInst.subscribe(Event.PROJECT_UPDATED, listenerUpdated);
eventMngInst.subscribe(Event.PROJECT_DELETED, listenerDeleted);
eventMngInst.subscribe(Event.LIFECYCLE_STEP_PERFORMED, listenerLCStepPerformed);
report = new InitializationReport(Status.OK, PLUGIN_ID + " init performed");
} catch (Exception e) {
InitializationException exc = new InitializationException("Unable to initialize " + DESCRIPTOR.getId(), e);
log.error("init error: {} ", exc);
throw exc;
}
return report;
}
/**
* Gets the descriptor.
*
* @return the descriptor
*/
@Override
public PluginDescriptor getDescriptor() {
return DESCRIPTOR;
}
/**
* Inits the in context.
*
* @return the initialization report
* @throws InitializationException the initialization exception
*/
@Override
@Synchronized
public InitializationReport initInContext() throws InitializationException {
log.debug("Called initInContext");
InitializationReport report = new InitializationReport();
try {
String context = UserUtils.getCurrent().getContext();
if (getNotificationBindingMapPerContext() == null) {
log.info("Initializing in " + context);
notificationEventsBindingMap.put(context, new HashMap<String, NotificationEventsSubscribedConfig>());
}
report.setStatus(Report.Status.OK);
report.putMessage("Initialized " + DESCRIPTOR.getId() + " in the " + context);
} catch (Exception e) {
InitializationException exc = new InitializationException("Unable to initialize " + DESCRIPTOR.getId(), e);
log.error("initInContext error: {} ", exc);
throw exc;
}
return report;
}
/**
* Check if subscribed event.
*
* @param observerd the observerd
* @return true, if successful
*/
public boolean checkIfSubscribedEvent(ItemObserved<Project> observerd) {
log.info("Checking if {} is an subscribed event", observerd.getEvent());
try {
NotificationEventsSubscribedConfig eventsSub = readNotificationsSubscribedFromConfigurationInTheUCD(
observerd.getUseCaseDescriptor());
if (eventsSub != null) {
List<SubscribeNotificationEvent> listEvents = eventsSub.getListNotificationEventSubscribed();
log.info("List events is {}", listEvents);
if(listEvents==null) {
log.info("no event subscribed, returning false");
return false;
}
if (listEvents.stream().anyMatch(sne -> sne.getEvent().equals(observerd.getEvent()))) {
log.info("the event {} is subscribed from config ", observerd.getEvent());
return true;
}
log.info("the event {} is not subscribed from config ", observerd.getEvent());
return false;
}
log.info("the event {} is not subscribed from config ", observerd.getEvent());
return false;
} catch (Exception e) {
log.error("Exception, Error on checking subscribed events", e);
return false;
}
}
/**
* Gets the notification binding map per context.
*
* @return the notification binding map per context
*/
protected Map<String, NotificationEventsSubscribedConfig> getNotificationBindingMapPerContext() {
String context = UserUtils.getCurrent().getContext();
log.debug("Getting {} from cache map for context {}", NotificationsPlugin.PLUGIN_ID, context);
if (notificationEventsBindingMap == null) {
notificationEventsBindingMap = new LinkedHashMap<String, Map<String, NotificationEventsSubscribedConfig>>();
}
// read notification events binding subscribed in the context
Map<String, NotificationEventsSubscribedConfig> map = notificationEventsBindingMap.get(context);
return map == null ? new LinkedHashMap<String, NotificationEventsSubscribedConfig>() : map;
}
/**
* Sets the notification binding map per context.
*
* @param context the context
* @param ucd the ucd
* @param notification the notification
*/
private void setNotificationBindingMapPerContext(String context, UseCaseDescriptor ucd,
NotificationEventsSubscribedConfig notification) {
Map<String, NotificationEventsSubscribedConfig> mapNotificationConfig = notificationEventsBindingMap
.get(context);
if (mapNotificationConfig == null) {
mapNotificationConfig = new LinkedHashMap<String, NotificationEventsSubscribedConfig>();
}
mapNotificationConfig.put(ucd.getId(), notification);
notificationEventsBindingMap.put(context, mapNotificationConfig);
}
/**
* Read notifications subscribed from configuration in the UCD.
*
* @param useCaseDescriptor the use case descriptor
* @return the notification events subscribed config
* @throws Exception the exception
*/
public NotificationEventsSubscribedConfig readNotificationsSubscribedFromConfigurationInTheUCD(
UseCaseDescriptor useCaseDescriptor) throws Exception {
log.debug("Reading subscribed events from UCD");
NotificationEventsSubscribedConfig notificationMapPerContext = null;
if (useCaseDescriptor == null)
throw new Exception("Error reading UCD null found");
try {
String context = UserUtils.getCurrent().getContext();
Map<String, NotificationEventsSubscribedConfig> mapPerContext = getNotificationBindingMapPerContext();
notificationMapPerContext = mapPerContext.get(useCaseDescriptor.getId());
if (notificationMapPerContext == null) {
notificationMapPerContext = new NotificationEventsSubscribedConfig();
setNotificationBindingMapPerContext(context, useCaseDescriptor, notificationMapPerContext);
}
List<SubscribeNotificationEvent> listNotificationEventsSubscribedPerUCD = notificationMapPerContext
.getListNotificationEventSubscribed();
if (listNotificationEventsSubscribedPerUCD == null) {
listNotificationEventsSubscribedPerUCD = new ArrayList<SubscribeNotificationEvent>();
Document profileConfiguration = getConfigurationFromProfile(useCaseDescriptor).getConfiguration();
log.debug("UseCaseDescriptor Configuration is {} ", profileConfiguration);
// JSONPathWrapper schemaNavigator = new
// JSONPathWrapper(useCaseDescriptor.getSchema().toJson());
if (profileConfiguration != null) {
for (Object fsConfigObj : profileConfiguration.get(SUBSCRIBE_NOTIFICATIONS_CONFIG, List.class)) {
log.debug("Managing {}", fsConfigObj);
SubscribeNotificationEvent fsConfig = Serialization.convert(fsConfigObj,
SubscribeNotificationEvent.class);
log.debug("Converted config {}", fsConfig);
try {
Event theEventSubsribed = Serialization.convert(fsConfig.getEvent(), Event.class);
if (theEventSubsribed == null)
throw new MaterializationException(
"Invalid Field Definition path in configuration [NO MATCH] : "
+ theEventSubsribed);
} catch (Exception e) {
log.error("MaterializationException: ", e);
throw new MaterializationException(
"Invalid Event Definition path in configuration [NO MATCH Event] : "
+ Event.values());
}
listNotificationEventsSubscribedPerUCD.add(fsConfig);
}
notificationMapPerContext.setUcd(useCaseDescriptor);
notificationMapPerContext
.setListNotificationEventSubscribed(listNotificationEventsSubscribedPerUCD);
String linkToMessages = profileConfiguration.get(CONFIG_LINK_TO_NOTIFICATIONS_MESSAGES,
String.class);
Boolean enabledNotifications = profileConfiguration.get(CONFIG_ENABLED, Boolean.class);
notificationMapPerContext.setLinkToNotificationsMessages(linkToMessages);
notificationMapPerContext.setEnabled(enabledNotifications);
}
setNotificationBindingMapPerContext(context, useCaseDescriptor, notificationMapPerContext);
log.info("Events subscribed read from config {} ", notificationMapPerContext);
}
} catch (InvalidProfileException e) {
log.warn("Unable to read configuration for {} in the UCD {}", NotificationsPlugin.PLUGIN_ID,
useCaseDescriptor.getId());
} catch (Exception e) {
log.error("Unable to read configuration for " + NotificationsPlugin.PLUGIN_ID, e);
} catch (Throwable t) {
log.error("Exception, Unable to read configuration ", t);
}
return notificationMapPerContext;
}
/**
* Shutdown.
*
* @throws ShutDownException the shut down exception
*/
@Override
public void shutdown() throws ShutDownException {
// TODO Auto-generated method stub
}
/**
* Do action.
*
* @param itemObserved the item observed
*/
@Override
public void doAction(ItemObserved<Project> itemObserved) {
log.debug("doAction called...");
boolean isSubscribedEvent = checkIfSubscribedEvent(itemObserved);
log.info("Is the event {} subscribed in notification plugin configured in the UCD: {} ",
itemObserved.getEvent(), isSubscribedEvent);
if (isSubscribedEvent) {
// Map (UCD_ID, Notification)
Map<String, NotificationEventsSubscribedConfig> notificationMapPerContext = getNotificationBindingMapPerContext();
NotificationEventsSubscribedConfig subscribedConfig = notificationMapPerContext
.get(itemObserved.getUCD_Id());
boolean subscribeNotificationsEnabled = subscribedConfig.isEnabled();
log.info("subscribeNotifications enabled: {}", subscribeNotificationsEnabled);
if (subscribeNotificationsEnabled) {
String linkToFileWithMessages = subscribedConfig.getLinkToNotificationsMessages();
List<SubscribeNotificationEvent> list = subscribedConfig.getListNotificationEventSubscribed();
// Filtering list of SubscribeNotificationEvent for itemObserved Event
List<SubscribeNotificationEvent> filterList = list.stream()
.filter(sne -> sne.getEvent().equals(itemObserved.getEvent())).collect(Collectors.toList());
log.debug(linkToFileWithMessages);
NMessagesPlaceholdersSubstitutorUtil nMPlaceholdersSUtil = null;
try {
nMPlaceholdersSUtil = new NMessagesPlaceholdersSubstitutorUtil(linkToFileWithMessages);
} catch (IOException e) {
log.error("Error instancing the {}. Please check the URL {}. Returning!!",
NMessagesPlaceholdersSubstitutorUtil.class.getSimpleName(), linkToFileWithMessages);
return;
}
ManageDoActionNotification mdoact = new ManageDoActionNotification(itemObserved, nMPlaceholdersSUtil,
filterList);
mdoact.manage();
}
}
}
}

View File

@ -0,0 +1,14 @@
package org.gcube.application.cms.notifications.config;
import org.gcube.com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class ExportAsPDF {
Boolean export;
String placeholder_msg;
}

View File

@ -0,0 +1,18 @@
package org.gcube.application.cms.notifications.config;
import java.util.List;
import org.gcube.com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.gcube.com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class NotificationFor {
List<String> roles;
@JsonProperty("when")
List<NotificationWhen> when;
}

View File

@ -0,0 +1,20 @@
package org.gcube.application.cms.notifications.config;
import java.util.List;
import org.gcube.com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
/**
* Instantiates a new notification when.
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class NotificationWhen {
List<String> target_phase;
String last_invoked_step;
List<Notify> notify;
}

View File

@ -0,0 +1,20 @@
package org.gcube.application.cms.notifications.config;
import org.gcube.application.cms.notifications.NotificationGenericConstants.NOTIFICATION_TYPE;
import org.gcube.com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.gcube.com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class Notify {
NOTIFICATION_TYPE type;
Boolean send;
String placeholder_title;
String placeholder_msg;
@JsonProperty("export_as_pdf")
ExportAsPDF export_as_pdf;
}

Some files were not shown because too many files have changed in this diff Show More