Modifier le fichier

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" Gestionnaire d'extension
  • Activer les modules "Statistique" et "Script automatisé de génération des statistiques" Module statistiques
  • Depuis l'écran de gestion des traitement planifiés, activer le traitement planifié "Batch d'extraction des statistiques" Traitement planifié

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,
      ...
      <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>
      ...
    
    A l'aide de l'attribut order, vous pouvez insérer votre bean dans la liste des deciders à l'endroit adapté à vos besoins.
  • 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é.
    ...
    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;
        }
    }
    ...
    
    Il suffit ensuite de déclarer le bean dans votre fichier de contexte
      ...
      <bean id="siteManagerProfileDecider" class="com.acme.statistics.util.decider.XxxxxxManagerProfileDecider">
          <property name="order" value="42000"/>
      </bean>
      ...
    
    A l'aide de l'attribut order, vous pouvez insérer votre bean dans la liste des deciders à l'endroit adapté à vos besoins.

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 contextel'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>