Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

API Geonetwork

132 views
Skip to first unread message

Thomas Zucchiatti

unread,
Apr 23, 2025, 4:23:23 AMApr 23
to georchestra
Bonjour, 

Dans le cadre d'un stage, je travaille sur la mise en place d'une interface georchestra et je rencontre actuellement un petit soucis au niveau de l'API de Geonetwork, et je n'ai pas trouvé beaucoup de documentation par rapport à mon problème. 

En fait, j'essaye de mettre en place un script pour automatiser la création de fiches de métadonnées dans geonetwork (v4.2.8). Pour cela, je voudrais utiliser la fonction PUT records/duplicate de l'API afin de me baser sur une template que j'ai créé en amont, pour déployer une nouvelle fiche qui reprendra la base de cette template et qui y ajoutera par la suite des informations selon les couches que je voudrais y mettre. Dans un premier temps je cherche simplement à créer une copie de cette template (mais qui sera une fiche) ; mais lors de mes tests il n'y a pas moyen de créer cette nouvelle fiche selon mon modèle de template, et cela même depuis l'interface Swagger UI

Dans Swagger UI j'ai pu tester différentes fonctions comme le DELETE records ou encore le PUT records/publish pour voir si le problème venait de l'API elle même, mais les deux ont fonctionnés normalement. A contrario, le PUT records/duplicate ne fonctionne pas. Alors je me dis que peut être je me trompe dans les champs à remplir quelque part. Voici ceux que j'ai renseignés intuitivement :
- MetadataType : METADATA
- sourceUUID : ID que je retrouve sur ma template (testé aussi avec une fiche classique mais sans résultat)
- group (peut être que le soucis vient de là) : J'ai testé avec le nom du groupe entier dans lequel ma template était publiée, le nom raccourci ou encore un chiffre mais les trois ne marchent pas
Pour le reste j'ai laissé les champs vides car non obligatoires.

Sinon, en ce qui concerne le script j'ai bien cerné le système des tokens XSRF pour s'authentifier depuis ce dernier (pas évident au début), et j'ai un script fonctionnel qui permet de supprimer des fiches sans aucun soucis, donc le problème vient uniquement de ma fonction PUT records/duplicate, c'est pour cela que je pense me tromper quelque part dans les champs à remplir. 

Merci d'avance, 
Cordialement,

Thomas Zucchiatti

François Van Der Biest

unread,
Apr 23, 2025, 4:29:44 PMApr 23
to georchestra
Salut Thomas, 
Je n'ai pas accès a un ordi en ce moment mais peut être des éléments de réponse à trouver dans ce dépôt ?
N'hésite pas a nous partager tes retours,
Merci ! 
F.

--
--
Vous avez reçu ce message, car vous êtes abonné au groupe
Groupe "georchestra" georc...@googlegroups.com
voir http://groups.google.fr/group/georchestra
 
Site web : http://www.georchestra.org

---
Vous recevez ce message, car vous êtes abonné au groupe Google Groupes "georchestra".
Pour vous désabonner de ce groupe et ne plus recevoir d'e-mails le concernant, envoyez un e-mail à l'adresse georchestra...@googlegroups.com.
Pour afficher cette discussion, accédez à https://groups.google.com/d/msgid/georchestra/b03a2fab-c1cd-4773-a940-a36cb0161bd3n%40googlegroups.com.

Thomas Zucchiatti

unread,
Apr 28, 2025, 3:44:05 AMApr 28
to georchestra
Bonjour,

Je vous remercie pour le dépôt partagé où j'ai pu remarquer sur l'un des scripts que l'identifiant de groupe était spécifié sous forme numérique et pas avec le nom directement. Cela permet d'éclaircir mes doutes sur ce point. Malgré cela je n'ai toujours pas résolu le problème avec Swagger UI. 

Cependant en creusant un peu j'ai trouvé les sources exactes des erreurs. En ce qui concerne le PUT records/duplicate voila la réponse renvoyée dans le body et le header :
{
  "message": "Content type '' not supported",
  "code": "runtime_exception",
  "description": null
}

access-control-allow-credentials: truetrue
 access-control-allow-headers: X-Requested-WithContent-Type
 access-control-allow-methods: GETPOSTPUTPATCHDELETEOPTIONS
 access-control-allow-origin: **
 access-control-max-age: 1800
 content-security-policy: frame-ancestors 'self'
 content-type: application/json
 date: Fri25 Apr 2025 07:29:45 GMT
 expires: Thu01 Jan 1970 00:00:00 GMT
 referrer-policy: strict-origin
 server: Caddy
 strict-transport-security: max-age=631138519
 transfer-encoding: chunked
 vary: Origin
 x-content-encoding-over-network: gzip
 x-content-type-options: nosniff
 x-download-options: noopen
 x-frame-options: SAMEORIGIN
 x-permitted-cross-domain-policies: none
 x-xss-protection: 0
