From c68577f3b12090c972edaa45c4ff257726694cc3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Agneray?= <francois.agneray@lam.fr>
Date: Mon, 14 Mar 2022 15:15:29 +0100
Subject: [PATCH] Fixed bugs + add data path env (archive, result)

---
 client/src/app/admin/admin.component.ts       |  2 ++
 .../effects/dataset-family.effects.ts         |  4 ----
 .../containers/portal-home.component.ts       |  2 ++
 .../shared/components/navbar.component.html   |  7 ++++++-
 docker-compose.yml                            |  4 ++++
 server/app/dependencies.php                   |  8 ++++----
 server/app/settings.php                       |  2 ++
 server/src/Action/DownloadArchiveAction.php   | 19 ++++++++++++++-----
 server/src/Action/DownloadResultAction.php    | 19 ++++++++++++++-----
 .../src/Action/IsArchiveAvailableAction.php   | 19 ++++++++++++++-----
 server/src/Action/IsResultAvailableAction.php | 19 ++++++++++++++-----
 tasks/.gitlab-ci.yml                          | 15 +++++++++++++++
 tasks/src/anis_tasks/archive.py               |  3 ++-
 tasks/src/anis_tasks/result.py                |  3 ++-
 tasks/src/anis_tasks/utils.py                 | 14 ++++++++++++++
 15 files changed, 109 insertions(+), 31 deletions(-)

