AppLog sur les objets System non fonctionnel?

Tags: #<Tag:0x00007f2f3a5824e0>

Bonjour,
dans l’objet System “User”, j’ai défini un hook postSave.
Lorsque le code était en Rhino, j’obtenais bien une trace dans les logs

User.postSave = function() {
	
	var ipn_cand = this.getFieldValue("usr_login");
	console.log("[IN User.postSave] refreshUser(g,"+ipn_cand+") ");
}

Ce code a été remplacé par le code java suivant

package com.simplicite.objects.System;
import com.simplicite.util.AppLog;

public class User extends ObjectDB {

	private static final long serialVersionUID = 1L;
	
	@Override
	public String postSave() {
		String ipn = this.getFieldValue("usr_login");
		AppLog.info(getClass(), "ATR--------------------------------------", "postSave", getGrant());
		AppLog.error("ATR--------------------------------------postSave" + ipn, new Exception(),  getGrant());
		return null;
	}
}

Je n’obtiens aucune trace du log de postSave.

Existe-t’il un raison pour laquelle les logs de mon objet ne soit pas affiché ?

Cordialement
Amandine

[Platform]
Status=OK
Version=4.0.P24
BuiltOn=2020-09-08 13:58 (revision cc3e1c0a38d7b0549d655541696b9efd34201031)
Encoding=UTF-8
EndpointIP=21.0.9.3
EndpointURL=http://af1dac8645f0:8080
TimeZone=Europe/Paris
SystemDate=2020-09-09 22:25:40

Nous ne connaissons pas de pb sur AppLog qui est massivement utilisé (au sein du code Simplicité et dans le code des modules) donc s’il y avait une anomalie à ce niveau on serait à priori au courant. Je requalifie donc votre post en “Support” car je soupçonne des pbs de configuration et/ou d’infrastructure technique.

Déjà votre usage des arguments n’est pas correct. Prenons l’exemple de info:

Vous pouvez utiliser soit la version complète, cf. https://docs.simplicite.io/4.0/javadoc/com/simplicite/util/AppLog.html#info(java.lang.Class,java.lang.String,java.lang.String,com.simplicite.util.Grant)), ex: AppLog.info(getClass(), "postSave", "Mon message", getGrant())

Soit sa version simplifiée (où la classe et la méthode sont valorisées automatiquement), cf. https://docs.simplicite.io/4.0/javadoc/com/simplicite/util/AppLog.html#info(java.lang.String,com.simplicite.util.Grant), ex: ex: AppLog.info("Mon message", getGrant())

Cette log ira, si vous avez conservé la configuration Log4j par défaut, dans le fichier log Simplicité <tomcat root>/webapps/ROOT/WEB-INF/log/simplicite et sur la console (je ne sais pas où elle est redirigée das votre cas). Si vous avez modifié la configuration log4j elle ira là ou vous avez décidé de l’envoyer.

En outre, si votre environnement technique permet le bon fonctionnement des websockets et si votre user a bien accès aux logs websockets (param utilisateur USE_WEBSOCKET_LOGS=yes) vous retrouverez aussi ce message dans la console du navigateur.

L’absence des logs dans la console du navigateur ne veut pas dire que les logs ne marchent pas mais qu’elles ne remontent pas jusque là dans votre contexte.

PS: regardez aussi du coté des log events si par hasard vous n’auriez pas changé le paramétrage des logs events en question (ex: INFO pour AppLog.info).

Merci pour votre retour. En effet, j’aurai du le mettre en Support. Veuillez m’excuser.
Mon incompréhension vient du fait que le code Rhino affichait bien des logs et pas le code java.
Dans d’autres classes de modules différents de System, mes logs s’affichent correctement.
Quand aux exemples d’AppLog dans mon extrait, il s’agit évidement d’un code temporaire (je remplace le nom de la méthode par un code facilement repérable dans les logs). Il n’est pas destiné à la production. Il s’affiche bien dans mes autres classes.

D’où ma question existe t-il deux configurations pour les logs (une pour le rhino et une pour le code java) ?

