Intégration projet du module Statistiques
Activation du module
Par défaut, le module "Statistiques" est désactivé.
Avant d'activer le module, il est nécessaire d'obtenir l'accord du client.
Activation programmatique
Afin d'activer les statistiques de manière programmatique, il est nécessaire de le faire au premier démarrage de l'application.
L'activation s'effectue en ajoutant les 3 beans suivant dans le fichier ExtensionContext.xml de votre projet :
Exemple : monProjetExtensionContext.xml
<bean id="activationTemplateSiteComposant" class="com.kportal.core.context.AttributeToOverrideBean">
<property name="idExtensionToMerge" value="core"/>
<property name="idBeanToMerge" value="composantStatistics"/>
<property name="attributes">
<map>
<entry key="etat">
<util:constant static-field="com.kportal.extension.module.IModule.ETAT_ACTIF"/>
</entry>
</map>
</property>
</bean>
<bean id="activationStatisticsJobModule" class="com.kportal.core.context.AttributeToOverrideBean">
<property name="idExtensionToMerge" value="core"/>
<property name="idBeanToMerge" value="statisticJobModule"/>
<property name="attributes">
<map>
<entry key="etat">
<util:constant static-field="com.kportal.extension.module.IModule.ETAT_ACTIF"/>
</entry>
</map>
</property>
</bean>
<bean id="activationStatisticsTrigger" class="com.kportal.core.context.AttributeToOverrideBean">
<property name="idExtensionToMerge" value="core"/>
<property name="idBeanToMerge" value="statisticsTrigger"/>
<property name="attributes">
<map>
<entry key="etat">
<util:constant static-field="com.kportal.extension.module.IModule.ETAT_ACTIF"/>
</entry>
</map>
</property>
</bean>
Activation manuelle
Il est possible d'activer manuellement le module dans l'interface de K-Sup. Mais il est conseillé de réaliser l'activation de manière programmatique.
Dans le backoffice, l'activation du module nécessite les actions suivantes :
- Depuis le gestionnaire d'extensions, déplier la section "Socle CMS"

- Activer les modules "Statistique" et "Script automatisé de génération des statistiques"

- Depuis l'écran de gestion des traitement planifiés, activer le traitement planifié "Batch d'extraction des statistiques"

