diff --git a/data-calculation/README.md b/data-calculation/README.md new file mode 100644 index 0000000..8bd6674 --- /dev/null +++ b/data-calculation/README.md @@ -0,0 +1,91 @@ +# data-computer + +L'instance `data-computer utilise l'application ezmaster +[`lodex-workers`](https://github.com/Inist-CNRS/lodex-workers). + +Elle offre plusieurs services **asynchrones** pour des calculs et de transformations de données simples. + +*Tous les services proposés acceptent uniquement en entrée des fichiers corpus standards au format tar.gz.* + + +## Configuration + +Il faut préciser dans le fichier de configuration de l'instance qu'elle utilise les paquets nodejs suivant : + +- `@ezs/analytics` +- `@ezs/basics` + +Bien sûr, les dernières versions sont préférables. + +Exemple: + +```json +{ + "packages": [ + "@ezs/core@3.0.5", + "@ezs/analytics@2.0.23", + "@ezs/basics@2.5.1" + ] +} +``` + +## Utilisation + +- [v1/tree-segment](#v1%2ftree-segment) + +### v1/tree-segment + +Créer des segments 2 à 2 de tous les éléments d'un tableau et agrège ces segments pour les compter + +par exemple avec ces données en entrée: + +```json +[ + { "value": ["a", "b", "c"] }, + { "value": ["a", "c", "d"] }, + { "value": ["a", "b", "d"] }, + { "value": ["a", "b", "c", "d"] }, + { "value": ["a", "c", "d", "e"] } +] + +``` + +on obtiendra : + +```json +[ + {"source":"a","target":"b","weight":3}, + {"source":"b","target":"c","weight":2}, + {"source":"a","target":"c","weight":2}, + {"source":"c","target":"d","weight":3}, + {"source":"b","target":"d","weight":1}, + {"source":"d","target":"e","weight":1} +] +``` + +> NOTE: Le service accepte des tableaux de tableaux (cas d'usage lodex/istex) + +#### Paramètre(s) URL + +| nom | description | +| ------------------- | ------------------------------------------- | +| indent (true/false) | Indenter le résultat renvoyer immédiatement | + +#### Entête(s) HTTP + +| nom | description | +| ------ | ------------------------------------------------------------ | +| X-Hook | URL à appeler quand le résultat sera disponible (facultatif) | + +#### Exemple en ligne de commande + + +```bash +# Send data for batch processing +cat input.tar.gz |curl --data-binary @- -H "X-Hook: https://webhook.site/dce2fefa-9a72-4f76-96e5-059405a04f6c" "http://localhost:31976/v1/tree-segment" > output.json + +# When the corpus is processed, get the result +cat output.json |curl --data-binary @- "http://localhost:31976/v1/retrieve" > output.tar.gz + +``` + diff --git a/data-calculation/example-json.tar.gz b/data-calculation/example-json.tar.gz new file mode 100644 index 0000000..cb57cc3 --- /dev/null +++ b/data-calculation/example-json.tar.gz Binary files differ diff --git a/data-calculation/examples.http b/data-calculation/examples.http new file mode 100644 index 0000000..efeda2e --- /dev/null +++ b/data-calculation/examples.http @@ -0,0 +1,28 @@ +# File Global Variables: Variables defined in Region without name or request +@baseUrl = http://localhost:31976 +#@baseUrl = http://data-calculation.tdmservices.intra.inist.fr/ +### + +# @name tree-segment +POST {{baseUrl}}/v1/tree-segment HTTP/1.1 +Content-Type: application/x-tar +X-Hook: https://webhook.site/69300b22-a251-4c16-9905-f7ba218ae7e9 + +< ./example-json.tar.gz + +### + +# @name retrieve +# @save +# @extension tar.gz +POST {{baseUrl}}/v1/retrieve HTTP/1.1 +Content-Type: application/json + +[ + { + "value":"PJPkijmzx" + } +] +### + + diff --git a/data-calculation/v1/README.md b/data-calculation/v1/README.md deleted file mode 100644 index 822e225..0000000 --- a/data-calculation/v1/README.md +++ /dev/null @@ -1,11 +0,0 @@ -### usage - -```bash -# Send data for batch processing -cat input.tar.gz |curl --data-binary @- -H "X-Hook: https://webhook.site/dce2fefa-9a72-4f76-96e5-059405a04f6c" "http://localhost:31976/v1/tree-segment" > output.json - -# When the corpus is processed, get the result -cat output.json |curl --data-binary @- "http://localhost:31976/v1/retrieve" > output.tar.gz - - ``` - diff --git a/data-calculation/v1/retrieve.ini b/data-calculation/v1/retrieve.ini index 1259407..ef65d11 100644 --- a/data-calculation/v1/retrieve.ini +++ b/data-calculation/v1/retrieve.ini @@ -5,19 +5,14 @@ [JSONParse] separator = * -[env] -path = manifest.identifier -value = get('value') - [exchange] value = get('value') [FILELoad] -location = /tmp +location = /tmp/retrieve -[unpack] +#[unpack] -[TARDump] -compress = true -manifest = env('manifest') -manifest = fix({description: 'Exemple de fichier batch pour traitement asynchrone'}) +#[TARDump] +#compress = true +#manifest = env('manifest') \ No newline at end of file diff --git a/data-calculation/v1/tree-segment.ini b/data-calculation/v1/tree-segment.ini index 7e3c02d..b797dc0 100644 --- a/data-calculation/v1/tree-segment.ini +++ b/data-calculation/v1/tree-segment.ini @@ -2,62 +2,98 @@ plugin = basics plugin = analytics +# Step 0 (générique) : Lire le fichier standard tar.gz [TARExtract] compress = true -# Création d'un identifiant unique pour le corpus reçu +# Step 1 (générique) : Créer un identifiant unique pour le corpus reçu [singleton] [singleton/identify] [singleton/env] +path = generator +value = tree-segment path = identifier value = get('uri').replace('uid:/', '') -# Traitement asynchrone de tous les items du corpus +# Step 2 (générique): Traiter de manière asynchnore les items reçus [fork] standalone = true -# Calcul sur le corpus -[fork/replace] +# Step 2.1 (générique): Lancer un calcul sur tous les items reçus +[fork/delegate] + +# Step 2.1.1 (spécifique): S'assurer d'avoir des tableaux de tableaux +[fork/delegate/replace] path = id value = get('id') path = value -value = get('value').castArray().map((item) => [].concat(item).reduce((pre, cur, idx, src) => (pre ? [ ...pre, [src[idx-1],cur]] : []), false)).flatten() +value = get('value').thru(x => x && Array.isArray(x[0])?x:[x]) +# Step 2.1.2 (spécifique): Créer des tableaux de paires des segements (ou Bigramme) +[fork/delegate/segment] +aggregate = false +path = value -# Sauvegarde le résultat produit +# Step 2.1.3 (spécifique): Regrouper les segments +[fork/delegate/aggregate] + +# Step 2.1.4 (spécifique): Compter les segments similaires +[fork/delegate/summing] +path = value + +# Step 2.1.5 (spécifique): Construire un résulat spécifique du calcul +[fork/delegate/replace] +path = source +value = get('id.0') +path = target +value = get('id.1') +path = weight +value = get('value') + +# Step 2.2 (générique): Création d'un fichier résulat standard +[fork/TARDump] +compress = true +manifest = fix({version: '1'}) +manifest = fix({identifier: env('identifier')}) +manifest = fix({generator: env('generator')}) + +# Step 2.3 (générique): Sauvegarder sur disque le résulat [fork/FILESave] -location = /tmp +location = /tmp/retrieve identifier = env('identifier') -jsonl = true +jsonl = false +compress = false -# Signal le fin du traitement via un appel à un webhook (si il a été précisé) +# Step 2.4 (générique): Signaler le fin du traitement via un appel à un webhook (si il a été précisé) [fork/swing] test = env('headers.x-hook').startsWith('http') + +# Step 2.4.1 (générique): Séléctionner les informations à envoyer au webhook [fork/swing/replace] path = body -value = self().pick(['size', 'atime', 'mtime', 'ctime']).set('identifier', env('identifier')).set('state', 'ready') +value = self().pick(['size', 'atime', 'mtime', 'ctime']).set('identifier', env('identifier')).set('generator', env('generator')).set('state', 'ready') - +# Step 2.4.2 (générique): Envoyer la requète HTTP [fork/swing/URLFetch] url = env('headers.x-hook') path = body headers = Content-Type:application/json +# Step 2.4.3 (faculatif) : Ajouter une trace dans log [fork/swing/debug] text = webhook triggered +# Step 2.5 (faculatif) : Ajouter une trace dans log [fork/debug] text = process completed - -# Retour immédiat d'un seul élément indiquant comment récupérer le corpus quand il sera prêt +# Step 3 : Renvoyer immédiatement seul élément indiquant comment récupérer le résulat quand il sera prêt [shift] [replace] path = id -value = http://localhost:31976/retrieve +value = env('generator') path = value value = env('identifier') [JSONString] -indent = env('indent') - +indent = env('indent') \ No newline at end of file