asit-asso / extract Goto Github PK
View Code? Open in Web Editor NEWEXTRACT makes it easy to extract and deliver of your geodata
License: GNU General Public License v3.0
EXTRACT makes it easy to extract and deliver of your geodata
License: GNU General Public License v3.0
Original author : Yves Blatti
Maquettes
Ajout de fichiers et suppression :
Sélection pour ajout de plusieurs fichiers possible
Ajout de fichiers, si aucun fichier présent :
Confirmation de la suppression :
Pas de modification possible si traitement en cours (état actif) ou si traitement terminé/annulé
Critères d’acceptation
|.ID|.Critère|
|16831-1|Il est possible d'ajouter un ou plusieurs fichiers (en une sélection)|
|16831-2|Après l'ajout, on retrouve la même page, l'élément reste dans le même statut|
|16831-3|Si on upload un fichier avec des caractères spécieux, il est renommé (ex: @l'apéro.zip@ -> @l_apero.zip@)|
|16831-4|Si un fichier présent possède le même nom (après renommage, s'il a eu lieu), il est écrasé|
|16831-5|le champ d'upload est représenté par un bouton bootstrap (et non le champ par défaut du browser)|
|16831-6|Si la sélection est validée (écran de sélection du navigateur, 16831_add_multiple_files.png), les fichiers sont immédiatement uploadés|
|16831-7|Il est possible de supprimer un fichier (après confirmation)|
|16831-8|Si la suppression est annulée à la modale, aucune modification n'est apportée, et l'utilisateur reste sur la page|
Budget : 2948
Original author : Yves Blatti
Proposition lors de la rencontre du GU le 03.12.2018.
Un plugin de tâche pour exécuter des exécutables/batchs/scripts arbitraires.
Exemples d'utilisation :
A evaluer...
Original author : Rémi Bovard
C'est un détail mais les polices sont différentes entre le mail de validation et celui de notification.
Budget : 430
Original author : Xavier Mérour
Le plugin de notification email permet d'envoyer un message à un ou plusieurs destinataires.
Les emails des destinataires doivent être séparés par des points-virgules.
L'objet et le contenu du message peuvent contenir des variables qui seront remplacées par les propriétés de la requête. Les propriétés dynamiques autorisées sont les suivantes :
orderLabel
orderGuid
productGuid
productLabel
startDate
organism
client
Exemple d'objet : "Nouvelle demande pour le produit {productLabel}, client {client}"
Exemple de contenu : "Le client {client} (organism) a commandé le produit {productLabel}
N° de commande : {orderLabel}
Date de traitement : {startDate}
Les données livrées ont été archivées vers : /home/data/extract/archive/{orderLabel}/{productLabel}"
Maquettes
Critères d’acceptation
|.ID|.Critère|
|18705-1|Lorsqu'un élément est traité par ce plugin, un message est envoyé à chaque destinataire|
|18705-2|Les emails sont individuels, un destinataire ne voit pas les autres|
|18705-3|Les messages peuvent contenir des variables, qui seront remplacées par les valeurs lors de l’exécution|
|18705-4|La configuration email et SMTP provient de la configuration système d'EXTRACT (@https:///extract/parameters@)|
|18705-5|La liste des destinataires est splitée par virgule ou point-virgule et nettoyée de caractères invisibles. Par exemple: "@technique@asitvd, [email protected] ; [email protected]@" est valable pour 3 adresses.|
Budget : 2908
Original author : Yves Blatti
Les assets sont conservés en cache browser lors d'une mise à jour
Il faut versionner les assets
<link href="/extract/lib/bootstrap/dist/css/bootstrap.min.uneVersionGeneree.css" rel="stylesheet" type="text/css" />
ou éventuellement
<link href="/extract/lib/bootstrap/dist/css/bootstrap.min.css?v=uneVersionGeneree" rel="stylesheet" type="text/css" />
La version peut être aléatoire, provenir de la révision, ou être un hash du fichier.
Budget : 430
Original author : Rémi Bovard
Selon la maquette [1]:
Dans la v1.1:
[1] https://projets.asitvd.ch/issues/17758
Budget : 430
Original author : Yves Blatti
Lorsqu’un périmètre dépasse 4000 caractères la requête n’est pas importée.
Il faudrait utiliser un type TEXT dans postgres
LOG :
<code class="php">
16:24:33.866 78300921 [pool-8-thread-1] ERROR o.e.e.b.w.ImportedRequestsWriter - Could not save the imported requests.
org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:526)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:765)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:734)
at sun.reflect.GeneratedMethodAccessor455.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.java:127)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy284.commit(Unknown Source)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:518)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:292)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:57)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy268.save(Unknown Source)
at org.easysdi.extract.batch.writer.ImportedRequestsWriter.write(ImportedRequestsWriter.java:129)
at org.easysdi.extract.orchestrator.runners.CommandImportJobRunner.run(CommandImportJobRunner.java:128)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: javax.persistence.RollbackException: Error while committing the transaction
at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:87)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517)
... 36 common frames omitted
Caused by: javax.validation.ConstraintViolationException: Validation failed for classes [org.easysdi.extract.domain.Request] during persist time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
ConstraintViolationImpl{interpolatedMessage='size must be between 0 and 4000', propertyPath=perimeter, rootBeanClass=class org.easysdi.extract.domain.Request, messageTemplate='{javax.validation.constraints.Size.message}'}
]
at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:138)
at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreInsert(BeanValidationEventListener.java:78)
at org.hibernate.action.internal.EntityInsertAction.preInsert(EntityInsertAction.java:205)
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:82)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:582)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:456)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:337)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1282)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:465)
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2963)
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2339)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:485)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:147)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$100(JdbcResourceLocalTransactionCoordinatorImpl.java:38)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:231)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:65)
at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:61)
... 37 common frames omitted
16:24:33.866 78300921 [pool-8-thread-1] ERROR o.e.e.o.r.CommandImportJobRunner - Could not process the product "248114 - R?seau d'assainissement de Dagobah".
org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:526)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:765)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:734)
at sun.reflect.GeneratedMethodAccessor455.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.java:127)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy284.commit(Unknown Source)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:518)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:292)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:57)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy268.save(Unknown Source)
at org.easysdi.extract.batch.writer.ImportedRequestsWriter.write(ImportedRequestsWriter.java:129)
at org.easysdi.extract.orchestrator.runners.CommandImportJobRunner.run(CommandImportJobRunner.java:128)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: javax.persistence.RollbackException: Error while committing the transaction
at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:87)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517)
... 36 common frames omitted
Caused by: javax.validation.ConstraintViolationException: Validation failed for classes [org.easysdi.extract.domain.Request] during persist time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
ConstraintViolationImpl{interpolatedMessage='size must be between 0 and 4000', propertyPath=perimeter, rootBeanClass=class org.easysdi.extract.domain.Request, messageTemplate='{javax.validation.constraints.Size.message}'}
]
at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:138)
at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreInsert(BeanValidationEventListener.java:78)
at org.hibernate.action.internal.EntityInsertAction.preInsert(EntityInsertAction.java:205)
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:82)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:582)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:456)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:337)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1282)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:465)
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2963)
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2339)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:485)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:147)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$100(JdbcResourceLocalTransactionCoordinatorImpl.java:38)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:231)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:65)
at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:61)
... 37 common frames omitted
Le problème est gênant avec le connecteur easySDI v4, car si la transaction HTTP se termine bien le service easySDI estime que tout OK, et la requête n'est plus présentée.
Elle va donc "disparaitre" si ce cas se présente.
Aujourd'hui (v1.0 et v1.1-BETA2) la colonne est un varchar(4000)
Ma proposition :
Forcer la colonne p_perimeter au type TEXT dans Hibernate.
On devrait faire pareil pour les règles.
Passer la définition des colone en TEXT, serait supporté par :
Dans le code il faudrait :
Remplacer dans java\easysdi\extract\src\main\java\org\easysdi\extract\domain\Request.java
<code class="java">
/**
* The WKT geometry of the geographical area for this order.
*/
@Size(max = 4000)
@Column(name = "p_perimeter", length = 4000)
private String perimeter;
par :
<code class="java">
/**
* The WKT geometry of the geographical area for this order.
*/
@Column(name = "p_perimeter", columnDefinition = "text")
private String perimeter;
et pour les règles :
Remplacer dans java\easysdi\extract\src\main\java\org\easysdi\extract\domain\Rule.java
<code class="java">
/**
* The criteria that the data item request must satisfy.
*/
@Size(max = 4000)
@Column(name = "rule", length = 4000)
private String rule;
par :
<code class="java">
/**
* The criteria that the data item request must satisfy.
*/
@Column(name = "rule", columnDefinition = "text")
private String rule;
Ensuite afin que les mises à jour roulent il faut changer les types de colonnes (car Hibernate ne fait pas d'alter table tout seul).
Je propose que l'on mette à jour les fichier SQL post-installation afin qu'il soit idempotent (on peut l'applique plusieurs fois) et qu'il soit à executer après chaque installation ET mise à jour.
Contenu proposé :
<code class="sql">
-- PROCESSES_USERS Table
ALTER TABLE processes_users
DROP CONSTRAINT fk_processes_users_process;
ALTER TABLE processes_users
ADD CONSTRAINT fk_processes_users_process FOREIGN KEY (id_process)
REFERENCES processes (id_process) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE CASCADE;
DROP INDEX IF EXISTS idx_processes_users_process;
CREATE INDEX idx_processes_users_process
ON processes_users (id_process);
ALTER TABLE processes_users
DROP CONSTRAINT fk_processes_users_user;
ALTER TABLE processes_users
ADD CONSTRAINT fk_processes_users_user FOREIGN KEY (id_user)
REFERENCES users (id_user) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE CASCADE;
DROP INDEX IF EXISTS idx_processes_users_user;
CREATE INDEX idx_processes_users_user
ON processes_users (id_user);
-- REQUESTS Table
ALTER TABLE requests
DROP CONSTRAINT fk_request_connector;
ALTER TABLE requests
ADD CONSTRAINT fk_request_connector FOREIGN KEY (id_connector)
REFERENCES connectors (id_connector) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE SET NULL;
ALTER TABLE requests
DROP CONSTRAINT fk_request_process;
ALTER TABLE requests
ADD CONSTRAINT fk_request_process FOREIGN KEY (id_process)
REFERENCES processes (id_process) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE SET NULL;
ALTER TABLE requests ALTER COLUMN p_perimeter TYPE TEXT;
-- REQUEST_HISTORY Table
ALTER TABLE request_history
DROP CONSTRAINT fk_request_history_request;
ALTER TABLE request_history
ADD CONSTRAINT fk_request_history_request FOREIGN KEY (id_request)
REFERENCES requests (id_request) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE CASCADE;
ALTER TABLE request_history
DROP CONSTRAINT fk_request_history_user;
ALTER TABLE request_history
ADD CONSTRAINT fk_request_history_user FOREIGN KEY (id_user)
REFERENCES users (id_user) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE SET NULL;
-- RULES Table
ALTER TABLE rules
DROP CONSTRAINT fk_rule_connector;
ALTER TABLE rules
ADD CONSTRAINT fk_rule_connector FOREIGN KEY (id_connector)
REFERENCES connectors (id_connector) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE CASCADE;
ALTER TABLE rules
DROP CONSTRAINT fk_rule_process;
ALTER TABLE rules
ADD CONSTRAINT fk_rule_process FOREIGN KEY (id_process)
REFERENCES processes (id_process) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE CASCADE;
ALTER TABLE rules ALTER COLUMN rule TYPE TEXT;
-- TASKS Table
ALTER TABLE tasks
DROP CONSTRAINT fk_task_process;
ALTER TABLE tasks
ADD CONSTRAINT fk_task_process FOREIGN KEY (id_process)
REFERENCES processes (id_process) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE CASCADE;
Original author : Yves Blatti
À la mise à jour d’EXTRACT sur un Tomcat 9 (Windows), si le dossier temp de tomcat contient encore une ancienne version d’EXTRACT, le classloading des plugins échoue :
Message d'erreur : Plugin EMAIL not found.
Message d'erreur : Plugin REJECT not found.
Je propose que l’on ajoute dans la doc de mise à jour une ligne demandant la suppression des anciens dossiers EXTARCT de [tomcat-root]/temp. (Ils peuvent être nommées “0-extract”, “1-extract”, etc...)
Original author : Daniel Savary
Problème de tri des commandes
Lors de l'ouverture, certains anciennes commandes (plus d'une année) s'affichent en premier.
Le tri sur la date ne semble pas se faire correctement (15 premières commandes)
Ensuite, le tri est correcte.
Voir documents ci-joints
Original author : Yves Blatti
Interface de configuration
Maquettes
Nouveau bloc à drag dropper + bloc dans le processus de traitement :
Tooltip d'aide :
Critères d’acceptation
Budget : 2908
Original author : Xavier Mérour
Modification du plugin d'archivage.
Maquette
Actuellement :
Comportement désiré :
Critères d’acceptation
|.ID|.Critère|
|17758-1|Si une tâche d'archivage se termine correctement, le chemin d'archivage est affiché dans le log|
|17758-2|Le chemin affiché est celui effectif (une fois les variables remplacées)|
Budget : 1090
Original author : Yves Blatti
Ajouter un bouton de téléchargement du périmètre de commande en DXF et en KML.
Le fichier DXF téléchargé doit être dans le SRS de la carte.
Maquettes
Critères d’acceptation
|.ID|.Critère|
|22291-1|Un bouton propose le téléchargement du périmètre en KML|
|22291-2|Un bouton propose le téléchargement du périmètre en DXF|
|22291-3|Le fichier DXF est dans le SRS de la carte|
|22291-4|Les boutons sont aussi ajoutés à la carte si c'est une carte personnalisée (map.custom.js)|
|22291-5|Le fichier KML est en WGS84|
Note : une ancienne implémentation existe dans easySDI : https://forge.easysdi.org/projects/easysdi/repository/entry/branches/4.5.x/joomla/easysdi/com_easysdi_shop/src/site/views/order/tmpl/order.js
Budget : 2948
Original author : Xavier Mérour
Il y a plusieurs petits détails qui ne suivent pas notre maquette et qui devraient être corrigés :
Original author : Xavier Mérour
Ajouter des règles basées sur les catégories d'organismes easySDI ?
exemples :
Original author : Xavier Mérour
Modification sur le plugin easySDI v4.
Si le user commande une donnée avec un périmètre prédéfini (parcelle, commune...) sur une plateforme easySDI, EXTRACT n'est pas en mesure de gérer l'extraction car il n'y a pas de géométrie associée (uniquement un ID de géométrie --> cf. #133). Il en résulte:
La distinction se fait sur l'attribut "@type@" de la balise "@perimeter@"
Périmètre OK:
Type de périmètre : "coordinates" -> OK peut être importé sans erreurs
<code class="xml">
<sdi:perimeter type="coordinates" id="1" alias="freeperimeter" guid="f0d48c8e-ad5a-09f4-d1b0-dce7dfa544a9">
<sdi:surface unit="m2">1874219.75000000000000000000</sdi:surface>
<sdi:contents>
<sdi:content>POLYGON((6.556053540245442 46.5406858665773,6.564736227940287 46.552776494518355,6.579339266387595 46.54778277789993,6.57065411715828 46.53569326277157,6.556053540245442 46.5406858665773))</sdi:content>
</sdi:contents>
</sdi:perimeter>
Périmètre KO:
Type de périmètre : "values" -> KO doit être importé en erreur
<code class="xml">
<sdi:perimeter type="values" id="4" alias="COMMUNE" guid="71ae448a-cfe4-f1f4-f597-ce2d7a0702bb">
<sdi:surface unit="m2">8568479.00000000000000000000</sdi:surface>
<sdi:contents>
<sdi:content>348</sdi:content>
<sdi:content>312</sdi:content>
</sdi:contents>
</sdi:perimeter>
Comportement attendu :
Budget : 1090
Original author : Yves Blatti
Règles basées sur organisme
Original author : Rémi Bovard
Afin d'utiliser les tuiles WMTS de façon optimales, il est nécessaire de définir en plus de la projection, les résolutions de la vue.
En me basant sur la doc pour le WMTS 2056 [1], les valeurs sont les suivantes :
<code class="javascript">
resolutions: [650, 500, 250, 100, 50, 20, 10, 5, 2.5, 2, 1, 0.5, 0.25, 0.1]
A ajouter dans le fichier @map.custom.js.dist@
[1] https://api3.geo.admin.ch/services/sdiservices.html#gettile
Budget : 545
Original author : Xavier Mérour
La vue "request" affiche par défaut une carte avec le service OSM comme fond de plan.
L'objectif est de permettre à l'administrateur de surcharger la carte par défaut s'il le désire, avec un ou des fonds de plan, et éventuellement une ou des couches à superposer.
Proposition technique pour le layer switcher : https://github.com/walkermatt/ol-layerswitcher
Maquettes
Critères d’acceptation
|.ID|.Critère|
|17219-1|Si aucun fichier @map.custom.js@ n'est présent, la carte de base s'affiche (la carte actuelle, OSM, avec @map.js@) |
|17219-2|Il est possible de choisir la projection de la carte (par exemple : EPSG:2056 ou EPSG:21781)|
|17219-3|Il est possible d'afficher des fonds de plans WMS (1) et WMTS (1)|
|17219-4|Il est possible d'afficher des couches WMS (1) et WMTS (1)|
Notes:
(1) à démontrer avec au minimum :
-ol.layer.Image avec ol.source.ImageWMS
-ol.layer.Tile avec ol.source.TileWMS
-ol.layer.Tile avec ol.source.WMTS
Budget : 2948
Original author : Rémi Bovard
Lorsque que les fichiers d'une commande avec plusieurs produits ont le même nom (p. ex. même script FME lancé 2x), seul le dernier est gardé dans le dossier d'archivage si le chemin n'est pas spécifique au produit.
Il faudrait au minimum ajouter l'information dans la tooltip d'aide du plugin pour éviter ces désagréments.
Original author : Yves Blatti
Afin de pouvoir créer des règles complexes avec plusieurs opérateurs booléen il faut ajouter le support des parenthèses dans les règles.
Exemple de règles possible :
productguid == "81c452ca-1bef-4544-2dc5-7e2844134c38"
and perimeter intersects POLYGON((6.55950172542713084 46.48890379920126747, 6.55774390464311452 46.59684404773618382, 6.72901850071676133 46.59804302426485378, 6.73043495839145844 46.49010040627619844, 6.55950172542713084 46.48890379920126747))
and (parameters.format != "LAS" OR surface > 1000000 and parameters.format == "LAS")
Cette règle doit actuellement écrite ainsi :
productguid == "81c452ca-1bef-4544-2dc5-7e2844134c38"
and perimeter intersects POLYGON((6.55950172542713084 46.48890379920126747, 6.55774390464311452 46.59684404773618382, 6.72901850071676133 46.59804302426485378, 6.73043495839145844 46.49010040627619844, 6.55950172542713084 46.48890379920126747))
and parameters.format != "LAS"
OR
productguid == "81c452ca-1bef-4544-2dc5-7e2844134c38"
and perimeter intersects POLYGON((6.55950172542713084 46.48890379920126747, 6.55774390464311452 46.59684404773618382, 6.72901850071676133 46.59804302426485378, 6.73043495839145844 46.49010040627619844, 6.55950172542713084 46.48890379920126747)) and surface > 1000000
and parameters.format == "LAS"
Critères d’acceptation
ID | Critère |
---|---|
19672-1 | Il est possible d'utiliser des parenthèses dans les règles pour changer l'ordre de prise en compte des opérateurs booléens [and|or] |
19672-2 | https://www.asitvd.ch/v5/restricted_access/file.txt |
Budget : 8441
Original author : Thierry Bussien
Avec le navigateur IE 11.0.9600 la page d'accueil ne charge pas la liste des demandes en cours.
Ce problème n'existe pas sous Firefox ou Chrome.
Original author : Xavier Mérour
Ajouter des remarques dans l'historique de traitement d'une requête pour préciser quand il y a eu :
Original author : Rémi Bovard
Pour reproduire :
Se connecter avec compte U1
Créer un compte U2
Créer un traitement T1, avec U1 et U2 comme opérateurs
Faire une commande C1 qui arrive dans T1
Traiter commande C1
Supprimer U2
Afficher C1 dans la liste des demandes traitées
L'erreur suivante se produit :
Une erreur s'est produite lors de la dernière opération.
500 - Internal Server Error
Exception evaluating SpringEL expression: "user.systemUser" (requests/details:376)
Le problème est que U1 existe toujours et est toujours assigné à T1, donc il n'a plus accès au détails de C1 (err500).
Budget : 1860
Original author : Xavier Mérour
Pour la version 1.1 d'EXTRACT nous attendons une mise à jour des librairies embarquées, spécifiquement les librairies sensibles (sécurité).
En particulier Spring (https://spring.io/blog/2018/04/05/multiple-cve-reports-published-for-the-spring-framework + https://spring.io/blog/2018/04/09/cve-2018-1275-address-partial-fix-for-cve-2018-1270)
À la livraison, merci de nous indiquer les changements effectués.
Original author : Xavier Mérour
Pour faciliter la saisie des traitement, il faut pouvoir en copier un existant, avec ses tâches.
Comportement
Maquettes
Critères d’acceptation
|.ID|.Critère|
|17759-1|Il est possible de cloner un traitement depuis la liste|
|17759-2|Toutes les tâches sont copiées dans le nouveau traitement|
|17759-3|Toutes les opérateurs sont copiées dans le nouveau traitement|
|17759-4|Le nouveau traitement porte le nom de l’orignal avec le suffixe " - copie"|
Budget : 2949
Original author : Rémi Bovard
Dans la version 1.1 d'EXTRACT, lors d'une erreur FME le retour n'est pas explicite :
Erreur / (-1)
Dans la version 1.0, cette même erreur était retournée ainsi :
Erreur / FME license system failure: The maximum number of concurrent FME instances specified in the license has been reached (-508) Program Terminating Translation FAILED. (-1)
Ce qui était bien plus explicite.
Serait-il possible de revenir au comportement précédent ?
Budget : 430
Original author : Yves Blatti
mise en place de la sécurité par authentification par certificats (2 ways SSL) plutôt que par login/password sur https avec filtrage IP.
(Lausanne)
Original author : Xavier Mérour
Pour la version 1.1 d'EXTRACT, les modifications de documentation suivantes sont attendues :
Budget : 0
Original author : Rémi Bovard
Lors d'une commande avec plusieurs produits (5 dans ce cas), qui arrivent dans le même traitement EXTRACT, une erreur FME de licence se produit :
FME license system failure: The maximum number of concurrent FME instances specified in the license has been reached (-508)
Après quelques tests, j'ai vraiment l'impression que le problème est que les 5 process FME sont appelés au même moment exact car si je relance les traitements manuellement (avec un intervalle d'environ 1 seconde - le temps de cliquer), FME fonctionne bien et les traitement tournent simultanément.
Pour info nous avons une licence fixe.
A surveiller.
Origine du problème
FME Desktop limite le d'instances de fme.exe en exécution parallèle à 8. [1]
Les scripts que tu utilise avec EXTRACT utilisent un WorkspaceRunner, ce qui lance une fme.exe supplémentaire (donc 2 processus par extraction). Ceci explique l'erreur dès 5 produits commandés en parallèle.
Ceci peut donc se produire lorsque EXTRACT reçoit :
8 produits avec un script simple
4 produits avec un script + 1 WorkspaceRunner
2 produits avec un script + 2 WorkspaceRunner
Solution 1 : Passer tout EXTARCT en "séquentiel".
Empêcher toute exécution en parallèle dans EXTRACT.
Changement d'architecture du logiciel. Règle le problème mais limite le fonctionnement d'EXTRACT... bof
Solution 2 : Passer le plugin FME Desktop en "séquentiel".
Empêcher toute exécution en parallèle d'un plugin FME Desktop.
Changement d'architecture du logiciel. Un plugin doit pourvoir se "déclarer" comme n'étant pas parallèle afin que l'orchestrateur n'en lance qu'un à la fois. Règle le problème pour FME Desktop et peut être d'autres à venir. NB : il ne sera plus jamais possible d'avoir deux extraction simultanées.
Solution 3 : Compter le nombre de FME en cours d’exécution.
Compter le nombre de fme.exe en cours d’exécution. Attendre s'il n y en a pas assez de "libre" (8 - LeNombreEnCours - LeNombrePourLeScript).
Changement uniquement dans le Plugin FME Desktop. Il faut:
Il faudra faire attention à quelques points:
C'est la solution qui, il me semble, répond le plus précisément au problème
Notes:
[1] : https://knowledge.safe.com/articles/139/how-many-concurrent-fme-processes-can-i-run-at-my.html
[2] : https://crunchify.com/how-to-get-a-list-of-current-open-processes-with-java/
Original author : Daniel Savary
Je peux ajouter un seul fichier à la fois.
Lorsque je souhaite ajouter plusieurs fichiers (sélection) en une seule fois.
J'obtiens l'erreur suivante : ERROR serveur 500
Origine : limite à l'upload.
Original author : Yves Blatti
Les règles écrites sur plusieures lignes ne match pas.
Cet exemple ne match pas :
productguid=="e0a491cc-a8f3-3e64-0590-c534ce6b0144"
OR
productguid=="aaaaaaaa"
workaround : ajouter des espaces :
productguid=="e0a491cc-a8f3-3e64-0590-c534ce6b0144"
OR
productguid=="aaaaaaaa"
Je suppose qu'un petit @x.replaceAll("\r\n", " ")@ devrait résoudre le problème
Original author : Yves Blatti
Message d'erreur : L'archivage des fichiers a échoué : authentification réseau échoué. L'erreur systŠme 1219 s'est produite. Plusieurs connexions … un serveur ou … une ressource partag‚e par le mˆme utilisateur, en utilisant plus d'un nom utilisateur, ne sont pas autoris‚es. Supprimez toutes les connexions pr‚c‚dentes au serveur ou … la ressource partag‚e et recommencez. (-1)
A investiguer : ça sent la bricole, genre NET USE avec le user qui fait tourner Tomcat...
Original author : Yves Blatti
Cas d'exemple: la ville de Lausanne va avoir un EXTRACT au SCC, mais le même compte sera utilisé par Alpiq (SEL 125KV...)
Il faudra que chacun des EXTRACT ne consomme le service QUE pour SES produits.
<!-- getOrdersByGuids with parameter guids -->
<?xml version="1.0"?>
<sdi:parameters xmlns:sdi="http://www.easysdi.org/2011/sdi"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.easysdi.org/2011/sdi/getordersparameters.xsd"
xsi:type="sdi:getOrdersByGuids">
<sdi:guids>
<sdi:guid>f655e481-39d1-3224-1db5-665c402b2869</sdi:guid>
<sdi:guid>d8d903d2-8117-89c4-bd9d-6c00e137ba44</sdi:guid>
</sdi:guids>
</sdi:parameters>
Original author : Daniel Savary
Supprimer la note "Fichier : Aucun" dans l'écran de détails lorsqu'un traitement est terminé (statut FINISHED)
Budget : 444
Original author : Xavier Mérour
Modification des plugins +FME+ et +FME Server+
Le contenu de l'aide doit aider un administrateur d'EXTRACT à créer un script FME compatible avec EXTRACT
Il faut y décrire les variables passées, leur nom, leur type et des données d'exemple
** Perimeter (et son encodage en WKT WGS84)
** Product (string, ID externe du produit)
** FolderOut (dossier de sortie utilisé pour FME desktop)
** Parameters (décrire leur encodage et l'aspect dynamique)
Expliquer le retour de donner (différence entre FME desktop et serveur)
pour FME Server -> spécifier qu'il faut utiliser le service "Data Download" et non "Job Submitter"
Paramètres publics à utiliser dans un script FME
Critères d’acceptation
|.ID|.Critère|
|18810-1|Le plugin FME desktop contient une aide en ligne pour aider l'administrateur|
|18810-2|Le plugin FME server contient une aide en ligne pour aider l'administrateur|
Budget : 1454
Original author : Rémi Bovard
Jusqu'à la v1.1 lors de la validation d'une commande, chaque fichier peut être téléchargé manuellement en cliquant dessus.
Pour améliorer le confort de la personne qui valide la commande, s'il y a plus d'un fichier, un bouton "Télécharger tous les fichiers" permet de télécharger un zip comprenant tous les fichiers, en conservant l'arborescence.
Maquette
Critères d’acceptation
|.ID|.Critère|
|21289-1|S'il y a plus d'un fichier à télécharger, proposer à l'opérateur un bouton "Télécharger tous les fichiers"|
|21289-2|Lors du téléchargement groupé, les fichiers sont zippés|
|21289-3|Dans le zip, l’arborescence des fichiers (depuis le dossier output) est conservée|
|21289-4|Le nom du fichier est "<request_id>.zip", par exemple "1657.zip"|
Budget : 1090
Original author : Xavier Mérour
Maquette
|.ID|.Critère|
|17762-1|La version installée, un lien vers easysdi.org et la licence sont affichés dans un panel sur la page de config|
Budget : 727
Implémenter une authentification avec LDAP
Dans les paramètres, sous le bloc Serveur SMTP, ajouter un nouveau bloc Authentification LDAP
Dans ce bloc, ajouter les champs suivants :
Champ | Type | Notes |
---|---|---|
Activer l'authentification avec LDAP | Toggle | Off par défaut |
Si toggle activé, afficher les éléments ci-dessous | ||
Serveurs LDAP* | Texte | Plusieurs valeurs possible |
Type de chiffrage | Toggle | LDAPS (par défaut) ou STARTTLS |
BASE_DN* | Texte | Plusieurs valeurs possibles |
LDAP_QUERY pour lister les administrateurs* | Texte | |
LDAP_QUERY pour lister les opérateurs* | Texte | |
Activer la synchronisation avec LDAP | Toggle | Off par défaut |
Si toggle activé, afficher les quatres champs ci-dessous | ||
User LDAP* | Texte | |
Password LDAP* | Mot de passe | |
Fréquence de synchronisation avec LDAP, en heures | Entier | 24 par défaut |
Synchroniser maintenant | Bouton | |
Tester la connexion | Bouton |
*= champs obligatoires
Le mapping entre les propriétés Extract et LDAP est défini dans le fichier de configuration global d'Extract.
Exemple :
Champ Extract | Champ LDAP par défaut (pour AD) |
---|---|
Nom d'utilisateur | cn |
Login | sAMAccountName |
Utilisateur local
: Utilisateur dont la base Extract est la source d'authentification (comme aujourd'hui)
Utilisateur LDAP
: Utilisateur dont un serveur LDAP est la source d'authentification
Utilisateur Extract
: Tous les comptes utilisateurs dans la base Extract (local et LDAP)
Une fois l'authentification avec LDAP activée, des Utilisateurs LDAP
peuvent se connecter à Extract avec leur identifiant et mot de passe LDAP.
Conditions pour Auth LDAP OK
Création à la volée
Si un utilisateur se connecte à Extract avec LDAP et qu'il n'est pas présent dans la base locale, il est créé à la volée.
Note : Étape 2FA indiquée de manière simplifiée, décrite plus précisément ici : #255
Il est possible d'activer la synchronisation LDAP.
Ces tâches sont les suivantes :
Utilisateurs LDAP
(comptes existants dans l'annuaire LDAP, pas encore dans la base Extract)Utilisateurs LDAP
(nom complet, email, rôle)Utilisateurs LDAP
dans la base Extract si ils sont désactivés ou supprimés de l'annuaire LDAPUtilisateurs LDAP
Les Utilisateurs LDAP
:
Les administrateurs
Utilisateurs LDAP
Utilisateurs LDAP
Utilisateurs LDAP
Des Utilisateurs locaux
peuvent coexister avec des Utilisateurs LDAP
.
Utilisateur LDAP
Un Utilisateur LDAP
est créé à partir des informations stockées dans LDAP.
Les propriétés de compte (login, Nom complet, email) sont automatiquement attribuées (correspondance entre les propriétés LDAP et Extract grâce au mapping configuré). Le rôle d’administrateur est attribué en fonction du groupe LDAP configuré.
Utilisateur LDAP
Met à jour l'Utilisateurs LDAP
avec les dernières informations stockées sur l'annuaire LDAP (nom complet, email). Le rôle d’administrateur est attribué en fonction du groupe LDAP configuré.
Utilisateur local
vers un Utilisateur LDAP
Dans la liste des Utilisateurs Extract
, une nouvelle colonne "Type" permet d'identifier facilement le type d'utilisateur. Elle est visible seulement si l'authentification avec LDAP est activée.
Dans les détails d'un utilisateur, il est possible de migrer un Utilisateur local
vers un Utilisateur LDAP
si l'authentification avec LDAP est activée.
Les modifications suivantes sont apportées durant la migration :
L'utilisateur pourra donc uniquement s'authentifier avec son username / password LDAP.
Cette opération n'est pas réversible et il n'est pas possible de migrer un Utilisateur LDAP
vers un Utilisateur local
.
Identifiant | Description |
---|---|
131-1 | Les administrateurs Extract peuvent en tout temps activer l'authentification avec LDAP |
131-2 | Une fois les paramètres renseignés, il doit être possible de tester la connexion |
131-3 | Une fonction doit pouvoir synchroniser immédiatement les Utilisateurs LDAP (création, mise à jour, suppression) |
131-4 | Les Utilisateurs LDAP doivent pouvoir se connecter à l'application en utilisant leur nom d'utilisateur et leur mot de passe LDAP. |
131-5 | Les propriétés d'un Utilisateur LDAP tels que le rôle ou le nom doivent provenir de l'annuaire LDAP |
131-6 | Les modifications apportées dans l'annuaire LDAP doivent être reflétées dans l'application grâce à la synchronisation. |
131-7 | Un administrateur peut migrer des Utilisateurs locaux (administrateurs et opérateurs) vers des Utilisateurs LDAP |
Original author : Yves Blatti
Original author : Rémi Bovard
Les utilisateurs ne peuvent pas modifier leur mot de passe, seuls les admins peuvent le faire.
Original author : Yves Blatti
Supporter la sélection des périmètres indirects (prédéfinis).
Exemple : sélectionner une commune, ou une grille kilométrique sur viageo.ch. Il faudrait alors, soit :
Original author : Rémi Bovard
Ajouter la possibilité de désactiver les notifications de traitement d'un utilisateur.
Cet utilisateur ne recevra plus de notifications de traitement et d'erreurs de traitement.
Maquettes
Edition du compte
Critères d’acceptation
|.ID|.Critère|
|22286-1|Si les notifications sont actives, le comportement est le même que sur la version 1.1|
|22286-2|Si les notifications sont désactivées, aucune notification de traitement, ou erreur de traitement n'est envoyée à l'utilisateur|
|22286-3|Si le compte est administrateur et ses notifications désactivées, il continuera a recevoir les notifications admin (erreur import, export, ...)|
|22286-4|Les messages système (comme la réinitialisation de mot de passe) sont toujours envoyées|
|22286-5|Label "Actif ?" changé pour "Utilisateur actif"|
Budget : 1817
Original author : Yves Blatti
Afin de pouvoir effectuer des traitement FME plus complexes, passer les paramètres supplémentaires suivants pour les traitement FME Desktop et FME Server :
Les GUIDs (client, organisme, produit) et l'DI interne de la requête sont affichés dans le panneau administration, au fond de l'écran, avec leur code.
Maquettes
Panneau d'administration
Critères d’acceptation
|.ID|.Critère|
|20315-1|Il est possible d'utiliser les 4 nouveaux paramètres dans FME Desktop|
|20315-2|Il est possible d'utiliser les 4 nouveaux paramètres dans FME Server|
|20315-3|La rétrocompatibilité doit être assurée: pas besoin de refaire les scripts FME existants pour passer à EXTRACT 1.2|
|20315-4|Les 3 GUIDs (client, organisme et produit) et l'ID interne sont affichés dans la zone d'admin au fond de la page détail|
Notes :
Budget : 2948
Original author : Yves Blatti
Pour la permettre la comparaison d'une variable à plusieurs valeurs ajouter la prise en charge des opérateurs @in@ et @Not IN@ (équivalent SQL)
exemple 1 :
@productguid IN ("70370f51-ec38-4eeb-b0e2-5489ffa03969","65939378-46bf-4d76-a74c-a01a94ad8381","196")@
cette règle doit actuellement être écrite ainsi:
@productguid == "70370f51-ec38-4eeb-b0e2-5489ffa03969" OR productguid == "65939378-46bf-4d76-a74c-a01a94ad8381" OR productguid == "196")@
exemple 2 :
@productguid NOT IN ("70370f51-ec38-4eeb-b0e2-5489ffa03969","65939378-46bf-4d76-a74c-a01a94ad8381","196")@
cette règle doit actuellement être écrite ainsi:
@productguid != "70370f51-ec38-4eeb-b0e2-5489ffa03969" AND productguid != "65939378-46bf-4d76-a74c-a01a94ad8381" AND productguid != "196")@
Ces opérateurs sont compatibles avec les autres (attributaires et géographiques) et peuvent être combinés avec des AND ou OR.
exemple 3 :
@productguid IN ("70370f51-ec38-4eeb-b0e2-5489ffa03969","196") AND surface < 10000@
Critères d’acceptation
|.ID|.Critère|
|19613-1|Il est possible de comparer une variable à 1 à n valeurs avec l'opérateur IN ou NOT IN|
|19613-2|Une règle contenant l'opérateur IN ou NOT IN peut contenir d'autres filtres|
|19613-3|Les opérateurs IN et NOT IN sont insensibles à la casse (IN = In = in)|
|19613-4|L'aide en ligne de saisie des règles est adaptée aux nouveaux opérateurs IN et NOT IN, avec un exemple|
Budget : 2948
Original author : Yves Blatti
Remonté par RM à Morges:
la fonction admin de suppression définitive d’une requête ne fonctionne pas s’il n’y a pas de dossier de données pour la demande.
Il semble que dans certains cas, une requête n’a pas encore de dossier, ou qu’il a été supprimé.
Il faudrait que l’administrateur puisse supprimer cette requête même s’il n’y a pas de dossier pour cette dernière.
Message à l’administrateur :
Une erreur s'est produite lors de la suppression de la demande. Veuillez réessayer plus tard.
Log :
08:59:45.704 239286 [http-nio-8080-exec-8] WARN o.e.extract.utils.FileSystemUtils - Could not get data folders to purge for request 187.
Original author : Yves Blatti
Les guillemets ne sont pas échappés dans les propriétés dynamiques.
Le JSON stocké en base est invalide.
il en résulte :
Original author : Xavier Mérour
Rendre possible (en option) le paramétrage des jours de la semaine et/ou des plages horaires de fonctionnement d'EXTRACT, ou son arrêt.
Cas d'utilisations possibles :
Configuration
Ajouter un bloc de paramètres "Heures de fonctionnement"
Comportement
Maquettes
Configuration
Accueil hors plages horaires
Accueil si arrêt complet
Critères d’acceptation
|.ID|.Critère|
|22299-1|La configuration propose un nouveau bloc "Heures de fonctionnement"|
|22299-2|Le bloc "Heures de fonctionnement" propose le choix de trois modes : "Tout le temps (24/7)" , "Seulement durant les heures ci-dessous" et "Arrêt complet"|
|22299-3|Les plages de fonctionnement peuvent se chevaucher et se croiser : exemples valables
+du LUN au VEN de 08:00 à 16:00+ ET +du VEN au VEN de 08:00 à 18:00+
+du LUN au JEU de 08:00 à 16:00+ ET +du VEN au VEN de 08:00 à 12:00+
+du LUN au VEN de 08:00 à 11:30+ ET +du LUN au VEN de 13:30 à 18:00+ ET +du SAM au SAM de 09:30 à 12:00+
+du LUN au MAR de 08:00 à 13:00+ ET +du MAR au VEN de 12:00 à 16:00+
|
|22299-4|La page d’accueil affiche la raison de l'arrêt|
|22299-5|Lorsque EXTRACT est arrêté aucun import n'est effectué|
|22299-6|Lorsque EXTRACT est arrêté aucun export n'est effectué|
|22299-7|Lorsque EXTRACT est arrêté aucun traitement automatique n'est lancé|
|22299-8|Dans l'écran de paramètres, les plages d'heures sont affichées et sauvées, peu importe le "mode" choisi, pour ne pas perdre la configuration|
Budget : 6987
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.