On y voit clairement qu'il ne renvoi rien du tout dans le content type et que le problème vient de cet espace vide, mais ce que je ne comprends pas c'est que ce content type est pourtant bien spécifié dans la réponse du header juste en dessous. Un fichier de configuration serait à modifier pour lui faire passer ce paramètre de force ? 

J'ai également essayé  de contourner ce PUT qui ne marchait pas avec le POST records, mais ici aussi une erreur, cependant différente. Voici ce que les réponses me renvoient : 
 {
  "message": "A file MUST be provided.",
  "code": "unsatisfied_request_parameter",
  "description": null
}

access-control-allow-credentials: truetrue
 access-control-allow-headers: X-Requested-WithContent-Type
 access-control-allow-methods: GETPOSTPUTPATCHDELETEOPTIONS
 access-control-allow-origin: **
 access-control-max-age: 1800
 content-security-policy: frame-ancestors 'self'
 content-type: application/json
 date: Fri25 Apr 2025 07:51:55 GMT
 expires: Thu01 Jan 1970 00:00:00 GMT
 referrer-policy: strict-origin
 server: Caddy
 strict-transport-security: max-age=631138519
 transfer-encoding: chunked
 vary: Origin
 x-content-encoding-over-network: gzip
 x-content-type-options: nosniff
 x-download-options: noopen
 x-frame-options: SAMEORIGIN
 x-permitted-cross-domain-policies: none
 x-xss-protection: 0
Ici, il me semble que le Swagger n'arrive pas à faire le lien avec le fichier que je lui spécifie ; que ce soit un XML ou un ZIP, parce que je ne trouve aucun lien avec le fichier spécifié dans mes URL :
curl.PNG
Un chemin vers mon fichier ne devrait-il pas être présent dans les url pour que la requête fonctionne ? 

Ces problèmes me semblent plus être des soucis dans la configuration plutôt que dans mes paramètres. Eclairez moi si jamais j'omets quelque chose d'important à cerner. 

Merci à vous 

Thomas Zucchiatti  

François Van Der Biest

unread,
Apr 28, 2025, 11:16:49 AMApr 28
to georc...@googlegroups.com
Peux-tu nous partager en mode texte les CURL que tu effectues ? et les réponses obtenues ?
Ce sera plus simple à débugger à distance.

Merci,
F.

Olivia Guyot

unread,
Apr 29, 2025, 3:05:59 AMApr 29
to georc...@googlegroups.com
Le premier message fait à mon avis référence à un header manquant dans la requête.

Un chemin vers mon fichier ne devrait-il pas être présent dans les url pour que la requête fonctionne ? 

Non, le fichier devrait être envoyé en binaire, mais je ne suis pas sûre que cela marche correctement avec l'interface Swagger. Si tu essaye de reproduire les requêtes sous forme de commandes CURL comme dit François ce sera plus simple de t'aider.

Pour ce faire tu peux aller dans le panneau des "dev tools" (F12 sur Chrome), onglet Réseau, et clic-droit sur la requête qui ne marche pas puis "copy as cURL".
--
camptocamp
INNOVATIVE SOLUTIONS
BY OPEN SOURCE EXPERTS

Olivia Guyot
Geospatial Developer


Thomas Zucchiatti

unread,
Apr 29, 2025, 3:51:03 AMApr 29
to georchestra
Pour la première requête avec le duplicate voici le curl et les réponses associées :

curl 'http://vm-geomatique.lan.cereg.com/geonetwork/srv/api/records/duplicate?metadataType=METADATA&sourceUuid=52ca7d77-44cf-4305-a567-01bdcda9b094&group=101&hasAttachmentsOfSource=true' \
  -X 'PUT' \
  -H 'Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7' \
  -H 'Connection: keep-alive' \
  -H 'Content-Length: 0' \
  -H 'Cookie: XSRF-TOKEN=6ca05baa-f690-47d8-9846-f40494f68bfb; JSESSIONID=node01bwz57l8txz9u1ruarpcm7ks2o36469.node0; serverTime=1745911156969; sessionExpiry=1745997556969; SESSION=83f04cfd-2bc0-44b6-b1d3-04e75aa838d4' \
  -H 'Origin: http://vm-geomatique.lan.cereg.com' \
  -H 'Referer: http://vm-geomatique.lan.cereg.com/' \
  -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36' \
  -H 'X-XSRF-TOKEN: 6ca05baa-f690-47d8-9846-f40494f68bfb' \
  -H 'accept: application/json' \
  --insecure

