Skip to main content

PMB — détails techniques

Fiche fonctionnelle

Description et fonctionnalités de ce module : PMB.

Nature et rôle

Module ENT pmb-connector (rangé dans connectors/, comme moodle-connector) : passerelle vers un catalogue CDI externe, qui alimente le médiacentre en notices bibliographiques via fr.openent.mediacentre.source.PMB. Il n'héberge aucune notice : il en dépose une copie dans l'index du médiacentre à chaque moissonnage (amass).

  • Schéma SQL dédié pmb (db-schema), table pmb.etablissement.
  • Protocole vers PMB : webservice apijsonrpc (ws/connector_out.php?source_id=…), authentification Basic.
  • Droit workflow pmb.structure.export pour les routes d'export d'annuaire.

Un serveur PMB par établissement

host/endpoint/source_id/credentials ne sont pas une configuration globale du module dans ent-core.yaml, mais une donnée par établissement :

CREATE TABLE pmb.etablissement (
id bigserial PRIMARY KEY,
idneo VARCHAR(36),
uai VARCHAR(8),
nom VARCHAR(50) NOT NULL,
principal boolean NOT NULL DEFAULT FALSE,
id_principal bigint,
pmb_host VARCHAR,
pmb_endpoint VARCHAR,
pmb_source_id VARCHAR,
pmb_username VARCHAR,
pmb_password VARCHAR,
pmb_page_size INTEGER,
pmb_opac_url VARCHAR
);

PMBServer n'est pas une instance unique mais un registre par UAI (PMBServer.get(uai)), réenregistré à chaque relevé à partir de ces colonnes. Un établissement pas encore configuré est simplement ignoré (log + rapport), il ne fait pas échouer les autres.

id_principal sert à partager une connexion déjà configurée : cité scolaire (plusieurs UAI, un même CDI physique) ou catalogue régional/départemental mutualisé. Dans les deux cas, l'UAI secondaire laisse ses colonnes pmb_* vides et hérite de la connexion de la ligne visée par id_principal — établissement réel, ou simple ligne « virtuelle » ne portant que des identifiants de connexion partagés.

pmbSourceId est l'identifiant de la source de connecteur sortant apijsonrpc créée côté admin PMB (Administration › Connecteurs › Sortants › ajouter une source), pas un préfixe ou un nom de base : pmbEndpoint (ws/connector_out.php) n'accepte aucun paramètre database. Le webservice doit en outre être autorisé pour un groupe d'utilisateurs externes (Administration › Utilisateurs externes) correspondant à pmbUsername/pmbPassword, comparés en clair côté PMB.

Routes et droits

RouteDroitUsage
GET /pmb/schoolssuper-administrateurlister TOUS les établissements connus du connecteur
GET /pmb/schools/minesuper-administrateur ou administrateur localétablissement(s) de l'utilisateur courant — filtrage sur user.getStructures()
POST /pmb/schoolssuper-administrateurcréer un établissement (idneo, uai, nom, principal, id_principal) — opération structurelle
PUT /pmb/schools/:schoolId/connectionsuper-administrateur ou administrateur local de cet établissementconfigurer sa connexion (pmbHost, pmbEndpoint, pmbSourceId, pmbUsername, pmbPassword, pmbPageSize)
DELETE /pmb/schools/:schoolIdsuper-administrateursupprimer un établissement
POST /pmb/email/sendutilisateur autorisé sur la ressourceemail de demande d'informations au prestataire PMB
GET /pmb/gestionnaire/list?uai=&type=cdi|pretworkflow pmb.structure.exportgestionnaires du CDI / gestionnaires de prêt
GET /pmb/user/structures/list?uai=&type=Student|Teacher|Personnelsuper-administrateurutilisateurs de l'établissement, pour les comptes emprunteurs

GET /schools/mine et PUT /schools/:id/connection acceptent AdminFilter (super-admin OU administrateur local), mais SchoolController vérifie en plus, pour un administrateur local, que l'idneo de l'établissement visé figure dans user.getStructures() — sans ce contrôle explicite, AdminFilter seul autoriserait un administrateur local à modifier la connexion de N'IMPORTE QUEL établissement.

Les listes de gestionnaires sont bâties sur deux groupes de l'annuaire, nommés dans la configuration du module (export.group_manager pour le CDI, export.group_manager_lend_manual pour le prêt).

BFF du dashboard

Le BFF (pages/api/admin/pmb/…) relaie la session ENT (cookies oneSessionId/XSRF-TOKEN, cf. _proxy.ts) vers les routes ci-dessus — pas de jeton statique comme pour WordPress, qui est un service tiers sans notion de session ENT. L'autorisation réelle est entièrement tranchée côté pmb-connector, pas dupliquée dans le BFF. L'email de demande d'informations part par le service configuré dans « Configuration des emails », pas par des variables d'environnement statiques. Écran et captures : Connexions PMB (CDI).

Prérequis : export PMB activé sur la structure (Neo4j)

Un établissement n'est moissonné que si son nœud Structure porte 'PMB' dans sa propriété exports (même mécanisme que les autres exports entcore) :

MATCH (s:Structure {UAI: '<uai>'})
SET s.exports = coalesce(s.exports, []) + 'PMB'

Sans ce flag, retrieveDeployedStructures() ne renvoie jamais l'établissement et l'amass tourne à vide silencieusement (log Stopping PMB amass worker: empty structures), même si sa connexion pmb_* est correctement remplie.

Configuration du module (ent-core.yaml)

