14.4. Worker Plugin

14.4.1. Présentation

Un plugin est un programme informatique conçu pour ajouter des fonctionnalités à un autre logiciel (appelé logiciel hôte). En français, on utilise également les termes équivalents de « module d’extension » ou de « greffon ». Dans le cadre de VITAM, un plugin pourra être ajouté dans un ou plusieurs Workflow(s) spécifique(s) pour effectuer de nouvelles fonctionnalités sur un type d’objet prédéfini (archive unit, manifest, …)

14.4.1.1. Présentation de l’architecture VITAM

Dans VITAM, on appelle Workflow une liste d’étapes (steps) devant être exécutées sur un objet particulier.

  • Un workflow est défini dans un fichier json. Ce fichier répertorie les différentes étapes et détaille également la liste des différentes actions à effectuer.
  • Le moteur d’exécution de Workflow (processing-engine) de VITAM va donc à partir de ce fichier json, pouvoir fournir à un Worker une étape particulière à exécuter.
  • Le Worker est responsable de l’exécution d’une étape, il devra retourner le résultat de son exécution à l’engine. Il est également responsable de lancer les différentes actions à exécuter décrites dans le fichier json.
  • Une action exécutée par un Worker se fait via l’exécution d’un plugin spécifique.
  • La liste des plugins disponibles pour le Worker est inscrite dans un fichier de configuration json. Dans ce fichier, on pourra trouver la déclaration des différentes actions (une action = un plugin). Un plugin est identifié par un nom de classe ainsi qu’un fichier de configuration. Au démarrage de l’application, le Worker va charger cette liste de plugins, afin d’être capable par la suite d’exécuter le code adéquat.

Le plugin doit respecter un contrat afin qu’il puisse :

  • recevoir du worker une liste de paramètre d’entrée contenant le nécessaire pour exécuter les actions que le plugin est censée prendre en charge.
  • retourner au worker un statut d’exécution complet utilisable.

D’une façon synthétique, voici la place du plugin dans l’architecture Vitam :

../../_images/archi_plugin_globale.jpg

14.4.1.2. Définition du plugin VITAM