{"message":"Content type '' not supported","code":"runtime_exception","description":null}

HTTP/1.1 400 Bad Request
Access-Control-Allow-Credentials: true
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: X-Requested-With, Content-Type
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS
Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 1800
Content-Security-Policy: frame-ancestors 'self'
Content-Type: application/json
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Referrer-Policy: strict-origin
Server: Caddy
Set-Cookie: serverTime=1745911192858; Path=/geonetwork
Set-Cookie: sessionExpiry=1745997592858; Path=/geonetwork
Strict-Transport-Security: max-age=631138519
Vary: Origin
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Frame-Options: SAMEORIGIN
X-Permitted-Cross-Domain-Policies: none
X-Xss-Protection: 0
Date: Tue, 29 Apr 2025 07:19:52 GMT
Transfer-Encoding: chunked
X-Content-Encoding-Over-Network: gzip

Si jamais, j'avais également essayé de passer la requête par script mais le problème reste le même :

Script : 
#!/bin/bash

export CATALOG="http://vm-geomatique.lan.cereg.com/geonetwork"
export CATALOGUSER="testadmin"
export CATALOGPASS="testadmin"

COOKIE_FILE="/home/admin/cookier.txt"

rm -f "$COOKIE_FILE"

curl -s -c "$COOKIE_FILE" -o /dev/null -X POST "$CATALOG/srv/eng/info?type=me"

export TOKEN=$(grep -P '\t/geonetwork\t' "$COOKIE_FILE" | grep XSRF-TOKEN | cut -f 7)

curl -v -X PUT \
-H "accept: application/json" \
-H "X-XSRF-TOKEN: $TOKEN" \
--user "$CATALOGUSER:$CATALOGPASS" \
-b "$COOKIE_FILE" \
"$CATALOG/srv/api/records/duplicate?metadataType=METADATA&sourceUuid=7043a273-6e21-4c35-8e02-fb7125c44a95&group=101&hasAttachmentsOfSource=true"

 Réponse : 
