Changeset 5038


Ignore:
Timestamp:
Aug 7, 2009, 12:50:01 PM (14 years ago)
Author:
Nicklas Nordborg
Message:

References #108: Logging the change history of an item

This enables configurable logging possibility. An implementation that logs to the database is supplied but turned off by default. All annotatable items has got support for logging, but only changes that happens on the item itself is logged. Eg. changes to annotations, files, etc. are not yet possible to log.

A single log entry corresponds to one database transaction and contains information about:

  • Date and time
  • The user that made the change
  • The session that the change was made in
  • Which client application that was used
  • Which project that was active
  • Which plug-in/job that was executing when the change was made
  • All items that was created/modified/deleted in the transaction
Location:
trunk
Files:
16 added
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/config/dist/base.config

    r5023 r5038  
    140140# secondary.storage.time = 18:15,07:30
    141141
     142# =========================
     143# Change history section
     144# =========================
     145
     146# Class name of the changelog factory; leave empty to disable the changelog
     147# changelog.factory = net.sf.basedb.core.log.db.DbLogManagerFactory
     148
    142149# ===============
    143150# General section
  • trunk/src/core/net/sf/basedb/core/Application.java

    r5023 r5038  
    2828import net.sf.basedb.core.data.SchemaVersionData;
    2929import net.sf.basedb.core.hibernate.JdbcWork;
     30import net.sf.basedb.core.log.LogManagerFactory;
    3031import net.sf.basedb.core.authentication.Authenticator;
     32import net.sf.basedb.util.ClassUtil;
    3133import net.sf.basedb.util.FileUtil;
    3234import net.sf.basedb.util.RegexpFileFilter;
     
    187189 
    188190  /**
     191    The name of the log manager factory class, if any.
     192  */
     193  private static String logManagerFactoryDriver;
     194
     195  /**
     196    The log manager factory currently in use (may be null)
     197  */
     198  private static LogManagerFactory logManagerFactory;
     199 
     200  /**
    189201    Get the major version.
    190202  */
     
    401413      secondaryStorageDriver = Config.getString("secondary.storage.driver");
    402414      log.info("secondary.storage.driver = " + secondaryStorageDriver);
     415     
     416      logManagerFactoryDriver = Config.getString("changelog.factory");
     417      log.info("changelog.factory = " + logManagerFactoryDriver);
    403418     
    404419      sessionCacheTimeout = Config.getInt("cache.timeout", 20); // minutes
     
    502517        RawDataTypes.initPlatforms();
    503518 
     519        // Initialise log manager factory
     520        if (logManagerFactoryDriver != null)
     521        {
     522          Class factoryClass = ClassUtil.checkAndLoadClass(null,
     523              logManagerFactoryDriver, true, LogManagerFactory.class);
     524          logManagerFactory = (LogManagerFactory)factoryClass.newInstance();
     525        }
     526       
    504527        // Adding a task that cleans the session control cache at regular intervals
    505528        long milliSeconds = 60 * 1000 * sessionCacheTimeout;
     
    678701
    679702  /**
     703    Get the log manager factory, or null if not enabled.
     704    @since 2.13
     705  */
     706  static LogManagerFactory getLogManagerFactory()
     707  {
     708    return logManagerFactory;
     709  }
     710 
     711  /**
    680712    Get the maximum number of minutes permission information for
    681713    a logged in user is kept in memory before beeing reloaded.
     
    944976    @param parent The parent session control
    945977    @param plugin The plugin to execute
     978    @param job The job that executes the plug-in, or null
    946979    @return The new plugin session control
    947980  */
    948   static synchronized PluginSessionControl newPluginSessionControl(SessionControl parent, PluginDefinition plugin)
     981  static synchronized PluginSessionControl newPluginSessionControl(SessionControl parent,
     982    PluginDefinition plugin, Job job)
    949983  {
    950984    String sessionControlId = null;
     
    953987      sessionControlId = generateRandomId(8);
    954988    } while (sessionCache.containsKey(sessionControlId));
    955     return new PluginSessionControl(sessionControlId, parent, plugin);
     989    return new PluginSessionControl(sessionControlId, parent, plugin, job);
    956990  }
    957991 
  • trunk/src/core/net/sf/basedb/core/DbControl.java

    r5014 r5038  
    3232import net.sf.basedb.core.data.GroupData;
    3333import net.sf.basedb.core.data.UserData;
     34import net.sf.basedb.core.log.LogManagerFactory;
     35import net.sf.basedb.core.log.LoggingInterceptor;
    3436import net.sf.basedb.util.ClassUtil;
    3537
     
    7476 
    7577  /**
     78    Handles logging of changes to items.
     79  */
     80  private LogControl logControl;
     81
     82  /**
    7683    The Hibernate session.
    7784  */
     
    132139  {
    133140    this.sc = sc;
    134     hSession = HibernateUtil.newSession();
     141    LogManagerFactory logManagerFactory = Application.getLogManagerFactory();
     142    LoggingInterceptor interceptor = null;
     143    if (logManagerFactory != null)
     144    {
     145      logControl = new LogControl(this);
     146      interceptor = new LoggingInterceptor(logControl, logManagerFactory);
     147    }
     148    hSession = HibernateUtil.newSession(interceptor);
    135149    hTransaction = HibernateUtil.newTransaction(hSession);
    136150    itemCache = new IdentityHashMap<BasicData, BasicItem>();
     
    162176  {
    163177    return sc;
     178  }
     179 
     180  /**
     181    Get the log controller for this db control. May be null if
     182    logging has been disabled.
     183    @since 2.13
     184  */
     185  LogControl getLogControl()
     186  {
     187    return logControl;
    164188  }
    165189 
     
    9891013      if (item.hasPermission(Permission.RESTRICTED_WRITE))
    9901014      {
    991         HibernateUtil.updateData(hSession, item.getData());
     1015        HibernateUtil.lockData(hSession, item.getData(), org.hibernate.LockMode.NONE);
     1016//        HibernateUtil.updateData(hSession, item.getData());
    9921017      }
    9931018      else if (item.hasPermission(Permission.READ))
  • trunk/src/core/net/sf/basedb/core/HibernateUtil.java

    r5037 r5038  
    7070
    7171import org.hibernate.Hibernate;
     72import org.hibernate.Interceptor;
    7273import org.hibernate.SessionFactory;
    7374import org.hibernate.Session;
     
    904905    throws BaseException
    905906  {
     907    return newSession(null);
     908  }
     909 
     910  /**
     911    Create a new Hibernate session, optionally with an interceptor.
     912    @since 2.13
     913  */
     914  static Session newSession(Interceptor interceptor)
     915    throws BaseException
     916  {
    906917    assert sf != null : "HibernateUtil has not been initialised";
    907918    try
    908919    {
    909       Session session = sf.openSession();
     920      Session session = sf.openSession(interceptor);
    910921      // FlushMode.COMMIT means that all changes
    911922      // are automatically flushed before a commit is performed
  • trunk/src/core/net/sf/basedb/core/Install.java

    r5015 r5038  
    114114    method.
    115115  */
    116   public static final int NEW_SCHEMA_VERSION = Integer.valueOf(72).intValue();
     116  public static final int NEW_SCHEMA_VERSION = Integer.valueOf(73).intValue();
    117117 
    118118  public static synchronized void createTables(boolean update, final ProgressReporter progress)
  • trunk/src/core/net/sf/basedb/core/PluginDefinition.java

    r4889 r5038  
    11591159    }
    11601160    if (sc == null) sc = getSessionControl();
    1161     p.init(sc.getPluginSessionControl(this),
     1161    p.init(sc.getPluginSessionControl(this, job),
    11621162      configuration == null ? new ParameterValuesImpl(this) : configuration.getParameterValuesImpl(configuration.getParameterVersion()),
    11631163      job == null ? new ParameterValuesImpl(this) : job.getParameterValuesImpl()
  • trunk/src/core/net/sf/basedb/core/PluginRequest.java

    r4889 r5038  
    8787    this.requestParameters = new HashMap<String, List<?>>();
    8888    this.parameterInfo = new HashMap<String, PluginParameter<?>>();
    89     plugin.init(sc.getPluginSessionControl(pluginDefinition), configurationParameters, jobParameters);
     89    plugin.init(sc.getPluginSessionControl(pluginDefinition, job), configurationParameters, jobParameters);
    9090  }
    9191
  • trunk/src/core/net/sf/basedb/core/PluginSessionControl.java

    r4517 r5038  
    4545    @param plugin The plugin that is executing
    4646  */
    47   PluginSessionControl(String id, SessionControl parent, PluginDefinition plugin)
     47  PluginSessionControl(String id, SessionControl parent, PluginDefinition plugin, Job job)
    4848  {
    49     super(id, parent, plugin);
     49    super(id, parent, plugin, job);
    5050    this.parent = parent;
    5151  }
     
    102102    parent as this session control has.
    103103  */
    104   PluginSessionControl getPluginSessionControl(PluginDefinition plugin)
     104  PluginSessionControl getPluginSessionControl(PluginDefinition plugin, Job job)
    105105  {
    106     return Application.newPluginSessionControl(parent, plugin);
     106    return Application.newPluginSessionControl(parent, plugin, job);
    107107  }
    108108
  • trunk/src/core/net/sf/basedb/core/SessionControl.java

    r5016 r5038  
    134134  private final Map<ContextKey, ItemContext> currentContexts;
    135135 
     136  private int pluginId;
     137 
     138  private int jobId;
     139 
    136140  /**
    137141    Create a new session control object using another one as the template.
     
    144148    @param plugin The plugin that is executing
    145149  */
    146   SessionControl(String id, SessionControl parent, PluginDefinition plugin)
     150  SessionControl(String id, SessionControl parent, PluginDefinition plugin, Job job)
    147151  {
    148152    this.id = id;
     
    152156    this.dbControlCache = Collections.synchronizedMap(new WeakHashMap<DbControl,String>());
    153157    this.currentContexts = parent.currentContexts;
     158    this.pluginId = plugin.getId();
     159    if (job != null) this.jobId = job.getId();
    154160    LoginInfo li = new LoginInfo(parent.loginInfo);
    155     li.keyring = new Keyring(li.keyring, plugin.getId(), plugin.getUsePermissions());
     161    li.keyring = new Keyring(li.keyring, pluginId, plugin.getUsePermissions());
    156162    this.loginInfo = li;
    157163  }
     
    729735
    730736  /**
     737    Get the id of the current user session, or 0 if no user is logged in.
     738    Use {@link Session#getById(DbControl, int)} to the {@link Session}
     739    object.
     740    @return The session id, or 0 if no user is logged in
     741    @since 2.13
     742  */
     743  public int getCurrentSessionId()
     744  {
     745    updateLastAccess();
     746    return loginInfo == null ? 0 : loginInfo.sessionId;
     747  }
     748 
     749  /**
     750    Get the id of the plug-in that is currently running with this
     751    session control.
     752    @return The plug-in id, or 0 if not running by a plug-in
     753    @since 2.13
     754  */
     755  public int getPluginId()
     756  {
     757    updateLastAccess();
     758    return pluginId;
     759  }
     760 
     761  /**
     762    Get the id of the job that is currently running with this
     763    session control.
     764    @return The job id, or 0 if not running by a job
     765    @since 2.13
     766  */
     767  public int getJobId()
     768  {
     769    updateLastAccess();
     770    return jobId;
     771  }
     772 
     773  /**
    731774    Check if the logged in user was impersonated by another user.
    732775    @return TRUE or FALSE
     
    853896    Create a new session control for executing a plugin.
    854897    @param plugin The plugin to execute
     898    @param job The job that executes the plug-in, or null
    855899    @return A plugin session control
    856900  */
    857   PluginSessionControl getPluginSessionControl(PluginDefinition plugin)
    858   {
    859     return Application.newPluginSessionControl(this, plugin);
     901  PluginSessionControl getPluginSessionControl(PluginDefinition plugin, Job job)
     902  {
     903    return Application.newPluginSessionControl(this, plugin, job);
    860904  }
    861905 
  • trunk/src/core/net/sf/basedb/core/Update.java

    r4938 r5038  
    3636
    3737import net.sf.basedb.core.data.ArrayDesignData;
     38import net.sf.basedb.core.data.ChangeHistoryData;
     39import net.sf.basedb.core.data.ChangeHistoryDetailData;
    3840import net.sf.basedb.core.data.DataCubeData;
    3941import net.sf.basedb.core.data.ExperimentData;
     
    814816    </td>
    815817  </tr>
     818  <tr>
     819    <td>73</td>
     820    <td>
     821      Added {@link ChangeHistoryData} and {@link ChangeHistoryDetailData}.
     822      No special update is needed. Only increase the schema version.
     823    </td>
     824  </tr>
    816825  </table>
    817826
     
    10961105      }
    10971106     
    1098       if (schemaVersion < 63)
    1099       {
    1100         if (progress != null) progress.display((int)(62*progress_factor), "--Updating schema version: " + schemaVersion + " -> 63...");
    1101         schemaVersion = setSchemaVersionInTransaction(session, 63);
    1102       }
    1103       // Schemaversion 64-72 only updates the version number
    1104       if (schemaVersion < 72)
    1105       {
    1106         if (progress != null) progress.display((int)(71*progress_factor), "--Updating schema version: " + schemaVersion + " -> 72...");
    1107         schemaVersion = setSchemaVersionInTransaction(session, 72);
     1107      // Schemaversion 61-73 only updates the version number
     1108      if (schemaVersion < 73)
     1109      {
     1110        if (progress != null) progress.display((int)(72*progress_factor), "--Updating schema version: " + schemaVersion + " -> 73...");
     1111        schemaVersion = setSchemaVersionInTransaction(session, 73);
    11081112      }
    11091113     
  • trunk/src/core/net/sf/basedb/core/data/AnnotatedData.java

    r4889 r5038  
    3636public abstract class AnnotatedData
    3737  extends CommonData
    38   implements AnnotatableData
     38  implements AnnotatableData, LoggableData
    3939{
    4040
Note: See TracChangeset for help on using the changeset viewer.