Un plugin au sens VITAM propose une liste d’action(s) à réaliser sur un ou plusieurs objets de même type. A l’heure actuelle, un plugin ne peut être ajouté qu’à froid. Un redémarrage de la plateforme est nécessaire pour prendre en considération l’ajout d’un nouveau plugin à un workflow existant. Au démarrage, le serveur worker charge tous les plugins ainsi que leurs fichiers de properties. La liste des plugins à charger est déclarée dans un fichier de configuration du Worker :

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
{
	"CHECK_DIGEST": {
	  "className": "fr.gouv.vitam.worker.core.plugin.CheckConformityActionPlugin",
	  "propertiesFile": "check_conformity_plugin.properties"
	},
	"CHECK_OBJECT_SIZE": {
	  "className": "fr.gouv.vitam.worker.core.plugin.CheckObjectSizeActionPlugin",
	  "propertiesFile": "check_object_size_plugin.properties"
	},
	"CHECK_ATTACHEMENT": {
	  "className": "fr.gouv.vitam.worker.core.plugin.CheckAttachementActionHandler"
	},
	"OG_OBJECTS_FORMAT_CHECK": {
	  "className": "fr.gouv.vitam.worker.core.plugin.FormatIdentificationActionPlugin",
	  "propertiesFile": "format_check_plugin.properties"
	},
	"UNIT_METADATA_INDEXATION": {
	  "className": "fr.gouv.vitam.worker.core.plugin.IndexUnitActionPlugin",
	  "propertiesFile": "index_unit_plugin.properties"
	},
	"OG_METADATA_INDEXATION": {
	  "className": "fr.gouv.vitam.worker.core.plugin.IndexObjectGroupActionPlugin",
	  "propertiesFile": "index_object_group_plugin.properties"
	},
	"OBJ_STORAGE": {
	  "className": "fr.gouv.vitam.worker.core.plugin.StoreObjectGroupActionPlugin",
	  "propertiesFile": "store_object_group_plugin.properties"
	},
	"UNITS_RULES_COMPUTE": {
	  "className": "fr.gouv.vitam.worker.core.plugin.UnitsRulesComputePlugin",
	  "propertiesFile": "units_rules_compute_plugin.properties"
	},
	"OG_METADATA_STORAGE": {
	  "className": "fr.gouv.vitam.worker.core.plugin.StoreMetaDataObjectGroupActionPlugin",
	  "propertiesFile": "store_metadata_objectGroup_plugin.properties"
	},
	"UNIT_METADATA_STORAGE": {
	  "className": "fr.gouv.vitam.worker.core.plugin.StoreMetaDataUnitActionPlugin",
	  "propertiesFile": "store_metadata_unit_plugin.properties"
	},
	"CHECK_UNIT_SCHEMA": {
	  "className": "fr.gouv.vitam.worker.core.plugin.CheckArchiveUnitSchemaActionPlugin",
	  "propertiesFile": "check_archive_unit_schema_plugin.properties"
	},
	"CHECK_ARCHIVE_UNIT_PROFILE": {
	  "className": "fr.gouv.vitam.worker.core.plugin.CheckArchiveUnitProfileActionPlugin",
	  "propertiesFile": "check_archive_unit_profile_plugin.properties"
	},
	"CHECK_CLASSIFICATION_LEVEL": {
	  "className": "fr.gouv.vitam.worker.core.plugin.CheckClassificationLevelActionPlugin",
	  "propertiesFile": "check_classification_level_plugin.properties"
	},
	"UPDATE_UNIT_RULES": {
	  "className": "fr.gouv.vitam.worker.core.plugin.ArchiveUnitRulesUpdateActionPlugin",
	  "propertiesFile": "archive_units_rules_update_plugin.properties"
	},
	"UPDATE_RUNNING_INGESTS": {
	  "className": "fr.gouv.vitam.worker.core.plugin.RunningIngestsUpdateActionPlugin",
	  "propertiesFile": "running_ingests_update_plugin.properties"
	},
	"AUDIT_CHECK_OBJECT": {
	  "className": "fr.gouv.vitam.worker.core.plugin.audit.AuditCheckObjectPlugin",
	  "propertiesFile": "audit_check_object_plugin.properties"
	},
	"LIST_OBJECTGROUP_ID": {
	  "className": "fr.gouv.vitam.worker.core.plugin.audit.AuditPreparePlugin",
	  "propertiesFile": "audit_prepare_plugin.properties"
	},
	"REPORT_AUDIT": {
	  "className": "fr.gouv.vitam.worker.core.plugin.audit.AuditFinalizePlugin",
	  "propertiesFile": "audit_finalize_plugin.properties"
	},
	"CREATE_MANIFEST": {
	  "className": "fr.gouv.vitam.worker.core.plugin.dip.CreateManifest",
	  "propertiesFile": "create_unit_secure_file_plugin.properties"
	},
	"EVIDENCE_AUDIT_LIST_OBJECT": {
	  "className": "fr.gouv.vitam.worker.core.plugin.evidence.EvidenceAuditPrepare",
	  "propertiesFile": "evidence_audit_prepare.properties"
	},
	"EVIDENCE_AUDIT_CHECK_DATABASE": {
	  "className": "fr.gouv.vitam.worker.core.plugin.evidence.EvidenceAuditDatabaseCheck",
	  "propertiesFile": "evidence_audit_database_check.properties"
	},
	"EVIDENCE_AUDIT_LIST_SECURED_FILES_TO_DOWNLOAD": {
	  "className": "fr.gouv.vitam.worker.core.plugin.evidence.EvidenceAuditListSecuredFiles",
	  "propertiesFile": "evidence_audit_list_secured_files.properties"
	},
	"EVIDENCE_AUDIT_EXTRACT_ZIP_FILE": {
	  "className": "fr.gouv.vitam.worker.core.plugin.evidence.EvidenceAuditExtractFromZip",
	  "propertiesFile": "evidence_audit_extract_from_zip.properties"
	},
	"EVIDENCE_AUDIT_PREPARE_GENERATE_REPORTS": {
	  "className": "fr.gouv.vitam.worker.core.plugin.evidence.EvidenceAuditGenerateReports",
	  "propertiesFile": "evidence_audit_generate_reports.properties"
	},
	"EVIDENCE_AUDIT_PREPARE_REPORT":{
	  "className":"fr.gouv.vitam.worker.core.plugin.evidence.EvidenceAuditPrepareReport",
	  "propertiesFile":"evidence_audit_prepare_report.properties"
	},
	"EVIDENCE_AUDIT_FINALIZE": {
	  "className": "fr.gouv.vitam.worker.core.plugin.evidence.EvidenceAuditFinalize",
	  "propertiesFile": "evidence_audit_finalize.properties"
	},
	"CORRECTIVE_AUDIT_CHECK_RESOURCE_AVAILABILITY": {
	  "className": "fr.gouv.vitam.worker.core.plugin.evidence.DataRectificationCheckResourceAvailability"
	},
	"CORRECTIVE_AUDIT": {
	  "className": "fr.gouv.vitam.worker.core.plugin.evidence.DataRectificationStep"
	},
	"CORRECTION_FINALIZE": {
	  "className": "fr.gouv.vitam.worker.core.plugin.evidence.DataCorrectionFinalize"
	},
	"MIGRATION_UNITS_LIST": {
	  "className": "fr.gouv.vitam.worker.core.plugin.migration.MigrationUnitPrepare"
	},
	"MIGRATION_UNITS": {
	  "className": "fr.gouv.vitam.worker.core.plugin.migration.MigrationUnits"
	},
	"MIGRATION_FINALIZE": {
	  "className": "fr.gouv.vitam.worker.core.plugin.migration.MigrationFinalize"
	},
	"EXPORT_CHECK_RESOURCE_AVAILABILITY": {
	  "className": "fr.gouv.vitam.worker.core.plugin.dip.ExportCheckResourceAvailability"
	},
	"PUT_BINARY_ON_WORKSPACE": {
	  "className": "fr.gouv.vitam.worker.core.plugin.dip.PutBinaryOnWorkspace",
	  "propertiesFile": "create_unit_secure_file_plugin.properties"
	},
	"STORE_MANIFEST": {
	  "className": "fr.gouv.vitam.worker.core.plugin.dip.StoreExports",
	  "propertiesFile": "create_unit_secure_file_plugin.properties"
	},
	"OBJECT_GROUP_UPDATE": {
	  "className": "fr.gouv.vitam.worker.core.plugin.UpdateObjectGroupPlugin",
	  "propertiesFile": "object_group_update.properties"
	},
	"RECLASSIFICATION_PREPARATION_CHECK_HOLD_RULES": {
	  "className": "fr.gouv.vitam.worker.core.plugin.reclassification.ReclassificationPreparationCheckHoldRulesHandler"
	},
	"UNIT_DETACHMENT": {
	  "className": "fr.gouv.vitam.worker.core.plugin.reclassification.UnitDetachmentPlugin",
	  "propertiesFile": "reclassification_unit_detachment.properties"
	},
	"UNIT_ATTACHMENT": {
	  "className": "fr.gouv.vitam.worker.core.plugin.reclassification.UnitAttachmentPlugin",
	  "propertiesFile": "reclassification_unit_attachment.properties"
	},
	"UNIT_GRAPH_COMPUTE": {
	  "className": "fr.gouv.vitam.worker.core.plugin.reclassification.UnitGraphComputePlugin",
	  "propertiesFile": "reclassification_unit_compute.properties"
	},
	"OBJECT_GROUP_GRAPH_COMPUTE": {
	  "className": "fr.gouv.vitam.worker.core.plugin.reclassification.ObjectGroupGraphComputePlugin",
	  "propertiesFile": "reclassification_object_group_compute.properties"
	},
	"MASS_UPDATE_RULES_CHECK": {
	  "className": "fr.gouv.vitam.worker.core.plugin.massprocessing.management.MassUpdateRulesCheck"
	},
	"MASS_UPDATE_CHECK": {
	  "className": "fr.gouv.vitam.worker.core.plugin.massprocessing.description.MassUpdateCheck"
	},
	"UNIT_METADATA_CHECK_CONSISTENCY": {
	  "className": "fr.gouv.vitam.worker.core.plugin.massprocessing.UnitMetadataRulesUpdateCheckConsistency",
	  "propertiesFile": "check_update_consistency.properties"
	},
	"CHECK_DISTRIBUTION_THRESHOLD": {
	  "className": "fr.gouv.vitam.worker.core.plugin.common.CheckDistributionThreshold"
	},
	"PREPARE_UPDATE_UNIT_LIST": {
	  "className": "fr.gouv.vitam.worker.core.plugin.massprocessing.PrepareUpdateUnits"
	},
	"MASS_UPDATE_UNITS": {
	  "className": "fr.gouv.vitam.worker.core.plugin.massprocessing.description.MassUpdateUnitsProcess"
	},
	"MASS_UPDATE_FINALIZE": {
	  "className": "fr.gouv.vitam.worker.core.plugin.massprocessing.MassUpdateFinalize"
	},
	"MASS_UPDATE_UNITS_RULES": {
	  "className": "fr.gouv.vitam.worker.core.plugin.massprocessing.management.MassUpdateUnitsRulesProcess"
	},
	"CHECK_QUERIES_THRESHOLD": {
	  "className": "fr.gouv.vitam.worker.core.plugin.bulkatomicupdate.CheckQueriesThreshold"
	},
	"PREPARE_BULK_ATOMIC_UPDATE_UNIT_LIST": {
	  "className": "fr.gouv.vitam.worker.core.plugin.bulkatomicupdate.PrepareBulkAtomicUpdate"
	},
	"BULK_ATOMIC_UPDATE_UNITS": {
	  "className": "fr.gouv.vitam.worker.core.plugin.bulkatomicupdate.BulkAtomicUpdateProcess"
	},
	"BULK_ATOMIC_UPDATE_FINALIZE": {
	  "className": "fr.gouv.vitam.worker.core.plugin.bulkatomicupdate.BulkAtomicUpdateFinalize"
	},
	"ELIMINATION_ANALYSIS_UNIT_INDEXATION": {
	  "className": "fr.gouv.vitam.worker.core.plugin.elimination.EliminationAnalysisUnitIndexationPlugin",
	  "propertiesFile": "elimination_analysis_unit_indexation.properties"
	},
	"ELIMINATION_ACTION_DELETE_UNIT": {
	  "className": "fr.gouv.vitam.worker.core.plugin.elimination.EliminationActionDeleteUnitPlugin",
	  "propertiesFile": "elimination_action_delete_unit.properties"
	},
	"ELIMINATION_ACTION_DELETE_OBJECT_GROUP": {
	  "className": "fr.gouv.vitam.worker.core.plugin.elimination.EliminationActionDeleteObjectGroupPlugin",
	  "propertiesFile": "elimination_action_delete_object_group.properties"
	},
	"ELIMINATION_ACTION_DETACH_OBJECT_GROUP": {
	  "className": "fr.gouv.vitam.worker.core.plugin.elimination.EliminationActionDetachObjectGroupPlugin",
	  "propertiesFile": "elimination_action_detach_object_group.properties"
	},
	"ELIMINATION_ACTION_ACCESSION_REGISTER_UPDATE": {
	  "className": "fr.gouv.vitam.worker.core.plugin.elimination.EliminationActionAccessionRegisterUpdatePlugin",
	  "propertiesFile": "elimination_action_update_accession_register.properties"
	},
	"TRANSFER_REPLY_DELETE_UNIT":{
	  "className": "fr.gouv.vitam.worker.core.plugin.transfer.reply.TransferReplyDeleteUnitPlugin",
	  "propertiesFile": "transfer_reply_delete_unit.properties"
	},
	"TRANSFER_REPLY_DELETE_OBJECT_GROUP":{
	  "className": "fr.gouv.vitam.worker.core.plugin.transfer.reply.TransferReplyDeleteObjectGroupPlugin",
	  "propertiesFile": "transfer_reply_delete_object_group.properties"
	},
	"TRANSFER_REPLY_DETACH_OBJECT_GROUP":{
	  "className": "fr.gouv.vitam.worker.core.plugin.transfer.reply.TransferReplyDetachObjectGroupPlugin",
	  "propertiesFile": "transfer_reply_detach_object_group.properties"
	},
	"TRANSFER_REPLY_ACCESSION_REGISTER_UPDATE":{
	  "className": "fr.gouv.vitam.worker.core.plugin.transfer.reply.TransferReplyAccessionRegisterUpdatePlugin",
	  "propertiesFile": "transfer_reply_update_accession_register.properties"
	},
	"TRANSFER_REPLY_DELETE_SIP":{
	  "className": "fr.gouv.vitam.worker.core.plugin.transfer.reply.TransferReplyDeleteSIP"
	},
	"PROBATIVE_VALUE_CREATE_REPORT": {
	  "className": "fr.gouv.vitam.worker.core.plugin.probativevalue.ProbativeCreateReport"
	},
	"PROBATIVE_VALUE_CREATE_DISTRIBUTION_FILE": {
	  "className": "fr.gouv.vitam.worker.core.plugin.probativevalue.ProbativeCreateDistributionFile"
	},
	"PROBATIVE_VALUE_CREATE_PROBATIVE_REPORT_ENTRY": {
	  "className": "fr.gouv.vitam.worker.core.plugin.probativevalue.ProbativeCreateReportEntry"
	},
	"PREPARE_UNIT_LFC_TRACEABILITY": {
	  "className": "fr.gouv.vitam.worker.core.plugin.lfc_traceability.PrepareUnitLfcTraceabilityActionPlugin",
	  "propertiesFile": "unit_lfc_traceability_preparation_plugin.properties"
	},
	"BUILD_UNIT_LFC_TRACEABILITY": {
	  "className": "fr.gouv.vitam.worker.core.plugin.lfc_traceability.BuildUnitTraceabilityActionPlugin",
	  "propertiesFile": "unit_lfc_traceability_build_plugin.properties"
	},
	"GENERATE_UNIT_LFC_TRACEABILITY": {
	  "className": "fr.gouv.vitam.worker.core.plugin.lfc_traceability.GenerateUnitLifecycleTraceabilityActionPlugin",
	  "propertiesFile": "unit_lfc_traceability_generation_plugin.properties"
	},
	"FINALIZE_UNIT_LFC_TRACEABILITY": {
	  "className": "fr.gouv.vitam.worker.core.plugin.lfc_traceability.FinalizeUnitLifecycleTraceabilityActionPlugin",
	  "propertiesFile": "unit_lfc_traceability_finalization_plugin.properties"
	},
	"PREPARE_OG_LFC_TRACEABILITY": {
	  "className": "fr.gouv.vitam.worker.core.plugin.lfc_traceability.PrepareObjectGroupLfcTraceabilityActionPlugin",
	  "propertiesFile": "object_group_lfc_traceability_preparation_plugin.properties"
	},
	"BUILD_OG_LFC_TRACEABILITY": {
	  "className": "fr.gouv.vitam.worker.core.plugin.lfc_traceability.BuildObjectGroupTraceabilityActionPlugin",
	  "propertiesFile": "object_group_lfc_traceability_build_plugin.properties"
	},
	"GENERATE_OG_LFC_TRACEABILITY": {
	  "className": "fr.gouv.vitam.worker.core.plugin.lfc_traceability.GenerateObjectGroupLifecycleTraceabilityActionPlugin",
	  "propertiesFile": "object_group_lfc_traceability_generation_plugin.properties"
	},
	"FINALIZE_OG_LFC_TRACEABILITY": {
	  "className": "fr.gouv.vitam.worker.core.plugin.lfc_traceability.FinalizeObjectGroupLifecycleTraceabilityActionPlugin",
	  "propertiesFile": "object_group_lfc_traceability_finalization_plugin.properties"
	},
	"TRACEABILITY_LINKED_CHECK_PREPARE": {
	  "className": "fr.gouv.vitam.worker.core.plugin.traceability.TraceabilityLinkedCheckPreparePlugin"
	},
	"RETRIEVE_SECURE_TRACEABILITY_DATA_FILE": {
	  "className": "fr.gouv.vitam.worker.core.plugin.traceability.RetrieveSecureTraceabilityDataFilePlugin"
	},
	"CHECKS_SECURE_TRACEABILITY_DATA_HASHES": {
	  "className": "fr.gouv.vitam.worker.core.plugin.traceability.ChecksSecureTraceabilityDataHashesPlugin"
	},
	"EXTRACT_SECURE_TRACEABILITY_DATA_FILE": {
	  "className": "fr.gouv.vitam.worker.core.plugin.traceability.ExtractSecureTraceabilityDataFilePlugin"
	},
	"CHECK_MERKLE_TREE": {
	  "className": "fr.gouv.vitam.worker.core.plugin.traceability.VerifyMerkleTreeActionHandler"
	},
	"VERIFY_TIMESTAMP": {
	  "className": "fr.gouv.vitam.worker.core.plugin.traceability.VerifyTimeStampActionHandler"
	},
	"CHECKS_SECURE_TRACEABILITY_DATA_STORAGELOG": {
	  "className": "fr.gouv.vitam.worker.core.plugin.traceability.ChecksSecureTraceabilityDataStoragelogPlugin"
	},
	"TRACEABILITY_FINALIZATION": {
	  "className": "fr.gouv.vitam.worker.core.plugin.traceability.TraceabilityFinalizationPlugin"
	},
	"PRESERVATION_PREPARATION": {
	  "className": "fr.gouv.vitam.worker.core.plugin.preservation.PreservationPreparationPlugin"
	},
	"PRESERVATION_CHECK_RESOURCE_AVAILABILITY": {
	  "className": "fr.gouv.vitam.worker.core.plugin.preservation.PreservationCheckResourceAvailability"
	},
	"PRESERVATION_ACTION": {
	  "className": "fr.gouv.vitam.worker.core.plugin.preservation.PreservationActionPlugin"
	},
	"PRESERVATION_EXTRACTION_AU": {
	  "className": "fr.gouv.vitam.worker.core.plugin.preservation.PreservationExtractionAUPlugin"
	},
	"PRESERVATION_FINALIZATION": {
	  "className": "fr.gouv.vitam.worker.core.plugin.preservation.PreservationFinalizationPlugin"
	},
	"PRESERVATION_SIEGFRIED_IDENTIFICATION": {
	  "className": "fr.gouv.vitam.worker.core.plugin.preservation.PreservationSiegfriedPlugin"
	},
	"PRESERVATION_TESSERACT_SPLIT_TEXT_CONTENT": {
	  "className": "fr.gouv.vitam.worker.core.plugin.preservation.PreservationTesseractPlugin"
	},
	"PRESERVATION_OBJECTGROUP_METADATA_SECURITY_CHECKS": {
	  "className": "fr.gouv.vitam.worker.core.plugin.preservation.PreservationObjectGroupMetadataSecurityChecks"
	},
	"PRESERVATION_UNIT_METADATA_SECURITY_CHECKS": {
	  "className": "fr.gouv.vitam.worker.core.plugin.preservation.PreservationUnitMetadataSecurityChecks"
	},
	"PRESERVATION_PREPARATION_INSERTION_AU_METADATA": {
	  "className": "fr.gouv.vitam.worker.core.plugin.preservation.PreservationPreparationInsertionAuMetadata"
	},
	"PRESERVATION_INSERTION_AU_METADATA": {
	  "className": "fr.gouv.vitam.worker.core.plugin.preservation.PreservationInsertionAuMetadata"
	},
	"PRESERVATION_BINARY_HASH": {
	  "className": "fr.gouv.vitam.worker.core.plugin.preservation.PreservationGenerateBinaryHash"
	},
	"PRESERVATION_STORAGE_BINARY": {
	  "className": "fr.gouv.vitam.worker.core.plugin.preservation.PreservationStorageBinaryPlugin"
	},
	"PRESERVATION_INDEXATION_METADATA": {
	  "className": "fr.gouv.vitam.worker.core.plugin.preservation.PreservationUpdateObjectGroupPlugin"
	},
	"PRESERVATION_STORAGE_METADATA_LFC": {
	  "className": "fr.gouv.vitam.worker.core.plugin.preservation.PreservationStorageMetadataAndLfc"
	},
	"HELLO_WORLD_PLUGIN": {
	  "className": "fr.vitam.plugin.custom.HelloWorldPlugin",
	  "propertiesFile": "hello_world_plugin.properties",
	  "jarName": "hello-world-plugin-1.14.0-SNAPSHOT.jar"
	},
	"COMPUTE_INHERITED_RULES_PREPARATION": {
	  "className": "fr.gouv.vitam.worker.core.plugin.computeinheritedrules.ComputeInheritedRulesPreparationPlugin"
	},
	"COMPUTE_INHERITED_RULES_ACTION": {
	  "className": "fr.gouv.vitam.worker.core.plugin.computeinheritedrules.ComputeInheritedRulesActionPlugin"
	},
	"COMPUTE_INHERITED_RULES_FINALIZATION": {
	  "className": "fr.gouv.vitam.worker.core.plugin.computeinheritedrules.ComputeInheritedRulesFinalizationPlugin"
	},
	"COMPUTE_INHERITED_RULES_PROGENY_IDENTIFIER": {
	  "className": "fr.gouv.vitam.worker.core.plugin.computeinheritedrules.ComputeInheritedRuleProgenyIdentifierPlugin"
	},
	"COMPUTE_INHERITED_RULES_INVALIDATOR": {
	  "className": "fr.gouv.vitam.worker.core.plugin.computeinheritedrules.ComputeInheritedRulesInvalidatorPlugin"
	},
	"COMPUTE_INHERITED_RULES_DELETE": {
	  "className": "fr.gouv.vitam.worker.core.plugin.computeinheritedrules.ComputeInheritedRulesDeletePlugin"
	},
	"SAVE_ARCHIVAL_TRANSFER_REPLY": {
	  "className": "fr.gouv.vitam.worker.core.plugin.transfer.reply.SaveAtrPlugin"
	},
	"CHECK_ATR_AND_ADD_IT_TO_WORKSPACE": {
	  "className": "fr.gouv.vitam.worker.core.plugin.transfer.reply.CheckAtrAndAddItToWorkspacePlugin"
	},
	"VERIFY_ARCHIVAL_TRANSFER_REPLY": {
	  "className": "fr.gouv.vitam.worker.core.plugin.transfer.reply.VerifyAtrPlugin"
	},
	"TRANSFER_REPLY_FINALIZATION": {
	  "className": "fr.gouv.vitam.worker.core.plugin.transfer.reply.TransferReplyFinalizationPlugin"
	},
	"PREPARE_STORAGE_STRATEGIES": {
	  "className": "fr.gouv.vitam.worker.core.plugin.PrepareStorageStrategiesPlugin"
	},
	"INGEST_CLEANUP_REQUEST_VALIDATION": {
	  "className": "fr.gouv.vitam.worker.core.plugin.ingestcleanup.IngestCleanupRequestValidationPlugin"
	},
	"INGEST_CLEANUP_ELIGIBILITY_VALIDATION": {
	  "className": "fr.gouv.vitam.worker.core.plugin.ingestcleanup.IngestCleanupEligibilityValidationPlugin"
	},
	"INGEST_CLEANUP_PREPARATION": {
	  "className": "fr.gouv.vitam.worker.core.plugin.ingestcleanup.IngestCleanupPreparationPlugin"
	},
	"INGEST_CLEANUP_DELETE_UNIT": {
	  "className": "fr.gouv.vitam.worker.core.plugin.ingestcleanup.IngestCleanupDeleteUnitPlugin"
	},
	"INGEST_CLEANUP_DELETE_OBJECT_GROUP": {
	  "className": "fr.gouv.vitam.worker.core.plugin.ingestcleanup.IngestCleanupDeleteObjectGroupPlugin"
	},
	"INGEST_CLEANUP_ACCESSION_REGISTER_UPDATE": {
	  "className": "fr.gouv.vitam.worker.core.plugin.ingestcleanup.IngestCleanupAccessionRegisterUpdatePlugin"
	},
	"INGEST_CLEANUP_FINALIZATION": {
	  "className": "fr.gouv.vitam.worker.core.plugin.ingestcleanup.IngestCleanupFinalizationPlugin"
	},
	"REVERT_CHECK": {
	  "className": "fr.gouv.vitam.worker.core.plugin.revertupdate.RevertUpdateUnitCheckPlugin"
	},
	"REVERT_UPDATE_UNITS": {
	  "className": "fr.gouv.vitam.worker.core.plugin.revertupdate.RevertUpdateUnitPlugin"
	},
	"REVERT_UPDATE_FINALIZE": {
	  "className": "fr.gouv.vitam.worker.core.plugin.revertupdate.RevertUpdateUnitFinalizePlugin"
	},
	"DELETE_GOT_VERSIONS_PREPARATION": {
	  "className": "fr.gouv.vitam.worker.core.plugin.deleteGotVersions.handlers.DeleteGotVersionsPreparationPlugin"
	},
	"DELETE_GOT_VERSIONS_ACTION": {
	  "className": "fr.gouv.vitam.worker.core.plugin.deleteGotVersions.handlers.DeleteGotVersionsActionPlugin"
	},
	"STORE_METADATA_AND_LFC_WORKSPACE": {
	  "className": "fr.gouv.vitam.worker.core.plugin.deleteGotVersions.handlers.DeleteGotVersionsStoreMetadataAndLfcPlugin"
	},
	"DELETE_GOT_VERSIONS_STORAGE": {
	  "className": "fr.gouv.vitam.worker.core.plugin.deleteGotVersions.handlers.DeleteGotVersionsStoragePlugin"
	},
	"DELETE_GOT_VERSIONS_ACCESSION_REGISTER_UPDATE": {
	  "className": "fr.gouv.vitam.worker.core.plugin.deleteGotVersions.handlers.DeleteGotVersionsAccessionRegisterUpdatePlugin"
	},
	"DELETE_GOT_VERSIONS_FINALIZATION": {
	  "className": "fr.gouv.vitam.worker.core.plugin.deleteGotVersions.handlers.DeleteGotVersionsFinalizationPlugin"
	}
  }
  