┌──[ad...@vm-geomatique.lan.cereg.com] ➜ ~
└─$ bash mm.sh
*   Trying 127.0.1.1:80...
* Connected to vm-geomatique.lan.cereg.com (127.0.1.1) port 80 (#0)
* Server auth using Basic with user 'testadmin'
> PUT /geonetwork/srv/api/records/duplicate?metadataType=METADATA&sourceUuid=7043a273-6e21-4c35-8e02-fb7125c44a95&group=101&hasAttachmentsOfSource=true HTTP/1.1
> Host: vm-geomatique.lan.cereg.com
> Authorization: Basic dGVzdGFkbWluOnRlc3RhZG1pbg==
> User-Agent: curl/7.88.1
> Cookie: XSRF-TOKEN=04d139f6-f837-41ef-bc68-16ca6c89da26
> accept: application/json
> X-XSRF-TOKEN: 04d139f6-f837-41ef-bc68-16ca6c89da26
>
< HTTP/1.1 400 Bad Request
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS
< Access-Control-Allow-Origin: *
< Access-Control-Max-Age: 1800
< Content-Security-Policy: frame-ancestors 'self'
< Content-Type: application/json
< Expires: Thu, 01 Jan 1970 00:00:00 GMT
< Referrer-Policy: strict-origin
< Server: Caddy
* Added cookie JSESSIONID="node01aprlwribk24210iu7bvg7ex2z39369.node0" for domain vm-geomatique.lan.cereg.com, path /geonetwork, expire 0
< Set-Cookie: JSESSIONID=node01aprlwribk24210iu7bvg7ex2z39369.node0; Path=/geonetwork; HttpOnly
* Added cookie serverTime="1745911506597" for domain vm-geomatique.lan.cereg.com, path /geonetwork, expire 0
< Set-Cookie: serverTime=1745911506597; Path=/geonetwork
* Added cookie sessionExpiry="1745911506597" for domain vm-geomatique.lan.cereg.com, path /geonetwork, expire 0
< Set-Cookie: sessionExpiry=1745911506597; Path=/geonetwork
< Strict-Transport-Security: max-age=631138519
< X-Content-Type-Options: nosniff
< X-Download-Options: noopen
< X-Frame-Options: SAMEORIGIN
< X-Permitted-Cross-Domain-Policies: none
< X-Xss-Protection: 0
< Date: Tue, 29 Apr 2025 07:25:06 GMT
< Transfer-Encoding: chunked
<
* Connection #0 to host vm-geomatique.lan.cereg.com left intact
{"message":"Content type '' not supported","code":"runtime_exception","description":null}┌──[ad...@vm-geomatique.lan.cereg.com] ➜ ~
└─$

Et pour le POST records voici le curl et les réponses : 

curl 'http://vm-geomatique.lan.cereg.com/geonetwork/srv/api/records?metadataType=METADATA&uuidProcessing=GENERATEUUID&assignToCatalog=true&transformWith=_none_' \
  -X 'POST' \
  -H 'Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7' \
  -H 'Connection: keep-alive' \
  -H 'Content-Length: 0' \
  -H 'Cookie: XSRF-TOKEN=6ca05baa-f690-47d8-9846-f40494f68bfb; JSESSIONID=node01bwz57l8txz9u1ruarpcm7ks2o36469.node0; serverTime=1745912040923; sessionExpiry=1745998440923; SESSION=83f04cfd-2bc0-44b6-b1d3-04e75aa838d4' \
  -H 'Origin: http://vm-geomatique.lan.cereg.com' \
  -H 'Referer: http://vm-geomatique.lan.cereg.com/' \
  -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36' \
  -H 'X-XSRF-TOKEN: 6ca05baa-f690-47d8-9846-f40494f68bfb' \
  -H 'accept: application/json' \
  --insecure

{"message":"A file MUST be provided.","code":"unsatisfied_request_parameter","description":null}

HTTP/1.1 400 Bad Request
Access-Control-Allow-Credentials: true
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: X-Requested-With, Content-Type
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS
Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 1800
Content-Security-Policy: frame-ancestors 'self'
Content-Type: application/json
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Referrer-Policy: strict-origin
Server: Caddy
Set-Cookie: serverTime=1745912090153; Path=/geonetwork
Set-Cookie: sessionExpiry=1745998490153; Path=/geonetwork
Strict-Transport-Security: max-age=631138519
Vary: Origin
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Frame-Options: SAMEORIGIN
X-Permitted-Cross-Domain-Policies: none
X-Xss-Protection: 0
Date: Tue, 29 Apr 2025 07:34:50 GMT
Transfer-Encoding: chunked
X-Content-Encoding-Over-Network: gzip

Olivia Guyot

unread,
May 5, 2025, 8:29:04 AMMay 5
to georc...@googlegroups.com
Pour le point 1 : je pense que si tu ajoutes un header "Content-type: application/json" à ta requête, ça devrait marcher. A mon avis c'est un problème de documentation de l'API de GeoNetwork : celle-ci ne devrait pas exiger un Content-type puisque le body pour cette requête est vide. La modification est probablement à faire ici :


Pour le 2e point : l'erreur que tu as remonté ("a file MUST be provided") nous a été remontée aussi par un client, et je penche pour une erreur de documentation de l'API là aussi. Le code concerné est ici :


Conclusion : il faudrait corriger ces deux points sur GeoNetwork upstream :)
--
camptocamp
INNOVATIVE SOLUTIONS
BY OPEN SOURCE EXPERTS

Olivia Guyot
Geospatial Developer

Thomas Zucchiatti

unread,
May 13, 2025, 6:35:52 AM (10 days ago) May 13
to georchestra
Bonjour, 

Effectivement, en rajoutant un header dans mon script la requête a bien fonctionné et cela va me permettre de faire ce que je voulais. Je vous remercie grandement. 

Egalement, j'ai fait quelques recherches concernant le fichier que vous m'aviez partagé et je suis tombé sur ce blog où un utilisateur se confrontait à un problème relativement similaire. On peut voir sous le post dans les réponses, qu'un utilisateur a partagé une solution pour l'erreur "Content type " " not supported" qui s'apparentent exactement à la notre. En fait, il faudrait simplement supprimer la ligne consumes= APPLICATION_JSON_VALUE et la requête depuis l'interface serait à nouveau possible. Il se trouve que cette ligne est effectivement présente dans le morceau de code du MetadataInsertDeleteApi.java que vous m'aviez partagé. J'ai essayé de modifier ça de mon côté pour tester mais je n'ai pas réussi à recompiler mon .java en .class (notamment à cause de la classe anonyme) pour le remettre correctement dans le .jar et mettre à jour mon conteneur, j'imagine que toucher à cette partie là du code est un peu au delà de mes compétences, et je ne suis pas non plus certain de cerner exactement ce qu'implique la suppression de ce morceau du code, mais si jamais ça peut servir à résoudre le problème sur Swagger UI je me dis que c'est une bonne idée de vous en parler. 

Pour le deuxième point on voit dans le code un produces = {MediaType.APPLICATION_JSON_VALUE}. Est ce que le modifier en produces = {MediaType.APPLICATION_XML_VALUE} ne serait pas plus logique puisque l'utilisateur est sensé y intégrer un XML ?

Cordialement

Thomas Zucchiatti
Reply all
Reply to author
Forward
0 new messages