CléRôle
PMB.page_sizedéfaut global (notices par page lors de l'amass), surchargeable par établissement (pmb_page_size)
db-schema: pmbschéma PostgreSQL du connecteur
export.group_manager / export.group_manager_lend_manualnoms des groupes de gestionnaires côté annuaire
infraMailexpéditeur de l'email de demande d'informations

Aucune autre clé (host/source_id/credentials) n'est attendue ici : elle proviendrait d'une configuration globale, remplacée par la configuration par établissement.

Déroulé d'un relevé (amass)

  1. Un cron (amass-cron, défaut 0 1 * * * ? *) déclenche AmassTask côté médiacentre, qui appelle .amass() sur chaque source configurée.
  2. PMB.amass() envoie un message sur le bus (fr.openent.pmb.controllers.PmbController|amass).
  3. PmbController.amass() récupère les établissements où le module est déployé et dont l'export PMB est activé, résout les regroupements id_principal, construit la configuration de connexion de chacun, puis déploie un AmassWorker (verticle worker).
  4. AmassWorker enregistre le PMBServer de chaque établissement (PMBServer.register), lance une recherche plein texte (pmbesSearch_simpleSearch) puis pagine les résultats (pmbesSearch_fetchSearchRecords).
  5. Chaque notice est convertie depuis l'UNIMARC (BibliographicRecord, UniMarcField) puis envoyée au médiacentre (fr.openent.mediacentre.source.PMB|records) pour indexation.

Liens OPAC posés sur les notices

BibliographicRecord.toJSON() porte deux liens, calculés sur l'OPAC et non sur pmb_host : <host>/index.php est le back-office de PMB, réservé aux gestionnaires du CDI — un élève qui suivait ce lien tombait sur l'authentification bibliothécaire.

ChampConstruction
link<opac>/index.php?lvl=notice_display&id=<id> — consultation de la notice
reservation_link<opac>/do_resa.php?lvl=resa&id_notice=<id> — exactement le lien que l'OPAC pose lui-même (opac_css/classes/record_datas.class.php, get_resas_datas)

L'OPAC est déduit de endpoint, qui porte le chemin d'installation de façon fiable (/pmb/ws/connector_out.php → racine /pmb → OPAC <host>/pmb/opac_css), le dispatcher des connecteurs sortants étant toujours à <racine PMB>/ws/connector_out.php. La colonne pmb_opac_url (migration 04-add-pmb-opac-url.sql) couvre les installations qui exposent l'OPAC ailleurs ; PMBServer trace l'URL retenue au moissonnage.

Le lien de réservation est posé sans condition : disponibilité d'un exemplaire, plafond de réservations et paramètre opac.resa sont des états que seul PMB connaît et qui changent entre deux moissonnages. C'est PMB qui refuse, avec son message. Côté médiacentre, le champ est porté par source/PMB.java dans l'index et rendu par SearchCard.tsx (mediacentre.card.reserve).

Connexion unique (CAS)

PmbRegisteredService (entcore, cas/src/main/java/org/entcore/cas/services/) résout les UAI de l'utilisateur puis interroge le bus (fr.openent.pmb.controllers.PmbController|getPrincipalUAIs) pour les remplacer par les UAI principaux. Un lecteur d'un établissement rattaché est donc présenté à PMB sous l'UAI du catalogue partagé, celui qui porte réellement ses comptes emprunteurs. Le ticket CAS suffit ensuite pour la consultation comme pour la réservation, y compris depuis le lien do_resa.php.

Diagnostic

SymptômeCause probableVérification
Stopping PMB amass worker: empty structuresaucun établissement avec 'PMB' IN s.exports (Neo4j)activer l'export PMB sur la structure
Établissement ignoré, log Configuration PMB incomplète pour l'établissement …colonnes pmb_* incomplètes en basePUT /pmb/schools/:schoolId/connection
No content to map due to end-of-input sur la réponse PMBwebservice PMB inaccessible, mauvais source_id/identifiants, ou réponse viderejouer l'appel en direct (curl -u <user>:<pwd> -X POST "<host><endpoint>?source_id=<id>" -d '{"method":"pmbesSearch_simpleSearch",...}')
No result for structure <uai> (empty PMB catalog?)recherche sans résultat ("result": null) — catalogue vide ou terme sans correspondanceattendu si le catalogue PMB de l'établissement ne contient aucune notice
Notices présentes mais sans bouton « Réserver au CDI »notices issues d'un moissonnage antérieur à pmb_opac_url / au champ reservation_linkrelancer un moissonnage
Lien de notice qui aboutit à une authentification bibliothécaireOPAC mal déduit (installation atypique)renseigner pmb_opac_url
Logs INFO de ce module invisibleslogger racine en WARN sans override pour fr.openent (tools/logback-ent.xml)ajouter un logger fr.openent en INFO

Couverture de tests

Le moissonnage et le webservice PMB lui-même n'ont pas de test e2e (pas de vrai serveur PMB en environnement de test) ; l'écran d'administration du dashboard, lui, est couvert par apps/dashboard-e2e/src/modules/03_admin/13_connexion_pmb_cdi.spec.ts — 3 scénarios, non destructifs (lecture/capture, aucune connexion n'est réellement enregistrée) :

  • accès à la page (pas de 5xx) ;
  • vue super-administrateur — tableau des établissements + ouverture du formulaire de connexion ;
  • vue administrateur local — connexion de son établissement, ou message si pas encore ajouté.

Le même fichier détecte le rôle via l'UI rendue et s'exécute pour tous les profils Playwright (superadmin, chef…), skippant proprement les scénarios non pertinents pour un profil donné.

Conformité

Évaluation au référentiel Open ENT NG (module pmb-connector).

Maillon de la chaîne qualitéRéférence
🎯 Fonctionnalités attenduesfiche fonctionnelle
🧪 Tests réalisésécran d'administration : couverture e2e ; moissonnage PMB : aucun test e2e à ce jour
✅ Tests de conformitétableau de conformité