Commit 0eb7423d authored by Bertrand Gauthier's avatar Bertrand Gauthier
Browse files

Correction de l'import forcé de thèse : utilisation du unicaen/db-import pour...

Correction de l'import forcé de thèse : utilisation du unicaen/db-import pour synchroniser après l'import des données.
parent 21325959
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@ Journal des modifications
- Résolution du problème de plantage lorsque le flux des actualités est erroné.
- Interface de gestion des comptes locaux pour les présidents de jury.
- Test d'archivabilité : possibilité de configurer le passage par un proxy.
- Correction de l'import forcé de thèse : utilisation du unicaen/db-import pour synchroniser après l'import des données.

2.1.4
-----
+1 −1
Original line number Diff line number Diff line
@@ -28,7 +28,7 @@
        "unicaen/auth":                  "^3.1",
        "unicaen/bjy-authorize":         "^3.0",
        "unicaen/code":                  "^3.0",
        "unicaen/db-import":             "dev-master",
        "unicaen/db-import":             "^3.1",
        "unicaen/faq":                   "^3.0",
        "unicaen/ldap":                  "^3.0",
        "unicaen/oracle":                "^3.0",
+5 −7
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@
        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
        "This file is @generated automatically"
    ],
    "content-hash": "967f7b9f94d78716af6109beff1d972f",
    "content-hash": "9a32749766400559d0b7f87218c03e2b",
    "packages": [
        {
            "name": "beberlei/assert",
@@ -3512,11 +3512,11 @@
        },
        {
            "name": "unicaen/db-import",
            "version": "dev-master",
            "version": "3.1.1",
            "source": {
                "type": "git",
                "url": "https://git.unicaen.fr/lib/unicaen/db-import.git",
                "reference": "00c0d05799f8e2edcbf9989b36a43f787ba26c5e"
                "reference": "87a2150a5bc845f5c242db5c18eb526a37fd5281"
            },
            "require": {
                "beberlei/assert": "^2.7",
@@ -3546,7 +3546,7 @@
                }
            },
            "description": "Module d'import entre bases de données",
            "time": "2020-09-07T11:56:55+00:00"
            "time": "2021-02-01T14:49:44+00:00"
        },
        {
            "name": "unicaen/faq",
@@ -7954,9 +7954,7 @@
    ],
    "aliases": [],
    "minimum-stability": "stable",
    "stability-flags": {
        "unicaen/db-import": 20
    },
    "stability-flags": [],
    "prefer-stable": false,
    "prefer-lowest": false,
    "platform": {
+4 −0
Original line number Diff line number Diff line
@@ -13,8 +13,12 @@ class SynchroServiceFactory
        /** @var EntityManager $entityManager */
        $entityManager = $container->get('doctrine.entitymanager.orm_default');

        /** @var \UnicaenDbImport\Service\SynchroService $synchroService */
        $synchroService = $container->get(\UnicaenDbImport\Service\SynchroService::class);

        $service = new SynchroService();
        $service->setEntityManager($entityManager);
        $service->setSynchroService($synchroService);

        return $service;
    }
+26 −99
Original line number Diff line number Diff line
@@ -4,12 +4,12 @@ namespace Import\Service;

use DateTime;
use Doctrine\DBAL\ConnectionException;
use Doctrine\DBAL\DBALException;
use Exception;
use Import\Model\SynchroLog;
use UnicaenApp\Exception\LogicException;
use UnicaenApp\Exception\RuntimeException;
use UnicaenApp\Service\EntityManagerAwareTrait;
use Zend\Filter\Word\DashToUnderscore;
use UnicaenDbImport\Service\Traits\SynchroServiceAwareTrait as DbImportSynchroServiceAwareTrait;

/**
 * Service chargé de réaliser la synchro UnicaenImport en base de données.
@@ -19,6 +19,7 @@ use Zend\Filter\Word\DashToUnderscore;
class SynchroService
{
    use EntityManagerAwareTrait;
    use DbImportSynchroServiceAwareTrait;

    private $services = [];

@@ -27,23 +28,13 @@ class SynchroService
     * @param array $params Ex: ['sql_filter' => "SOURCE_CODE = ''UCN::21311123''"]
     * @return self
     */
    public function addService($service, array $params = [])
    public function addService(string $service, array $params = []): self
    {
        $this->services[$service] = $params;

        return $this;
    }

    /**
     * @return self
     */
    public function removeAllServices()
    {
        $this->services = [];

        return $this;
    }

    /**
     * Lance la synchro des données par UnicaenImport pour tous les services inscrits.
     */