Le plugin doit implémenter la classe ActionHandler et doit surcharger soit la méthode execute() pour un traitement unitaire, soit la méthode executeAll() pour un traitemement de masse. Un plugin prend en paramètres : - WorkerParameters : objet contenant une liste de paramètres permettant d’exécuter des actions variées. Voici une liste non exhaustive des paramètres : url du service workspace, nom de l’étape en cours, container sur lequel l’action est exécutée, identifiant du process, url du service metadata, l’id de l’objet sur lequel on veut effectuer un traitement, etc… - HandlerIO qui a pour charge d’assurer la liaison avec le Workspace et la mémoire entre les différents traitements. Il permet de passer une liste d’input permettant le traitement du plugin.

La méthode doit retourner un objet de type ItemStatus, qui sera détaillé plus en détail dans un paragraphe dédié.

De manière synthétique, voici le fonctionnement du plugin VITAM.

../../_images/plugin.png

14.4.2. Gestion des entrants du plugin

14.4.2.1. WorkerParameters

Les paramètres WorkerParameters sont des paramètres permettant aux différents plugins d’exécuter leurs différentes actions.

Actuellement 5 paramètres sont obligatoires pour tous les workers : - urlMetadata afin d’intialiser le client metadata - urlWorkspace afin d’initialiser le client workspace - objectName le nom de l’object lorsque l’on boucle sur une liste - currentStep le nom de l’étape - containerName l’identifiant du container

