Activity Events

Last modified by Vincent Massol on 2024/11/19 16:12

 XWiki
 Implementation
 Completed
 

Description

Goal

Log events fired by xwiki-observation into a dedicated table in the database, allowing cheap retrieval of activity within various scopes: farm, wiki, space.

Architecture proposal

Summary:

  • Additions to the Event interface
    • Event getParent() allowing parent/child relationship management for events generated after some previous event
    • Date getDate() time at which the event occurred
    • Object getSource() get the source of the event from the event itself
    • Object getData() get of the data associated to the event from the event itself
  • Externalization of the event matching feature into dedicated classes
  • Creation of a criteria component made of current com.xpn.xwiki.criteria.* classes

Important notes:

  • This design page is a Work in Progress. 
  • The problem with the current proposal is that the persistence manager has to know the events it receives to be able to perform the matching between criteria fields and anonymous params in the database. A possible solution could be to add some meaningful fields in the event table: wiki, space, fullName, user.
  • Since we want to be able to add persistent events dynamically we might not be able to use hibernate (we don't want to add a new implementer class to the hibernate mapping each time we implement PersistentEvent). To be verified.

Structure

xwiki-observation-local

|-- ./EventListener.java (i)
|-- ./ObservationManager.java (i)
|-- ./event
|   |-- ./event/AbstractDocumentEvent.java (implements PersistentEvent)
|   |-- ./event/ActionExecutionEvent.java
|   |-- ./event/AllEvent.java
|   |-- ./event/ApplicationStartedEvent.java
|   |-- ./event/ApplicationStoppedEvent.java
|   |-- ./event/DocumentDeleteEvent.java
|   |-- ./event/DocumentSaveEvent.java
|   |-- ./event/DocumentUpdateEvent.java
|   |-- ./event/Event.java (i)
|   |-- ./event/PersistentEvent.java (i) (extends Event)
|   `-- ./event/criteria
|       |-- ./event/criteria/AbstractDocumentEventCriteria.java
|       |-- ./event/criteria/ActionExecutionEventCriteria.java
|       |-- ./event/criteria/ApplicationStartedEventCriteria.java
|       |-- ./event/criteria/ApplicationStoppedEventCriteria.java
|       |-- ./event/criteria/DocumentDeleteEventCriteria.java
|       |-- ./event/criteria/DocumentSaveEventCriteria.java
|       |-- ./event/criteria/DocumentUpdateEventCriteria.java
|       |-- ./event/criteria/EventCriteria.java (i)
|   `-- ./event/matching
|       |-- ./event/filter/AlwaysMatchingEventMatcher.java
|       |-- ./event/filter/EventMatcher.java (i)
|       |-- ./event/filter/FixedNameEventMatcher.java
|       `-- ./event/filter/RegexEventMatcher.java
`-- ./internal
    `-- ./internal/DefaultObservationManager.java

xwiki-observation-persistence

|-- ./EventPersistenceManager.java (i)
`-- ./internal
    `-- ./internal/DefaultEventPersistenceManager.java (implements EventPersistenceManager, EventListener)

PersistentEvent

public interface PersistentEvent extends Event
{
    String getId();
    String getParentId();

    String getString1();
    String getString2();
    String getString3();
    String getString4();
    String getString5();
    String getString6();
    String getString7();
    String getString8();
    String getString9();
    String getString10();

    String getText1();
    String getText2();
    String getText3();

    float getNumber1();
    float getNumber2();
    float getNumber3();

    Date getDate1();
    Date getDate2();
    Date getDate3();
}    

EventPersistenceManager

import org.xwiki.criteria.Period; // allows to match events between two dates
import org.xwiki.criteria.Scope; // allows to match events fired from a farm, a wiki, a space, a document
import org.xwiki.criteria.Users; // allows to match events fired by a given list of users

public interface EventPersistenceManager
{
    List<Event> getEvents(Event eventType, Period periodCriterion, Scope scopeCriterion, int start, int offset);

    List<Event> getEvents(Event eventType, Users userCriterion, Period periodCriterion, Scope scopeCriterion, int start, int offset);

    // To be extended
}

activity.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
 <class name="org.xwiki.activity.internal.DefaultActivityEvent" table="activityevent">
  <id name="id" type="string" unsaved-value="undefined">
   <column name="id" length="255" not-null="true" />
   <generator class="assigned" />
  </id>
  <property name="date" type="timestamp">
   <column name="date" />
  </property>
  <property name="class" type="string">
   <column name="class" length="255" />
  </property>
  <property name="parentId" type="string">
   <column name="parentId" length="255" />
  </property>

                <!-- String parameters -->
             
  <property name="string1" type="string">
   <column name="string1" length="255" />
  </property>
  <property name="string2" type="string">
   <column name="string2" length="255" />
  </property>
  <property name="string3" type="string">
   <column name="string3" length="255" />
  </property>
  <property name="string4" type="string">
   <column name="string4" length="255" />
  </property>
  <property name="string5" type="string">
   <column name="string5" length="255" />
  </property>
  <property name="string6" type="string">
   <column name="string6" length="255" />
  </property>
  <property name="string7" type="string">
   <column name="string7" length="255" />
  </property>
  <property name="string8" type="string">
   <column name="string8" length="255" />
  </property>
  <property name="string9" type="string">
   <column name="string9" length="255" />
  </property>
  <property name="string10" type="string">
   <column name="string10" length="255" />
  </property>

  <property name="string10" type="string">
   <column name="string10" length="255" />
  </property>

                <!-- Text parameters -->

  <property name="text1" type="string">
   <column name="text1" length="2000" />
  </property>
  <property name="text2" type="string">
   <column name="string10" length="2000" />
  </property>
  <property name="text3" type="string">
   <column name="text3" length="2000" />
  </property>

                <!-- Number parameters -->

  <property name="number1" type="float">
   <column name="number1" />
  </property>
  <property name="number2" type="float">
   <column name="number2" />
  </property>
  <property name="number3" type="float">
   <column name="number3" />
  </property>

                <!-- Date parameters -->

  <property name="date1" type="timestamp">
   <column name="date1" />
  </property>
  <property name="date2" type="timestamp">
   <column name="date2" />
  </property>
  <property name="date3" type="timestamp">
   <column name="date3" />
  </property>
 </class>
</hibernate-mapping>

 

Get Connected