diff --git a/client/src/app/admin/admin.component.ts b/client/src/app/admin/admin.component.ts
index cce79cb1..57ebd0e4 100644
--- a/client/src/app/admin/admin.component.ts
+++ b/client/src/app/admin/admin.component.ts
@@ -34,6 +34,7 @@ import { AppConfigService } from 'src/app/app-config.service';
  */
 export class AdminComponent implements OnInit {
     public favIcon: HTMLLinkElement = document.querySelector('#favicon');
+    public title: HTMLLinkElement = document.querySelector('#title');
     public links = [
         { label: 'Instances', icon: 'fas fa-object-group', routerLink: 'instance/instance-list' },
         { label: 'Surveys', icon: 'fas fa-table', routerLink: 'survey/survey-list'},
@@ -54,6 +55,7 @@ export class AdminComponent implements OnInit {
 
     ngOnInit() {
         this.favIcon.href = 'favicon.ico';
+        this.title.innerHTML = 'ANIS - Admin';
         Promise.resolve(null).then(() => this.store.dispatch(surveyActions.loadSurveyList()));
         Promise.resolve(null).then(() => this.store.dispatch(databaseActions.loadDatabaseList()));
         Promise.resolve(null).then(() => this.store.dispatch(selectActions.loadSelectList()));
diff --git a/client/src/app/metamodel/effects/dataset-family.effects.ts b/client/src/app/metamodel/effects/dataset-family.effects.ts
index c2a3925a..5a23acdd 100644
--- a/client/src/app/metamodel/effects/dataset-family.effects.ts
+++ b/client/src/app/metamodel/effects/dataset-family.effects.ts
@@ -8,7 +8,6 @@
  */
 
 import { Injectable } from '@angular/core';
-import { Router } from '@angular/router';
 
 import { Actions, createEffect, ofType, concatLatestFrom } from '@ngrx/effects';
 import { Store } from '@ngrx/store';
@@ -68,7 +67,6 @@ export class DatasetFamilyEffects {
             ofType(datasetFamilyActions.addDatasetFamilySuccess),
             concatLatestFrom(() => this.store.select(instanceSelector.selectInstanceNameByRoute)),
             tap(([, instanceName]) => {
-                this.router.navigate([`/admin/configure-instance/${instanceName}`]);
                 this.toastr.success('Dataset family successfully added', 'The new dataset family was added into the database')
             })
         ), { dispatch: false }
@@ -107,7 +105,6 @@ export class DatasetFamilyEffects {
             ofType(datasetFamilyActions.editDatasetFamilySuccess),
             concatLatestFrom(() => this.store.select(instanceSelector.selectInstanceNameByRoute)),
             tap(([action, instanceName]) => {
-                this.router.navigate([`/admin/configure-instance/${instanceName}`]);
                 this.toastr.success('Dataset family successfully edited', 'The existing dataset family has been edited into the database')
             })
         ), { dispatch: false }
@@ -161,7 +158,6 @@ export class DatasetFamilyEffects {
     constructor(
         private actions$: Actions,
         private datasetFamilyService: DatasetFamilyService,
-        private router: Router,
         private toastr: ToastrService,
         private store: Store<{ }>
     ) {}
diff --git a/client/src/app/portal/containers/portal-home.component.ts b/client/src/app/portal/containers/portal-home.component.ts
index 0b6160c8..6ec0b9d5 100644
--- a/client/src/app/portal/containers/portal-home.component.ts
+++ b/client/src/app/portal/containers/portal-home.component.ts
@@ -33,6 +33,7 @@ import { AppConfigService } from 'src/app/app-config.service';
 })
 export class PortalHomeComponent implements OnInit {
     public favIcon: HTMLLinkElement = document.querySelector('#favicon');
+    public title: HTMLLinkElement = document.querySelector('#title');
     public links = [];
     public isAuthenticated: Observable<boolean>;
     public userProfile: Observable<UserProfile>;
@@ -51,6 +52,7 @@ export class PortalHomeComponent implements OnInit {
 
     ngOnInit() {
         this.favIcon.href = 'favicon.ico';
+        this.title.innerHTML = 'ANIS - Portal';
     }
 
     /**
diff --git a/client/src/app/shared/components/navbar.component.html b/client/src/app/shared/components/navbar.component.html
index fd2da6ba..17f37000 100644
--- a/client/src/app/shared/components/navbar.component.html
+++ b/client/src/app/shared/components/navbar.component.html
@@ -88,7 +88,12 @@
                     <span class="fa-solid fa-right-to-bracket fa-fw"></span> Back to portal
                 </a>
             </li>
-            <li *ngIf="isAuthenticated" class="divider dropdown-divider"></li>
+            <li *ngIf="isAuthenticated || (!authenticationEnabled && !isAdminRoute())" class="divider dropdown-divider"></li>
+            <li *ngIf="!authenticationEnabled && !isAdminRoute()" role="menuitem">
+                <a class="dropdown-item pointer" routerLink="/admin">
+                    <span class="fas fa-tools"></span> Admin
+                </a>
+            </li>
             <li *ngIf="isAuthenticated" role="menuitem">
                 <a *ngIf="isAdmin() && !isAdminRoute()" class="dropdown-item pointer" routerLink="/admin">
                     <span class="fas fa-tools"></span> Admin
diff --git a/docker-compose.yml b/docker-compose.yml
index 463a5f3c..06b8074d 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -26,6 +26,8 @@ services:
             DATABASE_CO_USER: "postgres"
             DATABASE_CO_PASSWORD: "postgres"
             DATA_PATH: "/data"
+            ARCHIVE_FOLDER: "/ARCHIVE"
+            RESULT_FOLDER: "/RESULT"
             LOGGER_NAME: "anis-metamodel"
             LOGGER_PATH: "php://stderr"
             LOGGER_LEVEL: "debug"
@@ -71,6 +73,8 @@ services:
         environment:
             PYTHONPATH: "/project/src"
             DATA_PATH: /data
+            ARCHIVE_FOLDER: "/ARCHIVE"
+            RESULT_FOLDER: "/RESULT"
             SERVER_URL: http://server
             RMQ_HOST: rmq
             RMQ_PORT: 5672
diff --git a/server/app/dependencies.php b/server/app/dependencies.php
index c8d86647..42d875cc 100644
--- a/server/app/dependencies.php
+++ b/server/app/dependencies.php
@@ -216,11 +216,11 @@ $container->set('App\Action\StartTaskCreateResultAction', function (ContainerInt
 });
 
 $container->set('App\Action\IsResultAvailableAction', function (ContainerInterface $c) {
-    return new App\Action\IsResultAvailableAction($c->get('em'), $c->get('settings')['data_path'], $c->get(SETTINGS)['token']);
+    return new App\Action\IsResultAvailableAction($c->get('em'), $c->get('settings')['data_path'], $c->get('settings')['result_folder'], $c->get(SETTINGS)['token']);
 });
 
 $container->set('App\Action\DownloadResultAction', function (ContainerInterface $c) {
-    return new App\Action\DownloadResultAction($c->get('em'), $c->get('settings')['data_path'], $c->get(SETTINGS)['token']);
+    return new App\Action\DownloadResultAction($c->get('em'), $c->get('settings')['data_path'], $c->get('settings')['result_folder'], $c->get(SETTINGS)['token']);
 });
 
 $container->set('App\Action\StartTaskCreateArchiveAction', function (ContainerInterface $c) {
@@ -228,11 +228,11 @@ $container->set('App\Action\StartTaskCreateArchiveAction', function (ContainerIn
 });
 
 $container->set('App\Action\IsArchiveAvailableAction', function (ContainerInterface $c) {
-    return new App\Action\IsArchiveAvailableAction($c->get('em'), $c->get('settings')['data_path'], $c->get(SETTINGS)['token']);
+    return new App\Action\IsArchiveAvailableAction($c->get('em'), $c->get('settings')['data_path'], $c->get('settings')['archive_folder'], $c->get(SETTINGS)['token']);
 });
 
 $container->set('App\Action\DownloadArchiveAction', function (ContainerInterface $c) {
-    return new App\Action\DownloadArchiveAction($c->get('em'), $c->get('settings')['data_path'], $c->get(SETTINGS)['token']);
+    return new App\Action\DownloadArchiveAction($c->get('em'), $c->get('settings')['data_path'], $c->get('settings')['archive_folder'], $c->get(SETTINGS)['token']);
 });
 
 $container->set('App\Action\DatasetFileExplorerAction', function (ContainerInterface $c) {
diff --git a/server/app/settings.php b/server/app/settings.php
index b4811106..e062e3ef 100644
--- a/server/app/settings.php
+++ b/server/app/settings.php
@@ -26,6 +26,8 @@ return [
         ],
     ],
     'data_path' => getenv('DATA_PATH'),
+    'archive_folder' => getenv('ARCHIVE_FOLDER'),
+    'result_folder' => getenv('RESULT_FOLDER'),
     'logger' => [
         'name' => getenv('LOGGER_NAME'),
         'path' => getenv('LOGGER_PATH'),
diff --git a/server/src/Action/DownloadArchiveAction.php b/server/src/Action/DownloadArchiveAction.php
index b514baae..255fc5aa 100644
--- a/server/src/Action/DownloadArchiveAction.php
+++ b/server/src/Action/DownloadArchiveAction.php
@@ -31,6 +31,13 @@ final class DownloadArchiveAction extends AbstractAction
      */
     private $dataPath;
 
+    /**
+     * Contains archive folder path
+     *
+     * @var string
+     */
+    private $archiveFolder;
+
     /**
      * Contains settings to handle Json Web Token
      *
@@ -41,14 +48,16 @@ final class DownloadArchiveAction extends AbstractAction
     /**
      * Create the classe before call __invoke to execute the action
      *
-     * @param EntityManagerInterface $em       Doctrine Entity Manager Interface
-     * @param string                 $dataPath Contains anis-server data path
-     * @param array                  $settings Settings about token
+     * @param EntityManagerInterface $em            Doctrine Entity Manager Interface
+     * @param string                 $dataPath      Contains anis-server data path
+     * @param string                 $archiveFolder Contains archive folder path
+     * @param array                  $settings      Settings about token
      */
-    public function __construct(EntityManagerInterface $em, string $dataPath, array $settings)
+    public function __construct(EntityManagerInterface $em, string $dataPath, string $archiveFolder, array $settings)
     {
         parent::__construct($em);
         $this->dataPath = $dataPath;
+        $this->archiveFolder = $archiveFolder;
         $this->settings = $settings;
     }
 
@@ -89,7 +98,7 @@ final class DownloadArchiveAction extends AbstractAction
 
         // Search the file
         $archiveId = $args['id'];
-        $filePath = $this->dataPath . '/ARCHIVE/' . $archiveId . '.zip';
+        $filePath = $this->dataPath . $this->archiveFolder . '/' . $archiveId . '.zip';
 
         // If the file not found 404
         if (!file_exists($filePath)) {
diff --git a/server/src/Action/DownloadResultAction.php b/server/src/Action/DownloadResultAction.php
index 2413fa29..367fe5f8 100644
--- a/server/src/Action/DownloadResultAction.php
+++ b/server/src/Action/DownloadResultAction.php
@@ -31,6 +31,13 @@ final class DownloadResultAction extends AbstractAction
      */
     private $dataPath;
 
+    /**
+     * Contains result folder path
+     *
+     * @var array
+     */
+    private $resultFolder;
+
     /**
      * Contains settings to handle Json Web Token
      *
@@ -41,14 +48,16 @@ final class DownloadResultAction extends AbstractAction
     /**
      * Create the classe before call __invoke to execute the action
      *
-     * @param EntityManagerInterface $em       Doctrine Entity Manager Interface
-     * @param string                 $dataPath Contains anis-server data path
-     * @param array                  $settings Settings about token
+     * @param EntityManagerInterface $em           Doctrine Entity Manager Interface
+     * @param string                 $dataPath     Contains anis-server data path
+     * @param string                 $resultFolder Contains result folder path
+     * @param array                  $settings     Settings about token
      */
-    public function __construct(EntityManagerInterface $em, string $dataPath, array $settings)
+    public function __construct(EntityManagerInterface $em, string $dataPath, string $resultFolder, array $settings)
     {
         parent::__construct($em);
         $this->dataPath = $dataPath;
+        $this->resultFolder = $resultFolder;
         $this->settings = $settings;
     }
 
@@ -89,7 +98,7 @@ final class DownloadResultAction extends AbstractAction
 
         // Search the file
         $fileId = $args['id'];
-        $filePath = $this->dataPath . '/RESULT/' . $fileId;
+        $filePath = $this->dataPath . $this->resultFolder . '/' . $fileId;
 
         // If the file not found 404
         if (!file_exists($filePath)) {
diff --git a/server/src/Action/IsArchiveAvailableAction.php b/server/src/Action/IsArchiveAvailableAction.php
index b993e1d5..2ae63b27 100644
--- a/server/src/Action/IsArchiveAvailableAction.php
+++ b/server/src/Action/IsArchiveAvailableAction.php
@@ -31,6 +31,13 @@ final class IsArchiveAvailableAction extends AbstractAction
      */
     private $dataPath;
 
+    /**
+     * Contains archive folder path
+     *
+     * @var string
+     */
+    private $archiveFolder;
+
     /**
      * Contains settings to handle Json Web Token
      *
@@ -41,14 +48,16 @@ final class IsArchiveAvailableAction extends AbstractAction
     /**
      * Create the classe before call __invoke to execute the action
      *
-     * @param EntityManagerInterface $em       Doctrine Entity Manager Interface
-     * @param string                 $dataPath Contains anis-server data path
-     * @param array                  $settings Settings about token
+     * @param EntityManagerInterface $em            Doctrine Entity Manager Interface
+     * @param string                 $dataPath      Contains anis-server data path
+     * @param string                 $archiveFolder Contains archive folder path
+     * @param array                  $settings      Settings about token
      */
-    public function __construct(EntityManagerInterface $em, string $dataPath, array $settings)
+    public function __construct(EntityManagerInterface $em, string $dataPath, string $archiveFolder, array $settings)
     {
         parent::__construct($em);
         $this->dataPath = $dataPath;
+        $this->archiveFolder = $archiveFolder;
         $this->settings = $settings;
     }
 
@@ -70,7 +79,7 @@ final class IsArchiveAvailableAction extends AbstractAction
         $archiveId = $args['id'];
 
         // Search the file
-        $filePath = $this->dataPath . '/ARCHIVE/' . $archiveId . '.zip';
+        $filePath = $this->dataPath . $this->archiveFolder . '/' . $archiveId . '.zip';
 
         $isAvailable = false;
         if (file_exists($filePath)) {
diff --git a/server/src/Action/IsResultAvailableAction.php b/server/src/Action/IsResultAvailableAction.php
index 64bba6e7..c9503fe5 100644
--- a/server/src/Action/IsResultAvailableAction.php
+++ b/server/src/Action/IsResultAvailableAction.php
@@ -31,6 +31,13 @@ final class IsResultAvailableAction extends AbstractAction
      */
     private $dataPath;
 
+    /**
+     * Contains result folder path
+     *
+     * @var array
+     */
+    private $resultFolder;
+
     /**
      * Contains settings to handle Json Web Token
      *
@@ -41,14 +48,16 @@ final class IsResultAvailableAction extends AbstractAction
     /**
      * Create the classe before call __invoke to execute the action
      *
-     * @param EntityManagerInterface $em       Doctrine Entity Manager Interface
-     * @param string                 $dataPath Contains anis-server data path
-     * @param array                  $settings Settings about token
+     * @param EntityManagerInterface $em           Doctrine Entity Manager Interface
+     * @param string                 $dataPath     Contains anis-server data path
+     * @param string                 $resultFolder Contains result folder path
+     * @param array                  $settings     Settings about token
      */
-    public function __construct(EntityManagerInterface $em, string $dataPath, array $settings)
+    public function __construct(EntityManagerInterface $em, string $dataPath, string $resultFolder, array $settings)
     {
         parent::__construct($em);
         $this->dataPath = $dataPath;
+        $this->resultFolder = $resultFolder;
         $this->settings = $settings;
     }
 
@@ -70,7 +79,7 @@ final class IsResultAvailableAction extends AbstractAction
         $fileId = $args['id'];
 
         // Search the file
-        $filePath = $this->dataPath . '/RESULT/' . $fileId;
+        $filePath = $this->dataPath . $this->resultFolder . '/' . $fileId;
 
         $isAvailable = false;
         if (file_exists($filePath)) {
diff --git a/tasks/.gitlab-ci.yml b/tasks/.gitlab-ci.yml
index 2ffae8b5..e157cec8 100644
--- a/tasks/.gitlab-ci.yml
+++ b/tasks/.gitlab-ci.yml
@@ -1,5 +1,6 @@
 stages:
     - dockerize
+    - deploy
 
 variables:
     VERSION: "3.7"
@@ -15,3 +16,17 @@ dockerize:
         - docker pull $CI_REGISTRY/anis/anis-next/tasks:latest || true
         - docker build --cache-from $CI_REGISTRY/anis/anis-next/tasks:latest -t $CI_REGISTRY/anis/anis-next/tasks:latest .
         - docker push $CI_REGISTRY/anis/anis-next/tasks:latest
+
+deploy:
+    image: alpine
+    stage: deploy
+    variables:
+        GIT_STRATEGY: none
+    cache: {}
+    dependencies: []
+    script:
+        - apk add --update curl
+        - curl -XPOST $DEV_WEBHOOK_TASKS
+    only:
+        refs:
+            - develop
diff --git a/tasks/src/anis_tasks/archive.py b/tasks/src/anis_tasks/archive.py
index 2e93e389..b265813a 100644
--- a/tasks/src/anis_tasks/archive.py
+++ b/tasks/src/anis_tasks/archive.py
@@ -21,7 +21,8 @@ def archive_handler(ch, method, properties, body):
 
     # create a ZipFile object
     data_path = utils.get_data_path()
-    zip_path = data_path + "/ARCHIVE/" + message["archive_id"] + ".zip"
+    archive_folder = utils.get_archive_folder()
+    zip_path = data_path + archive_folder + "/" + message["archive_id"] + ".zip"
     zip = ZipFile(zip_path + ".tmp", 'w')
 
     # Search files
diff --git a/tasks/src/anis_tasks/result.py b/tasks/src/anis_tasks/result.py
index 27ac73df..f66573e5 100644
--- a/tasks/src/anis_tasks/result.py
+++ b/tasks/src/anis_tasks/result.py
@@ -16,7 +16,8 @@ def result_handler(ch, method, properties, body):
 
     # create a File object
     data_path = utils.get_data_path()
-    file_path = data_path + "/RESULT/" + message["file_id"]
+    result_folder = utils.get_result_folder()
+    file_path = data_path + result_folder + "/" + message["file_id"]
     file = open(file_path + ".tmp", "w")
 
     # Write data
diff --git a/tasks/src/anis_tasks/utils.py b/tasks/src/anis_tasks/utils.py
index ae43a76b..9eb29360 100644
--- a/tasks/src/anis_tasks/utils.py
+++ b/tasks/src/anis_tasks/utils.py
@@ -10,6 +10,8 @@ def check_config():
     """
     check_keys = {
         'DATA_PATH',
+        'ARCHIVE_FOLDER',
+        'RESULT_FOLDER',
         'SERVER_URL',
         'RMQ_HOST',
         'RMQ_PORT',
@@ -26,6 +28,18 @@ def get_data_path():
     """
     return os.environ['DATA_PATH']
 
+def get_archive_folder():
+    """
+    Get ANIS archive folder path
+    """
+    return os.environ['ARCHIVE_FOLDER']
+
+def get_result_folder():
+    """
+    Get ANIS result folder path
+    """
+    return os.environ['RESULT_FOLDER']
+
 def get_server_url():
     """
     Get ANIS server URL
-- 
GitLab