Les autres paramètres sont les suivants : - processId : id du process en cours d’exécution. Le pattern du processId est de la forme : {CONTAINER_NAME}_{WORKFLOW_ID}_{STEP_RANK_IN_THE_WORKFLOW}_{STEP_NAME} - stepUniqId : id de l’étape en cours d’exécution - objectId : id de l’objet sur lequel l’action va s’exécuter une action - workerGUID : id du worker ayant lancé l’action - metadataRequest : indique si l’action doit utiliser le module metadata - workflowStatusKo : si le worklow en cours a un statut KO ou FATAL, il contient son statut.

Pour récupérer un paramètre, il suffit d’appliquer :

@Override
public ItemStatus execute(WorkerParameters params, HandlerIO actionDefinition) {

  // on récupère le nom de l'objet sur lequel l'action va être effectuée
  final String objectName = params.getObjectName();
  // on récupère le nom de l'étape en cours
  final String currentStep = params.getCurrentStep();
  // il est possible de récupérer la même information différemment :
  final String currentStepBis = params.getParameterValue(WorkerParameterName.currentStep);
  // TODO : maintenant, réalisons l'action
  // on retourne un ItemStatus
  return new ItemStatus();
}

14.4.2.2. HandlerIO

Le HandlerIO a pour charge d’assurer la liaison avec le Workspace et la mémoire entre les différentes actions d’un step, exécutées dans différents plugins. Dans un workflow, est spécifiée une liste d’objets (de fichiers, de valeurs, etc…) qui en complément des WorkerParameters peuvent être transmis à travers le HandlerIO. Il revient au HandlerIO d’assurer la livraison de ces différents objets.