A partir de la version 7.0, l'applicatif va déterminer lui-même le client en scannant l'ExtensionContext du projet. A défaut de bean Extension dans le projet, c'est la valeur de la propriété statistics.client.id qui est utilisée.
En 6.7,vous devez valoriser la propriété statistics.client.id dans le fichier application_projet.properties de votre projet
Ajout d'un endpoint
L'ajout d'un nouveau endpoint, nécessite la déclaration d'un nouveau channel et d'un bridge depuis channel.in.core
Dans le cadre des statistiques, il est peu probable d'avoir besoin d'un nouveau endpoint.
Le cas échéant, voir avec l'équipe produit.
Ajout d'un profil fonctionnel
Le fonctionnement du calcul du profil est décrit dans cette page
Pour ajouter un nouveau profil fonctionnel , il suffit
- Soit d'instancier le bean PermissionProfileDecider dans votre fichier de contexte en valorisant les propriétés *
requiredPermissions* et/ou excludedPermissions et order selon vos besoins
Par exemple, pour ajouter un profil fonctionnel regroupant les utilisateurs ayant les droits sur la médiathèque,
A l'aide de l'attribut order, vous pouvez insérer votre bean dans la liste des deciders à l'endroit adapté à vos besoins.... <bean id="mediaManagerProfileDecider" class="com.kosmos.statistics.util.decider.profile.PermissionProfileDecider"> <property name="profile" value="MEDIAMANAGER"/> <property name="order" value="xxxxxx"/> <property name="requiredPermissions" value="#{'TECH/pho/C'.split(',')}"/> </bean> ... - Soit de créer un nouvean bean étendant AbstractProfileDecider en implémentant la méthode
String apply(AutorisationBean).
La méthode apply prend en paramètre l'AutorisationBean de l'utilisateur courant et retourne une chaine de caractère correspondant au profil fonctionnel souhaité.
Il suffit ensuite de déclarer le bean dans votre fichier de contexte... public class XxxxxxManagerProfileDecider extends AbstractProfileDecider { private static final String XXXXX_MANAGER = "XXXXXMANAGER"; @Override public String apply(final AutorisationBean arg) { if (arg != null && arg.isXxxxxxManager()) { LOGGER.debug("L'utilisateur actuel est ....."); return XXXXX_MANAGER; } LOGGER.trace("L'utilisateur actuel n'est pas ...."); return null; } } ...
A l'aide de l'attribut order, vous pouvez insérer votre bean dans la liste des deciders à l'endroit adapté à vos besoins.... <bean id="siteManagerProfileDecider" class="com.acme.statistics.util.decider.XxxxxxManagerProfileDecider"> <property name="order" value="42000"/> </bean> ...
Ajout d'un indicateur d'action
L'ajout d'un indicateur d'action se fera de manière préférentielle par de l'AOP sur une ou plusieurs méthodes d'un
service (ou assimilé) voire d'un DAO dans le cas de certains objets historiques K-Sup.
Selon les cas, on utilisera un aspect de type Before ou Around.
Ajout d'un indicateur HTTP d'accès à une URL
L'ajout d'un indicateur d'action nécessite la simple déclaration d'un filter. Par exemple, pour filtrer tous les appels HTTP au processus MON_PROCESSUS de l'extension MON_EXTENSION, déclarer le bean suivant et l'injecter dans les filtres d'inclusion du marqueur HTTP
...
<bean id="monprocessusHttpMarker" class="com.kosmos.statistics.marker.http.requestfilter.UrlMatchesFilter">
<property name="uri" value="${SGcontroller.mapping:/servlet/com.jsbsoft.jtf.core.SG}"/>
<property name="parameters">
<map>
<entry key-ref="EXT" value="MON_EXTENSION"/>
<entry key-ref="PROC" value="MON_PROCESSUS"/>
</map>
</property>
</bean>
<bean class="com.kportal.core.context.ListToAddBean">
<property name="idExtensionToMerge" ref="EXTENSION_CORE"/>
<property name="idBeanToMerge" value="httpMarkerProcessor"/>
<property name="listToMerge" value="includes"/>
<property name="add">
<list>
<ref bean="monprocessusHttpMarker"/>
</list>
</property>
</bean>
...
Ajout d'un indicateur d'action sur une création / mise à jour d'un bean de type PersitanceBean
Pour les PersitanceBean, le produit met à disposition un aspect générique, ContentUpdateAspect, permettant d'exécuter un code applicatif suite à une interception de méthode. Cet aspect applique une liste de processeurs (cf interface MarkerProcessor) Le bean applique une liste de MarkerProcessor (La liste des processeurs est initialisée par découverte). Chaque MarkerProcessor à la responsabilité de vérifier qu'il s'applique ou non via la méthode accept
...
@Override
public boolean accept(final PersitanceBean before, final PersitanceBean after) {
return isConditionRemplie && isClassAccepted(before.getClass());
}
...
La seconde méthode permet d'éxécuter un code applicatif
...
@Override
public void process(final PersitanceBean before, PersitanceBean after){
...
Code applicatif permettant de générer l'indicateur
...
}
...
Ajout d'un indicateur d'action sur un objet autre qu'un PersitanceBean
- Déclarer un intercepteur sur la ou les méthodes.
- La méthode doit être publique et non statique
- La méthode doit être appelée depuis l'extérieur de la classe — l'AOP ne fonctionne pas sur les appels internes
- La classe doit être dans le même contexte — l'AOP ne fonctionne pas sur une classe d'un jar externe
- La classe doit être un bean du contexte Spring
- La méthode interceptée doit être dans la classe écoutée, sinon, écouter la classe parente
- Ne pas réaliser d'interception de type * sur une classe ou un package, mais cibler précisément les méthodes
... <aop:config proxy-target-class="true"> <aop:aspect id="serviceXxxxxAspect" ref="xxxxxAspect"> <aop:pointcut id="xxxxxStatisticsInterceptor" expression="execution(* com.acme.service.ServiceXxxxx.save(..))" /> <aop:around pointcut-ref="xxxxxStatisticsInterceptor" method="maMethode"/> </aop:aspect> </aop:config> ... <bean id="xxxxxAspect" class="com.acme.aspect.XxxxxAspect" parent="abstractStatisticsAspect"/> ... - Créer un nouvel aspect dédié à votre indicateur.
La classe doit étendre AbstractStatisticsAspect afin de bénéficier du service ServiceCorePublisher de publication de message (publisher) et du service ServiceStatistique.... public class XxxxxAspect extends AbstractStatisticsAspect { public void maMethode(ProceedingJoinPoint call) throws Throwable { call.proceed(); try { final Object arg0 = call.getArgs()[0]; ... construction de la payload et des headers ... publisher.publish(payload, ..., null, null, headers); } catch (final Exception e) { LOG.error("Impossible de générer le marqueur statistiques", e); } } ... }
Ajout d'un indicateur de volume (batch)
Packages
Voici la syntaxe des packages a utiliser pour la mise en place des indicateurs sur votre projet :
package com.kosmos.[EXTENSION].statistics.marker.processor;
package com.kosmos.[EXTENSION].statistics.marker.module;
package com.kosmos.[EXTENSION].statistics.marker.volume.counter;
Ajout d'un indicateur de volume sur un type de fiche en ligne
Vous n'avez rien à faire : le produit va détecter les objets partagés et générer les compteurs de fiches en ligne.
Ajout d'un compteur spécifique
Pour ajouter un compteur de volume, il faut créer une classe implémentant com.kosmos.statistics.marker.volume.counter.Counter
et déclarer le bean dans le contexte.
Exemple avec le compteur de "document en mode téléchargement" :
package com.kosmos.ged.statistics.marker.volume.counter;
import com.kosmos.ged.context.GedConfig;
import com.kosmos.statistics.marker.volume.counter.Counter;
import com.kosmos.statistics.util.Indicator;
import com.kosmos.statistics.marker.volume.counter.CounterOnlineContent;
import com.univ.objetspartages.bean.DocumentBean;
import com.univ.objetspartages.dao.impl.DocumentDAO;
import com.univ.objetspartages.om.EtatFiche;
import java.util.List;
/**
* Coumpteur du nombre de fiches Document uniquement en téléchargement.
*/
public class CounterDocumentTelechargement implements Counter {
private static final String CONTENT = "DocumentTelechargement";
private DocumentDAO documentDAO;
@Override
public Indicator count() {
Indicator result = new Indicator();
result.setComponent(GedConfig.ID_EXTENSION);
result.setMarker(CounterOnlineContent.MARKER);
final List<DocumentBean> documents = documentDAO.select(" JOIN METATAG m on m.META_ID_FICHE = T1.ID_DOCUMENT and m.META_CODE_OBJET = '0017' and ETAT_OBJET = '" + EtatFiche.EN_LIGNE + "' and META_DOCUMENT_FICHIERGW = '1'");
result.addToPayload(Indicator.PAYLOAD_CONTENT_TYPE, CONTENT);
result.addToPayload(Indicator.PAYLOAD_COUNT, documents.size());
return result;
}
public void setDocumentDAO(final DocumentDAO documentDAO) {
this.documentDAO = documentDAO;
}
}
<bean id="statisticsDocumentTelechargementCounter" class="com.kosmos.ged.statistics.marker.volume.counter.CounterDocumentTelechargement">
<property name="documentDAO" ref="documentDAO"/>
</bean>