Non le console de Rhino est en fait une instance d’une classe java (https://docs.simplicite.io/4.0/javadoc/com/simplicite/util/Console.html) qui ne fait que des appels à AppLog.log

Cela ne sert pas à grand chose (à part consommer de la mémoire et faire travailler le garbage collector) mais vous pouvez instancier cette classe, ex: dans un objet métier Console console = new Console(this) puis faire des console.log(...)

Je pense que votre code n’est pas appelé et que ce n’est pas un problème de log.

Vous surchargez un objet System User en héritant de ObjectDB dans le package com.simplicite.objects.System. Cette classe existe déjà dans Simplicité, ce que vous faites est impossible, ça reviendrait à écraser le fonctionnement interne de l’objet User. On ne peut pas non plus s’hériter de soit même en Java (public class User extends com.simplicite.objects.System.User n’a pas de sens non plus)

Le bon pattern quand on surcharge un objet System (ou déjà existant en général) est de créer un héritier MyUser dans son module métier

  • définit comme héritant de User et même template niveau paramétrage pour avoir les mêmes attributs/areas
  • au niveau du code Java : public class MyUser extends com.simplicite.objects.System.User en pensant à bien appeler les méthodes super quand vous overridez un hook, sinon vous perdrez le fonctionnement natif de l’objet père :
@Override
public String postSave() {
	// ...
	return super.postSave();
}

Bref il faut retenir que les objets Simplicité (User, Field…) sont des objets comme les autres, sauf que leurs hooks Java sont déjà livrées dans les libs et ne sont donc pas remplaçables / piratables, on peut juste en hériter pour en modifier/étendre le comportement ‘ailleurs’. C’est tout l’intérêt de la plateforme.

Le code Rhino vient en complément du Java, et peut donc cohabiter mais ce n’est pas conseillé de mélanger les 2 pour des raisons de problème de priorités d’un code sur l’autre. Aucun objet interne Simplicité n’a de hook en Rhino.

Merci 1000 fois pour votre retour. J’en étais venu à la même conclusion (sur le fait que le code n’était pas appelé).
Notre besoin était le suivant : lors de la création d’un utilisateur nous souhaitons que notre base IDP/SSO soit appelé.
Nous avons bien un objet héritié BCSIPerson qui implémente une action refreshUser qui appelle notre idp et met à jour les données (nom, prénom, …) à partir du login renseigné.
BCSIPerson a un filtre pour n’hériter que des Users non technique.

User.postSave = function() {
	console.log("[IN User.postSave] CANCEL refreshUser(g,"+ipn_cand+") being BCSIPerson already synchronized today");
	
	var ipn_cand = this.getFieldValue("usr_login");
	
	var tmpobj = this.getGrant().getTmpObject("BCSIPerson");
	tmpobj.resetFilters();
	tmpobj.resetValues();
	tmpobj.getField("usr_login").setFilter(ipn_cand);
	var rows_ipn_cand = tmpobj.search();
	if ( rows_ipn_cand != null && rows_ipn_cand.size() > 0 ) {
		tmpobj.setValues(rows_ipn_cand.get(0));
		if ( tmpobj.getFieldValue("PersonLastADPSynchroDate") != Tool.getCurrentDate() ) {
			console.log("[IN User.postSave] refreshUser(g,"+ipn_cand+") being BCSIPerson and PersonLastADPSynchroDate="+Tool.getCurrentDate()+"<>today");
			tmpobj.invokeAction("refreshUser");
			tmpobj.getField("PersonLastADPSynchroDate").setValue(Tool.getCurrentDate());
			tmpobj.save();
		} else {
			console.log("[IN User.postSave] CANCEL refreshUser(g,"+ipn_cand+") being BCSIPerson already synchronized today");
		}
	} else {
		console.log("[IN User.postSave] CANNOT refreshUser(g,"+ipn_cand+") not being a BCSIPerson");
	}
}

Ce code fonctionnait jusqu’à il n’y a pas si longtemps, nous avons décidé de migrer tous notre code Rhino en Java et c’est lors de cette migration que vous problème de logs est survenue.
J’ai “bêtement” pensé que si le code Rhino avait fonctionné, il devait en être de même pour le code JAVA.

Auriez-vous une solution pour que l’update d’un user invoque l’action de son code hérité ou devons-nous “interdire” la création d’un user et systématique passer par un BCSIPerson (lorsque l’on souhaite cette synchro) ?

Merci beaucoup pour vos retours

@david ce besoin va de pair avec la règle de création à la volée d’un utilisateur demandé par @bmo.
Sur la BCSI, lorsqu’un utilisateur se connecte pour la première fois et qu’il n’a pas de compte, vous avez implémenté une règle pour créer un user à la volée. Ici nous voudrions que lors de cette création, on récupère les informations ARCA.
@bmo a “avoué” avoir profité de la permissivité du code Rhino pour implémenter cette fonctionnalité.
Le passage au code JAVA prouve que cette solution n’est pas pérenne, ni stable.
Pensez-vous avoir une solution ?

PS : Nous savons que ce besoin est très spécifique, nous comprenons donc que vous ne passiez pas de temps à développer une solution. Le but de ce ticket est de savoir s’il n’existe pas, par hasard, déjà une solution.

Cordialement

Comme l’a dit @francois si vous devez mettre de l’intelligence supplémentaire sur un objet système vous devez en faire un héritier et ne pas donner accès à l’objet d’origine. C’est ça le bon pattern.

NB: Rhino permettait d’ajouter dans certain cas du code car la logique c’est d’executer le code Rhino s’il existe puis le code Java à defaut, or les objets systèmes sont tous en Java, clairement ça c’est un anti-pattren