Dans un workflow, nous avons donc des listes d’inputs et d’outputs. Ces listes sont configurées dans un fichier json de configuration Les inputs peuvent être utilisés par les différents plugins (selon la spécification dans la configuration du workflow.

Voici un json d’exemple de configuration de workflow :

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
{
  "id": "DEFAULT_WORKFLOW",
  "name": "Default Ingest Workflow",
  "identifier": "PROCESS_SIP_UNITARY",
  "typeProc": "INGEST",
  "comment": "Default Ingest Workflow V6",
  "steps": [
    {
      "workerGroupId": "DefaultWorker",
      "stepName": "STP_SANITY_CHECK_SIP",
      "behavior": "BLOCKING",
      "distribution": {
        "kind": "REF"
      },
      "waitFor": "sanityCheckResult.json",
      "actions": [
        {
          "action": {
            "actionKey": "SANITY_CHECK_SIP",
            "behavior": "BLOCKING",
            "in": {
              "name": "paramToCheck",
              "uri": "VALUE:antivirusParam"
            }
          }
        },
        {
          "action": {
            "actionKey": "CHECK_CONTAINER",
            "behavior": "BLOCKING",
            "in": {
              "name": "paramToCheck",
              "uri": "VALUE:fileFormatParam"
            }
          }
        },
        {
          "action": {
            "actionKey": "MANIFEST_FILE_NAME_CHECK",
            "behavior": "BLOCKING",
            "in": {
              "name": "paramToCheck",
              "uri": "VALUE:fileNameManifestParam"
            }
          }
        },
        {
          "action": {
            "actionKey": "MANIFEST_DIGEST_CHECK",
            "behavior": "BLOCKING",
            "in": {
              "name": "paramToCheck",
              "uri": "VALUE:digestManifestParam"
            }
          }
        }
      ]
    },
    {
      "workerGroupId": "DefaultWorker",
      "stepName": "STP_UPLOAD_SIP",
      "behavior": "BLOCKING",
      "distribution": {
        "kind": "REF"
      },
      "waitFor": "stpUploadResult.json",
      "actions": [
        {
          "action": {
            "actionKey": "UPLOAD_SIP",
            "behavior": "BLOCKING"
          }
        }
      ]
    },
    {
      "workerGroupId": "DefaultWorker",
      "stepName": "STP_INGEST_CONTROL_SIP",
      "behavior": "BLOCKING",
      "distribution": {
        "kind": "REF",
        "element": "SIP/manifest.xml"
      },
      "actions": [
        {
          "action": {
            "actionKey": "CHECK_SEDA",
            "behavior": "BLOCKING"
          }
        },
        {
          "action": {
            "actionKey": "CHECK_HEADER",
            "behavior": "BLOCKING",
            "in": [
              {
                "name": "checkOriginatingAgency",
                "uri": "VALUE:true"
              },
              {
                "name": "checkProfile",
                "uri": "VALUE:true"
              }
            ],
            "out": [
              {
                "name": "contracts.json",
                "uri": "WORKSPACE:referential/contracts.json"
              }
            ]
          }
        },
        {
          "action": {
            "actionKey": "PREPARE_STORAGE_INFO",
            "behavior": "BLOCKING",
            "in": [
              {
                "name": "contracts.json",
                "uri": "WORKSPACE:referential/contracts.json"
              }
            ],
            "out": [
              {
                "name": "storageInfo.json",
                "uri": "WORKSPACE:StorageInfo/storageInfo.json"
              }
            ]
          }
        },
        {
          "action": {
            "actionKey": "CHECK_DATAOBJECTPACKAGE",
            "behavior": "BLOCKING",
            "in": [
              {
                "name": "checkNoObject",
                "uri": "VALUE:false"
              },
              {
                "name": "UnitType",
                "uri": "VALUE:INGEST"
              },
              {
                "name": "storageInfo.json",
                "uri": "WORKSPACE:StorageInfo/storageInfo.json"
              },
              {
                "name": "contracts.json",
                "uri": "WORKSPACE:referential/contracts.json"
              }
            ],
            "out": [
              {
                "name": "unitsLevel.file",
                "uri": "WORKSPACE:UnitsLevel/ingestLevelStack.json"
              },
              {
                "name": "mapsDOtoOG.file",
                "uri": "WORKSPACE:Maps/DATA_OBJECT_TO_OBJECT_GROUP_ID_MAP.json"
              },
              {
                "name": "mapsDO.file",
                "uri": "WORKSPACE:Maps/DATA_OBJECT_ID_TO_GUID_MAP.json"
              },
              {
                "name": "mapsObjectGroup.file",
                "uri": "WORKSPACE:Maps/OBJECT_GROUP_ID_TO_GUID_MAP.json"
              },
              {
                "name": "mapsObjectGroup.file",
                "uri": "MEMORY:MapsMemory/OG_TO_ARCHIVE_ID_MAP.json"
              },
              {
                "name": "mapsDOtoVersionBDO.file",
                "uri": "WORKSPACE:Maps/DATA_OBJECT_ID_TO_DATA_OBJECT_DETAIL_MAP.json"
              },
              {
                "name": "mapsUnits.file",
                "uri": "WORKSPACE:Maps/ARCHIVE_ID_TO_GUID_MAP.json"
              },
              {
                "name": "globalSEDAParameters.file",
                "uri": "WORKSPACE:ATR/globalSEDAParameters.json"
              },
              {
                "name": "mapsObjectGroup.file",
                "uri": "MEMORY:MapsMemory/OBJECT_GROUP_ID_TO_GUID_MAP.json"
              },
              {
                "name": "existingObjectGroup.file",
                "uri": "WORKSPACE:UpdateObjectGroup/existing_object_group.json"
              },
              {
                "name": "mapsGuid.file",
                "uri": "WORKSPACE:Maps/GUID_TO_ARCHIVE_ID_MAP.json"
              },
              {
                "name": "ontology.file",
                "uri": "WORKSPACE:Ontology/ontology.json"
              },
              {
                "name": "mapsExisitingGotToNewGotForAttachment.file",
                "uri": "WORKSPACE:Maps/EXISTING_GOT_TO_NEW_GOT_GUID_FOR_ATTACHMENT_MAP.json"
              },
              {
                "name": "mapsExisitingUnitsForAttachment.file",
                "uri": "WORKSPACE:Maps/EXISTING_UNITS_GUID_FOR_ATTACHMENT_MAP.json"
              },
              {
                "name": "mapsExisitingGotsForAttachment.file",
                "uri": "WORKSPACE:Maps/EXISTING_GOTS_GUID_FOR_ATTACHMENT_MAP.json"
              }
            ]
          }
        },
        {
          "action": {
            "actionKey": "CHECK_ATTACHEMENT",
            "behavior": "BLOCKING",
            "in": [
              {
                "name": "mapsExisitingGotsForAttachment.file",
                "uri": "WORKSPACE:Maps/EXISTING_GOTS_GUID_FOR_ATTACHMENT_MAP.json"
              },
              {
                "name": "mapsExisitingUnitsForAttachment.file",
                "uri": "WORKSPACE:Maps/EXISTING_UNITS_GUID_FOR_ATTACHMENT_MAP.json"
              }
            ]
          }
        }
      ]
    },
    {
      "workerGroupId": "DefaultWorker",
      "stepName": "STP_OG_CHECK_AND_TRANSFORME",
      "behavior": "BLOCKING",
      "distribution": {
        "kind": "LIST_IN_DIRECTORY",
        "element": "ObjectGroup",
        "type": "ObjectGroup"
      },
      "actions": [
        {
          "action": {
            "actionKey": "CHECK_DIGEST",
            "behavior": "BLOCKING",
            "in": [
              {
                "name": "algo",
                "uri": "VALUE:SHA-512"
              }
            ],
            "out": [
              {
                "name": "groupObject",
                "uri": "MEMORY:groupObjectId"
              }
            ]
          }
        },
        {
          "action": {
            "actionKey": "CHECK_OBJECT_SIZE",
            "behavior": "BLOCKING",
            "out": [
              {
                "name": "groupObject",
                "uri": "MEMORY:groupObjectId"
              }
            ]
          }
        },
        {
          "action": {
            "actionKey": "OG_OBJECTS_FORMAT_CHECK",
            "behavior": "BLOCKING",
            "in": [
              {
                "name": "groupObject",
                "uri": "MEMORY:groupObjectId"
              },
              {
                "name": "contracts.json",
                "uri": "WORKSPACE:referential/contracts.json"
              }
            ]
          }
        }
      ]
    },
    {
      "workerGroupId": "DefaultWorker",
      "stepName": "STP_UNIT_CHECK_AND_PROCESS",
      "behavior": "BLOCKING",
      "distribution": {
        "kind": "LIST_ORDERING_IN_FILE",
        "type": "Units",
        "element": "UnitsLevel/ingestLevelStack.json"
      },
      "actions": [
        {
          "action": {
            "actionKey": "CHECK_UNIT_SCHEMA",
            "behavior": "BLOCKING",
            "in": [
              {
                "name": "ontology.file",
                "uri": "WORKSPACE:Ontology/ontology.json"
              }
            ],
            "out": [
              {
                "name": "unit",
                "uri": "MEMORY:unitId"
              }
            ]
          }
        },
        {
          "action": {
            "actionKey": "CHECK_ARCHIVE_UNIT_PROFILE",
            "behavior": "NOBLOCKING",
            "in": [
              {
                "name": "mapsGuid.file",
                "uri": "WORKSPACE:Maps/GUID_TO_ARCHIVE_ID_MAP.json"
              }
            ],
            "out": [
              {
                "name": "unit",
                "uri": "MEMORY:unitId"
              }
            ]
          }
        },
        {
          "action": {
            "actionKey": "CHECK_CLASSIFICATION_LEVEL",
            "behavior": "BLOCKING",
            "in": [
              {
                "name": "unit",
                "uri": "MEMORY:unitId"
              }
            ]
          }
        },
        {
          "action": {
            "actionKey": "UNITS_RULES_COMPUTE",
            "behavior": "BLOCKING",
            "in": [
              {
                "name": "unit",
                "uri": "MEMORY:unitId"
              }
            ]
          }
        }
      ]
    },
    {
      "workerGroupId": "DefaultWorker",
      "stepName": "STP_STORAGE_AVAILABILITY_CHECK",
      "behavior": "BLOCKING",
      "distribution": {
        "kind": "REF",
        "element": "SIP/manifest.xml"
      },
      "actions": [
        {
          "action": {
            "actionKey": "STORAGE_AVAILABILITY_CHECK",
            "behavior": "BLOCKING",
            "in": [
              {
                "name": "contracts.json",
                "uri": "WORKSPACE:referential/contracts.json"
              }
            ]
          }
        }
      ]
    },
    {
      "workerGroupId": "DefaultWorker",
      "stepName": "STP_OBJ_STORING",
      "behavior": "BLOCKING",
      "distribution": {
        "kind": "LIST_IN_DIRECTORY",
        "element": "ObjectGroup",
        "type": "ObjectGroup",
        "bulkSize": 1000
      },
      "actions": [
        {
          "action": {
            "actionKey": "OBJ_STORAGE",
            "behavior": "BLOCKING",
            "out": [
              {
                "name": "groupObject",
                "uri": "MEMORY:groupObjectId"
              }
            ]
          }
        },
        {
          "action": {
            "actionKey": "OG_METADATA_INDEXATION",
            "behavior": "BLOCKING",
            "in": [
              {
                "name": "groupObject",
                "uri": "MEMORY:groupObjectId"
              }
            ]
          }
        }
      ]
    },
    {
      "workerGroupId": "DefaultWorker",
      "stepName": "STP_UNIT_METADATA",
      "behavior": "BLOCKING",
      "distribution": {
        "kind": "LIST_ORDERING_IN_FILE",
        "type": "Units",
        "element": "UnitsLevel/ingestLevelStack.json",
        "bulkSize": 1000
      },
      "actions": [
        {
          "action": {
            "actionKey": "UNIT_METADATA_INDEXATION",
            "behavior": "BLOCKING",
            "in": [
              {
                "name": "globalSEDAParameters.file",
                "uri": "WORKSPACE:ATR/globalSEDAParameters.json"
              }
            ]
          }
        }
      ]
    },
    {
      "workerGroupId": "DefaultWorker",
      "stepName": "STP_OG_STORING",
      "behavior": "BLOCKING",
      "distribution": {
        "kind": "LIST_IN_DIRECTORY",
        "element": "ObjectGroup",
        "type": "ObjectGroup",
        "bulkSize": 128
      },
      "actions": [
        {
          "action": {
            "actionKey": "COMMIT_LIFE_CYCLE_OBJECT_GROUP",
            "behavior": "BLOCKING"
          }
        },
        {
          "action": {
            "actionKey": "OG_METADATA_STORAGE",
            "behavior": "BLOCKING",
            "lifecycleLog": "DISABLED"
          }
        }
      ]
    },
    {
      "workerGroupId": "DefaultWorker",
      "stepName": "STP_UNIT_STORING",
      "behavior": "BLOCKING",
      "distribution": {
        "kind": "LIST_ORDERING_IN_FILE",
        "type": "Units",
        "element": "UnitsLevel/ingestLevelStack.json",
        "bulkSize": 128
      },
      "actions": [
        {
          "action": {
            "actionKey": "COMMIT_LIFE_CYCLE_UNIT",
            "behavior": "BLOCKING"
          }
        },
        {
          "action": {
            "actionKey": "UNIT_METADATA_STORAGE",
            "behavior": "BLOCKING",
            "lifecycleLog": "DISABLED"
          }
        }
      ]
    },
    {
      "workerGroupId": "DefaultWorker",
      "stepName": "STP_UPDATE_OBJECT_GROUP",
      "behavior": "BLOCKING",
      "distribution": {
        "kind": "LIST_IN_FILE",
        "element": "UpdateObjectGroup/existing_object_group.json",
        "type": "ObjectGroup",
        "statusOnEmptyDistribution": "OK",
        "bulkSize": 128
      },
      "actions": [
        {
          "action": {
            "actionKey": "OBJECT_GROUP_UPDATE",
            "behavior": "BLOCKING",
            "lifecycleLog": "FLUSH_LFC"
          }
        },
        {
          "action": {
            "actionKey": "COMMIT_LIFE_CYCLE_OBJECT_GROUP",
            "behavior": "BLOCKING"
          }
        },
        {
          "action": {
            "actionKey": "OG_METADATA_STORAGE",
            "behavior": "BLOCKING",
            "lifecycleLog": "DISABLED"
          }
        }
      ]
    },
    {
      "workerGroupId": "DefaultWorker",
      "stepName": "STP_ACCESSION_REGISTRATION",
      "behavior": "BLOCKING",
      "distribution": {
        "kind": "REF",
        "element": "SIP/manifest.xml"
      },
      "actions": [
        {
          "action": {
            "actionKey": "ACCESSION_REGISTRATION",
            "behavior": "BLOCKING",
            "in": [
              {
                "name": "globalSEDAParameters.file",
                "uri": "WORKSPACE:ATR/globalSEDAParameters.json"
              }
            ]
          }
        }
      ]
    },
    {
      "workerGroupId": "DefaultWorker",
      "stepName": "STP_INGEST_FINALISATION",
      "behavior": "FINALLY",
      "distribution": {
        "kind": "REF",
        "element": "SIP/manifest.xml"
      },
      "actions": [
        {
          "action": {
            "actionKey": "ATR_NOTIFICATION",
            "behavior": "NOBLOCKING",
            "in": [
              {
                "name": "mapsUnits.file",
                "uri": "WORKSPACE:Maps/ARCHIVE_ID_TO_GUID_MAP.json",
                "optional": true
              },
              {
                "name": "mapsDO.file",
                "uri": "WORKSPACE:Maps/DATA_OBJECT_ID_TO_GUID_MAP.json",
                "optional": true
              },
              {
                "name": "mapsDOtoOG.file",
                "uri": "WORKSPACE:Maps/DATA_OBJECT_TO_OBJECT_GROUP_ID_MAP.json",
                "optional": true
              },
              {
                "name": "mapsDOtoVersionBDO.file",
                "uri": "WORKSPACE:Maps/DATA_OBJECT_ID_TO_DATA_OBJECT_DETAIL_MAP.json",
                "optional": true
              },
              {
                "name": "globalSEDAParameters.file",
                "uri": "WORKSPACE:ATR/globalSEDAParameters.json",
                "optional": true
              },
              {
                "name": "mapsOG.file",
                "uri": "WORKSPACE:Maps/OBJECT_GROUP_ID_TO_GUID_MAP.json",
                "optional": true
              },
              {
                "name": "mapsExisitingGotToNewGotForAttachment.file",
                "uri": "WORKSPACE:Maps/EXISTING_GOT_TO_NEW_GOT_GUID_FOR_ATTACHMENT_MAP.json",
                "optional": true
              }
            ],
            "out": [
              {
                "name": "atr.file",
                "uri": "WORKSPACE:ATR/responseReply.xml"
              }
            ]
          }
        },
        {
          "action": {
            "actionKey": "ROLL_BACK",
            "behavior": "BLOCKING"
          }
        }
      ]
    }
  ]
}

Voici un exemple, de ce que l’on pourrait trouver au seun d’une action en terme d’input et d’output :

"action": {
 "actionKey": "CHECK_CONSISTENCY",
 "behavior": "NOBLOCKING",
 "in": [
   {
     "name": "mapsDOtoOG.file",
     "uri": "MEMORY:MapsMemory/OG_TO_ARCHIVE_ID_MAP.json"
   },
   {
     "name": "mapsObjectGroup.file",
     "uri": "MEMORY:MapsMemory/OBJECT_GROUP_ID_TO_GUID_MAP.json"
   },
   {
     "name": "algo",
     "uri": "VALUE:SHA-512"
   }
 ],
 "out": [
   {
     "name": "atr.file",
     "uri": "WORKSPACE:ATR/responseReply.xml"
   }
 ]
}

On peut noter qu’il existe plusieurs types d’inputs qui sont identifiés par :

  • un nom (name) utilisé pour référencer cet élément entre différents handlers d’une même étape

  • une cible (uri) comportant un schema (WORKSPACE, MEMORY, VALUE) et un path :

    • WORKSPACE:path -> indique le chemin relatif sur le workspace
    • MEMORY:path -> indique le nom de la clef de valeur
    • VALUE:path -> indique la valeur statique en entrée

On peut noter qu’il existe plusieurs types d’outputs qui sont identifiés par :

Il existe plusieurs manières de récupérer les différents objets dans les plugins, faisons un tour d’horizon.

  • un nom (name) utilisé pour référencer cet élément entre différents handlers d’une même étape

  • une cible (uri) comportant un schema (WORKSPACE, MEMORY) et un path :

    • WORKSPACE:path indique le chemin relatif sur le workspace
    • MEMORY:path indique le nom de la clef de valeur

Chaque plugin peut donc accéder aux différents inputs ou peut stocker différents outputs dès lors qu’ils sont bien déclarés dans la configuration.

14.4.2.2.1. Récupérer un Json sur le workspace

// récupérons sur le workspace un json répresenant un objet sur lequel l'action est en cours
final JsonNode jsonOG = handlerIO.getJsonFromWorkspace(
                 IngestWorkflowConstants.OBJECT_GROUP_FOLDER + "/" + params.getObjectName());

14.4.2.2.2. Transférer un fichier sur le Workspace

// transférons sur le workspace un inputstream
InputStreamFromOutputStream<String> isos = new InputStreamFromOutputStream<String>();
handlerIO.transferInputStreamToWorkspace(
                         IngestWorkflowConstants.OBJECT_GROUP_FOLDER + "/" + params.getObjectName(),
                         isos);
// transfer json to workspace
JsonNode jsonNode;
// TODO : construction du jsonNode
handlerIO.transferJsonToWorkspace(StorageCollectionType.OBJECTGROUPS.getCollectionName(),
         params.getObjectName(),
         jsonNode, true);

14.4.2.2.3. Récupérer un objet spécifique déterminé dans le workflow

Soit la déclaration d’inputs :

"in": [
 {
   "name": "testValue",
   "uri": "VALUE:SHA-512"
 },
 {
   "name": "testFile.file",
   "uri": "WORKSPACE:Maps/testFile.json"
 },
 {[...]}
]

Si l’on souhaite réaliser les différentes opérations :

  • Récupérer un objet « VALUE » :
 // récupérons le fichier défini de rang 0 , en tant que VALUE dans le workflow
 final DigestType digestTypeInput = DigestType.fromValue((String) handlerIO.getInput(0));


- Récupérer un objet "WORKSPACE", autrement dit, récupérer un FILE sur le workspace :
// récupérons le fichier défini de rang 1 , en tant que WORKSPACE dans le workflow
File file = handlerIO.getInput(1);
  • Récupérer un objet « MEMORY », autrement dit, récupérer un object en mémoire :
// récupérons l'objet défini en rang 2, en mémoire
Object object = handlerIO.getInput(2);

14.4.2.2.4. Travailler sur le Workspace sur un fichier temporaire

S’il est nécessaire de travailler sur un fichier temporaire sur le workspace, il est possible de faire :

// créons un fichier temporaire sur le workspace
File temporaryFile = handlerIO.getNewLocalFile("MyTempFile" + objectName);

14.4.2.2.5. Enregistrer un output

Soit la déclaration d’outputs :

"out": [
 {
   "name": "test.file",
   "uri": "WORKSPACE:test.txt"
 },
 {
   "name": "test.memory",
   "uri": "MEMORY:test.memory"
 }
]

Si l’on souhaite réaliser les différentes opérations :

  • Stocker sur le workspace un fichier :
 // To get the filename as specified by the workflow
 ProcessingUri uri = handlerIO.getOutput(0);
 String filename = uri.getPath();
 // Write your own file
 File newFile = handlerIO.getNewLocalFile(filename);
 // write it
 ...
 // add it to the handler IO
 handlerIO.addOuputResult(0, newFile);


- Stocker en mémoire un objet :
// Create your own Object
Map myMap = new HashMap();
// ... add some values in the map
// Now give it back to handlerIO as ouput result
handlerIO.addOuputResult(1, myMap);

14.4.3. Gestion des statuts du plugin : ItemStatus

Le plugin dans sa méthode execute, doit forcément retourner un objet de type ItemStatus.

Il doit être instancié avec un identifiant tehnique précisant l’action exécutée. Cette instanciation est nécessaire pour pouvoir appliquer une liste de messages humains qui seront calculés en fonction du statut de l’action (cf paragraphe 3.1).

final ItemStatus itemStatus = new ItemStatus("MON_ACTION_PLUGIN_1");

Le plugin est ensuite libre d’exécuter le code qu’il souhaire ensuite. La mise à jour du statut de l’exécution du plugin se fait en appelant la méthode increment sur l’objet ItemStatus créé.

// mon exécution a fonctionné, le statut est OK :
itemStatus.increment(StatusCode.OK);
// mon exécution n'a pas fonctionné, je n'obtiens pas ce que je devais avoir, le statut est KO :
itemStatus.increment(StatusCode.KO);

Cas particulier du traitement de plusieurs objets dans un même plugin. Si l’on se trouve dans un plugin devant traiter une liste d’objets (ex : groupes d’objets pour une vérification de format) alors il sera possible d’ajouter des statuts sur les sous-tâches.

for (final Object monObjet : maListedOBjetsDansLeGroupeDobjets) {
  // j'exécute ma sous tache
  Result result = monObjet.doSomething();
  itemStatus.increment(result.getStatus());
  itemStatus.setSubTaskStatus(monObjet.getObjectId(), itemStatus);
}

En fin de execute(), le plugin doit donc retourner l’objet ItemStatus instancié.

return new ItemStatus(CHECK_RULES_TASK_ID).setItemsStatus(CHECK_RULES_TASK_ID, itemStatus);

14.4.3.1. Journalisation : opération et cycle de vie

Le worker, lorsqu’il récupérera le statut du plugin, devra traduire les différentes clés (ID_PLUGIN + STATUT) en messages humains en utilisant par défaut le fichier de properties VITAM (vitam-logbook-messages_fr.properties). Si les clés ne sont pas définies dans le fichier de properties VITAM, alors le worker utilisera les labels définis dans le fichier de properties du plugin.

Si l’on souhaite gérer les différents messages qui seront enregistrés dans les journaux d’opération, il faudra dans le plugin, ajouter un fichier de properties intégrant les différentes clés (identifiant du plugin + statut final éventuellement).

PLUGIN.MON_PLUGIN=Exécution de mon plugin
PLUGIN.MON_PLUGIN.OK=Succès de l'exécution de mon plugin
PLUGIN.MON_PLUGIN.KO=Échec lors de l'exécution de mon plugin
PLUGIN.MON_PLUGIN.WARNING=Avertissement lors de l'exécution de mon plugin
PLUGIN.MON_PLUGIN.FATAL=Erreur fatale lors de l'exécution de mon plugin

Cas particulier du traitement des lifecycles. Lorsqu’un plugin s’exécute sur une liste d’objets (ex : « kind »: « LIST_ORDERING_IN_FILE », « element »: « ObjectGroup » ou « element »: « Units » dans la configuration du Workflow) on va pouvoir ajouter des enregistrements dans la journalisation des cycles de vie (ObjectGroup ou Unit).

Prenons l’exemple de l’action CHECK_DIGEST dans le DefaultWorkflow qui est exécuté au sein d’une étape sur une liste d’ObjectGroups. Cette action va exécuter un plugin particulier (identifié via un fichier de configuration). Le journal de cycle de vie des objectgroups va donc être mis à jour en fonction de l’exécution du plugin sur chaque objet. Ce plugin exécute un traitement ayant pour identifiant CALC_CHECK. En fonction du statut de chaque traitement on aura donc des messages différents dans les journaux de cycle de vie.

{
  "evType" : "LFC.CHECK_DIGEST",
  "outcome" : "OK",
  "outDetail" : "LFC.CHECK_DIGEST.OK",
}
{
  "evType" : "LFC.CHECK_DIGEST.CALC_CHECK",
  "outcome" : "OK",
  "outDetail" : "LFC.CHECK_DIGEST.CALC_CHECK.OK",
}

Il convient donc d’avoir dans le fichier de properties VITAM (vitam-logbook-messages_fr.properties) ou bien dans le fichier de properties du plugin (si les clés ne sont pas définies dans le VITAM) :

LFC.CHECK_DIGEST=Vérification de l''intégrité des objets versés
LFC.CHECK_DIGEST.OK=Succès de la vérification de l''intégrité des objets versés
LFC.CHECK_DIGEST.WARNING=Empreinte de l''objet recalculée en enregistrées dans les métadonnées de l''objet
LFC.CHECK_DIGEST.KO=Échec de la vérification de l''intégrité des objets versés
LFC.CHECK_DIGEST.FATAL= Vérification de l''intégrité de l''objet impossible
LFC.CHECK_DIGEST.CALC_CHECK=Calcul d''une empreinte en SHA-512
LFC.CHECK_DIGEST.CALC_CHECK.OK=Succès du calcul d''une l''empreinte en SHA-512
LFC.CHECK_DIGEST.CALC_CHECK.KO=Échec du calcul d''une empreinte en SHA-512
LFC.CHECK_DIGEST.CALC_CHECK.FATAL=Erreur fatale lors calcul d''une empreinte en SHA-512

Tous les différents cas d’erreur doivent être traités.

14.4.4. Intégration d’un nouveau plugin

Afin d’ajouter un nouveau plugin dans l’architecture VITAM, il convient de réaliser plusieurs opérations.

14.4.4.1. Ajout de l’action dans le Workflow

Dans le bon Workflow, il s’agit d’ajouter une action dans l’étape adéquate.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
{
  "id": "DEFAULT_WORKFLOW",
  "name": "Default Ingest Workflow",
  "identifier": "PROCESS_SIP_UNITARY",
  "typeProc": "INGEST",
  "comment": "Default Ingest Workflow V6",
  "steps": [
    {
      "workerGroupId": "DefaultWorker",
      "stepName": "STP_SANITY_CHECK_SIP",
      "behavior": "BLOCKING",
      "distribution": {
        "kind": "REF"
      },
      "waitFor": "sanityCheckResult.json",
      "actions": [
        {
          "action": {
            "actionKey": "SANITY_CHECK_SIP",
            "behavior": "BLOCKING",
            "in": {
              "name": "paramToCheck",
              "uri": "VALUE:antivirusParam"
            }
          }
        },
        {
          "action": {
            "actionKey": "CHECK_CONTAINER",
            "behavior": "BLOCKING",
            "in": {
              "name": "paramToCheck",
              "uri": "VALUE:fileFormatParam"
            }
          }
        },
        {
          "action": {
            "actionKey": "MANIFEST_FILE_NAME_CHECK",
            "behavior": "BLOCKING",
            "in": {
              "name": "paramToCheck",
              "uri": "VALUE:fileNameManifestParam"
            }
          }
        },
        {
          "action": {
            "actionKey": "MANIFEST_DIGEST_CHECK",
            "behavior": "BLOCKING",
            "in": {
              "name": "paramToCheck",
              "uri": "VALUE:digestManifestParam"
            }
          }
        }
      ]
    },
    {
      "workerGroupId": "DefaultWorker",
      "stepName": "STP_UPLOAD_SIP",
      "behavior": "BLOCKING",
      "distribution": {
        "kind": "REF"
      },
      "waitFor": "stpUploadResult.json",
      "actions": [
        {
          "action": {
            "actionKey": "UPLOAD_SIP",
            "behavior": "BLOCKING"
          }
        }
      ]
    },
    {
      "workerGroupId": "DefaultWorker",
      "stepName": "STP_INGEST_CONTROL_SIP",
      "behavior": "BLOCKING",
      "distribution": {
        "kind": "REF",
        "element": "SIP/manifest.xml"
      },
      "actions": [
        {
          "action": {
            "actionKey": "CHECK_SEDA",
            "behavior": "BLOCKING"
          }
        },
        {
          "action": {
            "actionKey": "CHECK_HEADER",
            "behavior": "BLOCKING",
            "in": [
              {
                "name": "checkOriginatingAgency",
                "uri": "VALUE:true"
              },
              {
                "name": "checkProfile",
                "uri": "VALUE:true"
              }
            ],
            "out": [
              {
                "name": "contracts.json",
                "uri": "WORKSPACE:referential/contracts.json"
              }
            ]
          }
        },
        {
          "action": {
            "actionKey": "PREPARE_STORAGE_INFO",
            "behavior": "BLOCKING",
            "in": [
              {
                "name": "contracts.json",
                "uri": "WORKSPACE:referential/contracts.json"
              }
            ],
            "out": [
              {
                "name": "storageInfo.json",
                "uri": "WORKSPACE:StorageInfo/storageInfo.json"
              }
            ]
          }
        },
        {
          "action": {
            "actionKey": "CHECK_DATAOBJECTPACKAGE",
            "behavior": "BLOCKING",
            "in": [
              {
                "name": "checkNoObject",
                "uri": "VALUE:false"
              },
              {
                "name": "UnitType",
                "uri": "VALUE:INGEST"
              },
              {
                "name": "storageInfo.json",
                "uri": "WORKSPACE:StorageInfo/storageInfo.json"
              },
              {
                "name": "contracts.json",
                "uri": "WORKSPACE:referential/contracts.json"
              }
            ],
            "out": [
              {
                "name": "unitsLevel.file",
                "uri": "WORKSPACE:UnitsLevel/ingestLevelStack.json"
              },
              {
                "name": "mapsDOtoOG.file",
                "uri": "WORKSPACE:Maps/DATA_OBJECT_TO_OBJECT_GROUP_ID_MAP.json"
              },
              {
                "name": "mapsDO.file",
                "uri": "WORKSPACE:Maps/DATA_OBJECT_ID_TO_GUID_MAP.json"
              },
              {
                "name": "mapsObjectGroup.file",
                "uri": "WORKSPACE:Maps/OBJECT_GROUP_ID_TO_GUID_MAP.json"
              },
              {
                "name": "mapsObjectGroup.file",
                "uri": "MEMORY:MapsMemory/OG_TO_ARCHIVE_ID_MAP.json"
              },
              {
                "name": "mapsDOtoVersionBDO.file",
                "uri": "WORKSPACE:Maps/DATA_OBJECT_ID_TO_DATA_OBJECT_DETAIL_MAP.json"
              },
              {
                "name": "mapsUnits.file",
                "uri": "WORKSPACE:Maps/ARCHIVE_ID_TO_GUID_MAP.json"
              },
              {
                "name": "globalSEDAParameters.file",
                "uri": "WORKSPACE:ATR/globalSEDAParameters.json"
              },
              {
                "name": "mapsObjectGroup.file",
                "uri": "MEMORY:MapsMemory/OBJECT_GROUP_ID_TO_GUID_MAP.json"
              },
              {
                "name": "existingObjectGroup.file",
                "uri": "WORKSPACE:UpdateObjectGroup/existing_object_group.json"
              },
              {
                "name": "mapsGuid.file",
                "uri": "WORKSPACE:Maps/GUID_TO_ARCHIVE_ID_MAP.json"
              },
              {
                "name": "ontology.file",
                "uri": "WORKSPACE:Ontology/ontology.json"
              },
              {
                "name": "mapsExisitingGotToNewGotForAttachment.file",
                "uri": "WORKSPACE:Maps/EXISTING_GOT_TO_NEW_GOT_GUID_FOR_ATTACHMENT_MAP.json"
              },
              {
                "name": "mapsExisitingUnitsForAttachment.file",
                "uri": "WORKSPACE:Maps/EXISTING_UNITS_GUID_FOR_ATTACHMENT_MAP.json"
              },
              {
                "name": "mapsExisitingGotsForAttachment.file",
                "uri": "WORKSPACE:Maps/EXISTING_GOTS_GUID_FOR_ATTACHMENT_MAP.json"
              }
            ]
          }
        },
        {
          "action": {
            "actionKey": "CHECK_ATTACHEMENT",
            "behavior": "BLOCKING",
            "in": [
              {
                "name": "mapsExisitingGotsForAttachment.file",
                "uri": "WORKSPACE:Maps/EXISTING_GOTS_GUID_FOR_ATTACHMENT_MAP.json"
              },
              {
                "name": "mapsExisitingUnitsForAttachment.file",
                "uri": "WORKSPACE:Maps/EXISTING_UNITS_GUID_FOR_ATTACHMENT_MAP.json"
              }
            ]
          }
        }
      ]
    },
    {
      "workerGroupId": "DefaultWorker",
      "stepName": "STP_OG_CHECK_AND_TRANSFORME",
      "behavior": "BLOCKING",
      "distribution": {
        "kind": "LIST_IN_DIRECTORY",
        "element": "ObjectGroup",
        "type": "ObjectGroup"
      },
      "actions": [
        {
          "action": {
            "actionKey": "CHECK_DIGEST",
            "behavior": "BLOCKING",
            "in": [
              {
                "name": "algo",
                "uri": "VALUE:SHA-512"
              }
            ],
            "out": [
              {
                "name": "groupObject",
                "uri": "MEMORY:groupObjectId"
              }
            ]
          }
        },
        {
          "action": {
            "actionKey": "CHECK_OBJECT_SIZE",
            "behavior": "BLOCKING",
            "out": [
              {
                "name": "groupObject",
                "uri": "MEMORY:groupObjectId"
              }
            ]
          }
        },
        {
          "action": {
            "actionKey": "OG_OBJECTS_FORMAT_CHECK",
            "behavior": "BLOCKING",
            "in": [
              {
                "name": "groupObject",
                "uri": "MEMORY:groupObjectId"
              },
              {
                "name": "contracts.json",
                "uri": "WORKSPACE:referential/contracts.json"
              }
            ]
          }
        }
      ]
    },
    {
      "workerGroupId": "DefaultWorker",
      "stepName": "STP_UNIT_CHECK_AND_PROCESS",
      "behavior": "BLOCKING",
      "distribution": {
        "kind": "LIST_ORDERING_IN_FILE",
        "type": "Units",
        "element": "UnitsLevel/ingestLevelStack.json"
      },
      "actions": [
        {
          "action": {
            "actionKey": "CHECK_UNIT_SCHEMA",
            "behavior": "BLOCKING",
            "in": [
              {
                "name": "ontology.file",
                "uri": "WORKSPACE:Ontology/ontology.json"
              }
            ],
            "out": [
              {
                "name": "unit",
                "uri": "MEMORY:unitId"
              }
            ]
          }
        },
        {
          "action": {
            "actionKey": "CHECK_ARCHIVE_UNIT_PROFILE",
            "behavior": "NOBLOCKING",
            "in": [
              {
                "name": "mapsGuid.file",
                "uri": "WORKSPACE:Maps/GUID_TO_ARCHIVE_ID_MAP.json"
              }
            ],
            "out": [
              {
                "name": "unit",
                "uri": "MEMORY:unitId"
              }
            ]
          }
        },
        {
          "action": {
            "actionKey": "CHECK_CLASSIFICATION_LEVEL",
            "behavior": "BLOCKING",
            "in": [
              {
                "name": "unit",
                "uri": "MEMORY:unitId"
              }
            ]
          }
        },
        {
          "action": {
            "actionKey": "UNITS_RULES_COMPUTE",
            "behavior": "BLOCKING",
            "in": [
              {
                "name": "unit",
                "uri": "MEMORY:unitId"
              }
            ]
          }
        }
      ]
    },
    {
      "workerGroupId": "DefaultWorker",
      "stepName": "STP_STORAGE_AVAILABILITY_CHECK",
      "behavior": "BLOCKING",
      "distribution": {
        "kind": "REF",
        "element": "SIP/manifest.xml"
      },
      "actions": [
        {
          "action": {
            "actionKey": "STORAGE_AVAILABILITY_CHECK",
            "behavior": "BLOCKING",
            "in": [
              {
                "name": "contracts.json",
                "uri": "WORKSPACE:referential/contracts.json"
              }
            ]
          }
        }
      ]
    },
    {
      "workerGroupId": "DefaultWorker",
      "stepName": "STP_OBJ_STORING",
      "behavior": "BLOCKING",
      "distribution": {
        "kind": "LIST_IN_DIRECTORY",
        "element": "ObjectGroup",
        "type": "ObjectGroup",
        "bulkSize": 1000
      },
      "actions": [
        {
          "action": {
            "actionKey": "OBJ_STORAGE",
            "behavior": "BLOCKING",
            "out": [
              {
                "name": "groupObject",
                "uri": "MEMORY:groupObjectId"
              }
            ]
          }
        },
        {
          "action": {
            "actionKey": "OG_METADATA_INDEXATION",
            "behavior": "BLOCKING",
            "in": [
              {
                "name": "groupObject",
                "uri": "MEMORY:groupObjectId"
              }
            ]
          }
        }
      ]
    },
    {
      "workerGroupId": "DefaultWorker",
      "stepName": "STP_UNIT_METADATA",
      "behavior": "BLOCKING",
      "distribution": {
        "kind": "LIST_ORDERING_IN_FILE",
        "type": "Units",
        "element": "UnitsLevel/ingestLevelStack.json",
        "bulkSize": 1000
      },
      "actions": [
        {
          "action": {
            "actionKey": "UNIT_METADATA_INDEXATION",
            "behavior": "BLOCKING",
            "in": [
              {
                "name": "globalSEDAParameters.file",
                "uri": "WORKSPACE:ATR/globalSEDAParameters.json"
              }
            ]
          }
        }
      ]
    },
    {
      "workerGroupId": "DefaultWorker",
      "stepName": "STP_OG_STORING",
      "behavior": "BLOCKING",
      "distribution": {
        "kind": "LIST_IN_DIRECTORY",
        "element": "ObjectGroup",
        "type": "ObjectGroup",
        "bulkSize": 128
      },
      "actions": [
        {
          "action": {
            "actionKey": "COMMIT_LIFE_CYCLE_OBJECT_GROUP",
            "behavior": "BLOCKING"
          }
        },
        {
          "action": {
            "actionKey": "OG_METADATA_STORAGE",
            "behavior": "BLOCKING",
            "lifecycleLog": "DISABLED"
          }
        }
      ]
    },
    {
      "workerGroupId": "DefaultWorker",
      "stepName": "STP_UNIT_STORING",
      "behavior": "BLOCKING",
      "distribution": {
        "kind": "LIST_ORDERING_IN_FILE",
        "type": "Units",
        "element": "UnitsLevel/ingestLevelStack.json",
        "bulkSize": 128
      },
      "actions": [
        {
          "action": {
            "actionKey": "COMMIT_LIFE_CYCLE_UNIT",
            "behavior": "BLOCKING"
          }
        },
        {
          "action": {
            "actionKey": "UNIT_METADATA_STORAGE",
            "behavior": "BLOCKING",
            "lifecycleLog": "DISABLED"
          }
        }
      ]
    },
    {
      "workerGroupId": "DefaultWorker",
      "stepName": "STP_UPDATE_OBJECT_GROUP",
      "behavior": "BLOCKING",
      "distribution": {
        "kind": "LIST_IN_FILE",
        "element": "UpdateObjectGroup/existing_object_group.json",
        "type": "ObjectGroup",
        "statusOnEmptyDistribution": "OK",
        "bulkSize": 128
      },
      "actions": [
        {
          "action": {
            "actionKey": "OBJECT_GROUP_UPDATE",
            "behavior": "BLOCKING",
            "lifecycleLog": "FLUSH_LFC"
          }
        },
        {
          "action": {
            "actionKey": "COMMIT_LIFE_CYCLE_OBJECT_GROUP",
            "behavior": "BLOCKING"
          }
        },
        {
          "action": {
            "actionKey": "OG_METADATA_STORAGE",
            "behavior": "BLOCKING",
            "lifecycleLog": "DISABLED"
          }
        }
      ]
    },
    {
      "workerGroupId": "DefaultWorker",
      "stepName": "STP_ACCESSION_REGISTRATION",
      "behavior": "BLOCKING",
      "distribution": {
        "kind": "REF",
        "element": "SIP/manifest.xml"
      },
      "actions": [
        {
          "action": {
            "actionKey": "ACCESSION_REGISTRATION",
            "behavior": "BLOCKING",
            "in": [
              {
                "name": "globalSEDAParameters.file",
                "uri": "WORKSPACE:ATR/globalSEDAParameters.json"
              }
            ]
          }
        }
      ]
    },
    {
      "workerGroupId": "DefaultWorker",
      "stepName": "STP_INGEST_FINALISATION",
      "behavior": "FINALLY",
      "distribution": {
        "kind": "REF",
        "element": "SIP/manifest.xml"
      },
      "actions": [
        {
          "action": {
            "actionKey": "ATR_NOTIFICATION",
            "behavior": "NOBLOCKING",
            "in": [
              {
                "name": "mapsUnits.file",
                "uri": "WORKSPACE:Maps/ARCHIVE_ID_TO_GUID_MAP.json",
                "optional": true
              },
              {
                "name": "mapsDO.file",
                "uri": "WORKSPACE:Maps/DATA_OBJECT_ID_TO_GUID_MAP.json",
                "optional": true
              },
              {
                "name": "mapsDOtoOG.file",
                "uri": "WORKSPACE:Maps/DATA_OBJECT_TO_OBJECT_GROUP_ID_MAP.json",
                "optional": true
              },
              {
                "name": "mapsDOtoVersionBDO.file",
                "uri": "WORKSPACE:Maps/DATA_OBJECT_ID_TO_DATA_OBJECT_DETAIL_MAP.json",
                "optional": true
              },
              {
                "name": "globalSEDAParameters.file",
                "uri": "WORKSPACE:ATR/globalSEDAParameters.json",
                "optional": true
              },
              {
                "name": "mapsOG.file",
                "uri": "WORKSPACE:Maps/OBJECT_GROUP_ID_TO_GUID_MAP.json",
                "optional": true
              },
              {
                "name": "mapsExisitingGotToNewGotForAttachment.file",
                "uri": "WORKSPACE:Maps/EXISTING_GOT_TO_NEW_GOT_GUID_FOR_ATTACHMENT_MAP.json",
                "optional": true
              }
            ],
            "out": [
              {
                "name": "atr.file",
                "uri": "WORKSPACE:ATR/responseReply.xml"
              }
            ]
          }
        },
        {
          "action": {
            "actionKey": "ROLL_BACK",
            "behavior": "BLOCKING"
          }
        }
      ]
    }
  ]
}

Par exemple, je souhaite ajouter une deuxième vérification, en plus de la vérification du manifest par rapport au XSD. Je souhaite valider le manifest avec un XSD « maison ». Cette vérification doit générer un fichier de report sur le Workspace, qui sera utilisé dans un futur proche. Il suffit donc d’ajouter les informations dans le Workflow adéquat.

{
 "action": {
   "actionKey": "CHECK_SEDA",
   "behavior": "BLOCKING"
 }
}, {
 "action": {
   "actionKey": "CHECK_MANIFEST_CUSTOM_XSD",
   "behavior": "NOBLOCKING",
   "out": [
     {
       "name": "report.file",
       "uri": "WORKSPACE:REPORT/report.txt"
     }
   ]
  }
}

De cette manière, l’action de vérification du manifest par un XSD maison se déroulera dans l’étape « STP_INGEST_CONTROL_SIP » et ne bloquera pas le processus en cas d’erreur (pour que l’on puisse continuer le workflow en cas d’erreur).

14.4.4.2. Ajout du plugin dans la liste des plugins

Une fois l’action déclarée dans le Workflow, il convient de préciser les informations au Worker pour qu’il puisse connaitre le code à exécuter pour ce type d’action. Dans le fichier de configuration plugins.json de l’ansiblerie du Worker, il conviendra d’ajouter les lignes suivantes :

"CHECK_MANIFEST_CUSTOM_XSD": {
      "className": "mon.package.plugin.CheckManifestCustomXSD",
      "propertiesFile": "check_manifest_custom_xsd_plugin.properties"
}

Pour information, le fichier de configuration plugins.json se trouve dans le répertoire /vitam/conf/worker/ du Worker.

14.4.4.3. Création du plugin

Maintenant le plugin déclaré, il convient enfin de coder le plugin à proprement parler. Pour ceci, il faut donc créer une classe CheckManifestCustomXSD.java qui doit implémenter la classe ActionHandler et notamment surcharger la méthode execute() pour un plugin unitaire ou la méthode executeAll() pour un traitemement de masse.

Le choix de faire un plugin unitaire ou traitement de masse dépend de l’action à réaliser par le plugin. Si cette action comporte des modifications massives en base de données (par exmeple mise à jour d’unité archivistique), alors le traitement de masse est à envisager pour profiter au mieux des performances de la base de données.

A contrario, si le traitement est par exemple une transformation de fichier, alors le plugin unitaire est plus adapté.

Il faut, à minima l’arborescence suivante :

/src/main/java/mon/package/plugin/CheckManifestCustomXSD.java /src/main/resources/check_manifest_custom_xsd_plugin.properties

On arrivera à quelque chose dans ce style :

package mon.package.plugin;
public class CheckManifestCustomXSD extends ActionHandler {
  // lets decide that the name of this task would be CHECK_TEST_MANIFEST
  private static final String CHECK_TEST_MANIFEST = "CHECK_TEST_MANIFEST";
  @Override
  public ItemStatus execute(WorkerParameters param, HandlerIO handler)
     throws ProcessingException, ContentAddressableStorageServerException {
     final ItemStatus itemStatus = new ItemStatus(CHECK_TEST_MANIFEST);
     // lets get the manifest that is passed as an input
     InputStream manifest = null;
     try {
         manifest = handler.getInputStreamFromWorkspace(
             IngestWorkflowConstants.SEDA_FOLDER + "/" + IngestWorkflowConstants.SEDA_FILE);
     } catch (Exception e) {
         // error but status code is KO
         itemStatus.increment(StatusCode.KO);
         System.out.println("Manifest not found or technical problem");
         throw new ProcessingException("Manifest not found or technical problem", e);
     }
     // lets validate with XSD
     File reportFile;
     try {
         reportFile = CustomValidator.validateCustomXSD(manifest, itemStatus);
         // in the validateCustomXSD if the validate is ok
         // we ll have in the code : itemStatus.increment(StatusCode.OK);
         // if it's not : itemStatus.increment(StatusCode.WARNING);
     } catch (Exception e) {
         // error but status code is KO
         System.out.println("technical problem");
         itemStatus.increment(StatusCode.KO);
     }
     handler.addOuputResult(0, reportFile, true);
     // lets return the status
     return new ItemStatus(CHECK_TEST_MANIFEST).setItemsStatus(CHECK_TEST_MANIFEST, itemStatus);
  }
  @Override
  public void checkMandatoryIOParameter(HandlerIO handler) throws ProcessingException {
     // Nothing to do here - it s not neccessary to check handlerIO at this moment
  }

}

De plus, il faudra créer le fichier de properties (check_manifest_custom_xsd_plugin.properties) associé :

PLUGIN.CHECK_TEST_MANIFEST=Vérification de la cohérence du manifest avec le CUSTOM XSD
PLUGIN.CHECK_TEST_MANIFEST.OK=Manifest conforme au CUSTOM XSD
PLUGIN.CHECK_TEST_MANIFEST.KO=Échec lors de la vérification de la cohérence du manifest avec le CUSTOM XSD
PLUGIN.CHECK_TEST_MANIFEST.WARNING=Manifest non conforme au CUSTOM XSD

14.4.4.4. Installation du plugin

Le plugin devra être fourni sous forme de jar (s’il provient d’une source externe à VITAM) et devra être installé dans le Worker, dans /vitam/lib/worker/