@@ -53,18 +44,19 @@ class SynchroService
            throw new LogicException("Aucun service à synchroniser");
        }

        // ajout en premier des appels de procédures permettant d'enregistrer certains changements durant la synchro
        $calls = $this->getProcedureCallsForStoringObservImportResults();

        // détermination des appels de procédures de synchro à faire
        foreach ($this->services as $service => $params) {
            $sqlFilter = isset($params['sql_filter']) ? $params['sql_filter'] : [];
            $calls = array_merge($calls, $this->getProcedureCallsForImportingService($service, $sqlFilter));
        foreach ($this->services as $name => $params) {
            $synchro = $this->synchroService->getSynchroByName($name);
            $result = $this->synchroService->runSynchro($synchro);
            if ($exception = $result->getFailure()) {
                throw new RuntimeException(
                    sprintf("Erreur rencontrée pendant la synchro '%s'", $synchro->getName()),
                    null,
                    $result->getFailure());
            }
        // suppression des appels en double EN CONSERVANT LE DERNIER appel et non le premier
        $calls = array_reverse(array_unique(array_reverse($calls)));

        $this->executeProcedureCalls($calls);
        }
        $this->executeProcedureCalls([
            $this->backgroundify("DBMS_MVIEW.REFRESH('MV_RECHERCHE_THESE', 'C');"),
        ]);
    }

    /**
@@ -83,7 +75,7 @@ class SynchroService
            $connection->commit();
            $success = true;
            $message = null;
        } catch (DBALException $e) {
        } catch (Exception $e) {
            $success = false;
            $message = "Erreur rencontrée lors de l'exécution des procédures de synchro (import) : " . PHP_EOL . $e->getMessage();
            try {
@@ -102,71 +94,6 @@ class SynchroService
        }
    }

    /**
     * Retourne les appels de procédures permettant d'enregistrer certains changements durant la synchro.
     *
     * @return string[]
     */
    private function getProcedureCallsForStoringObservImportResults()
    {
        return [
            'APP_IMPORT.STORE_OBSERV_RESULTS();',
        ];
    }

    /**
     * Retourne, pour un service donné, les appels ORDONNÉS de procédures de synchronisation à lancer.
     *
     * @param string $serviceName
     * @param string $sqlFilter
     * @return string[]
     */
    private function getProcedureCallsForImportingService($serviceName, $sqlFilter = null)
    {
        $sqlFilterSnippet = $sqlFilter ? "'WHERE " . str_replace("'", "''", $sqlFilter) . "'" : '';

        // config de base pour les services où :
        // - il n'y a qu'une procédure à appeler, et
        // - le nom de cette procédure peut être déduite du nom du service.
        $defaultConfig = [];
        $f = new DashToUnderscore();
        foreach (ImportService::SERVICES as $service) {
            $procName = 'MAJ_' . strtoupper($f->filter($service)); // ex: 'titre-acces' => 'MAJ_TITRE_ACCES'
            $defaultConfig[$service] = [
                "UNICAEN_IMPORT.$procName($sqlFilterSnippet);",
            ];
        }

        // modif de la config de base pour certains services
        $config = array_merge($defaultConfig, [
            'ecole-doctorale' => [
                "UNICAEN_IMPORT.MAJ_ECOLE_DOCT($sqlFilterSnippet);",
                $this->backgroundify("APP_IMPORT.REFRESH_MV('MV_RECHERCHE_THESE');"),
            ],
            'unite-recherche' => [
                "UNICAEN_IMPORT.MAJ_UNITE_RECH($sqlFilterSnippet);",
            ],
            'doctorant'       => [
                "UNICAEN_IMPORT.MAJ_DOCTORANT($sqlFilterSnippet);",
                $this->backgroundify("APP_IMPORT.REFRESH_MV('MV_RECHERCHE_THESE');"),
            ],
            'these'           => [
                "UNICAEN_IMPORT.MAJ_THESE($sqlFilterSnippet);",
                $this->backgroundify("APP_IMPORT.REFRESH_MV('MV_RECHERCHE_THESE');"),
            ],
            'acteur'          => [
                "UNICAEN_IMPORT.MAJ_ACTEUR($sqlFilterSnippet);",
                $this->backgroundify("APP_IMPORT.REFRESH_MV('MV_RECHERCHE_THESE');"),
            ],
        ]);

        if (!array_key_exists($serviceName, $config)) {
            throw new LogicException("Service spécifié inattendu : '$serviceName'.'");
        }

        return $config[$serviceName];
    }

    /**
     * Génère le code PL/SQL permettant de lancer du PL/SQL en tâche de fond.
     *
@@ -174,7 +101,7 @@ class SynchroService
     * @param int $secondsToWait
     * @return string
     */
    private function backgroundify($plsql, $secondsToWait = 0)
    private function backgroundify(string $plsql, $secondsToWait = 0): string
    {
        $nextDateSql = 'SYSDATE';
        if ($secondsToWait > 0) {
@@ -198,9 +125,9 @@ EOS;
     * @param DateTime $finishDate
     * @param string $sql
     * @param string $status
     * @param string    $message
     * @param null $message
     */
    private function log(DateTime $startDate, DateTime $finishDate, $sql, $status, $message = null)
    private function log(DateTime $startDate, DateTime $finishDate, string $sql, string $status, $message = null)
    {
        $log = (new SynchroLog())
            ->setLogDate(date_create())
@@ -210,10 +137,10 @@ EOS;
            ->setStatus($status)
            ->setMessage($message);

        $this->entityManager->persist($log);
        try {
            $this->entityManager->persist($log);
            $this->entityManager->flush($log);
        } catch (\Exception $e) {
        } catch (Exception $e) {
            throw new RuntimeException("Erreur rencontrée lors de l'enregistrement du SynchroLog.", null, $e);
        }
    }