Changeset 6079


Ignore:
Timestamp:
Aug 6, 2012, 3:20:43 PM (11 years ago)
Author:
Nicklas Nordborg
Message:

References #1601: Convert logging plug-in system to an extension point

This should now be implemented and the database log manager has been converted. Need to document changes and also add a note about backwards (in)compatibility.

Location:
trunk/src/core
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/core/core-extensions.xml

    r6052 r6079  
    119119  </extension-point>
    120120 
     121  <extension-point
     122    id="net.sf.basedb.core.log-manager">
     123    <action-class>net.sf.basedb.core.log.LogManagerFactory</action-class>
     124    <name>Log managers</name>
     125    <description>
     126      Extension point for logging changes that are made to items. This
     127      extension point is invoked for every access and the ClientContext
     128      is populated with the current SessionControl.
     129    </description>
     130  </extension-point>
     131 
    121132  <extension
    122133    id="net.sf.basedb.core.uri.http-connection-manager"
     
    198209  </extension>
    199210
     211  <extension
     212    id="net.sf.basedb.core.db-log-manager"
     213    extends="net.sf.basedb.core.log-manager"
     214    >
     215    <about>
     216      <name>Database log manager</name>
     217      <description>
     218        Information about changes to items are logged in the
     219        database. Some configuration options can be set in base.config.
     220      </description>
     221    </about>
     222    <index>1</index>
     223    <action-factory>
     224      <factory-class>net.sf.basedb.core.log.db.DbLogManagerFactory</factory-class>
     225    </action-factory>
     226  </extension>
     227
    200228  <!--
    201229  <extension
  • trunk/src/core/net/sf/basedb/core/Application.java

    r6046 r6079  
    2727import net.sf.basedb.core.data.SchemaVersionData;
    2828import net.sf.basedb.core.hibernate.JdbcWork;
    29 import net.sf.basedb.core.log.LogManagerFactory;
    3029import net.sf.basedb.core.authentication.Authenticator;
    3130import net.sf.basedb.util.ClassUtil;
     
    194193 
    195194  /**
    196     The name of the log manager factory class, if any.
    197   */
    198   private static String logManagerFactoryDriver;
    199 
    200   /**
    201     The log manager factory currently in use (may be null)
    202   */
    203   private static LogManagerFactory logManagerFactory;
    204  
    205   /**
    206195    Manager for the extensions system.
    207196  */
     
    441430      secondaryStorageDriver = Config.getString("secondary.storage.driver");
    442431      log.info("secondary.storage.driver = " + secondaryStorageDriver);
    443      
    444       logManagerFactoryDriver = Config.getString("changelog.factory");
    445       log.info("changelog.factory = " + logManagerFactoryDriver);
    446432     
    447433      sessionCacheTimeout = Config.getInt("cache.timeout", 20); // minutes
     
    558544        java.io.File xtSettings = new java.io.File(userFilesDirectory, "extension-settings.xml");
    559545        xtManager = new ExtensionsManager(xtRegistry, xtSettings);
    560        
     546
    561547        // Add core extension points and extensions
    562548        xtManager.addURI(Application.class.getResource("/core-extensions.xml").toURI());
     
    574560        // Finalize registration
    575561        xtManager.processFiles(new MarkAsProcessedProcessor(), new WasProcessedFilter(results));
    576 
    577         // Initialise log manager factory
    578         if (logManagerFactoryDriver != null)
    579         {
    580           Class factoryClass = ClassUtil.checkAndLoadClass(null,
    581               logManagerFactoryDriver, true, LogManagerFactory.class);
    582           logManagerFactory = (LogManagerFactory)factoryClass.newInstance();
    583         }
    584              
     562           
    585563        // Adding a task that cleans the session control cache at regular intervals
    586564        long milliSeconds = 60000L * sessionCacheTimeout;  // minutes --> milliseconds
     
    762740  }
    763741
    764   /**
    765     Get the log manager factory, or null if not enabled.
    766     @since 2.13
    767   */
    768   static LogManagerFactory getLogManagerFactory()
    769   {
    770     return logManagerFactory;
    771   }
    772  
    773  
     742
    774743  public static ExtensionsManager getExtensionsManager()
    775744  {
  • trunk/src/core/net/sf/basedb/core/DbControl.java

    r5889 r6079  
    3737import net.sf.basedb.core.log.LoggingInterceptor;
    3838import net.sf.basedb.util.ClassUtil;
     39import net.sf.basedb.util.extensions.ClientContext;
     40import net.sf.basedb.util.extensions.ExtensionsInvoker;
     41import net.sf.basedb.util.extensions.manager.ExtensionsManager;
    3942
    4043import java.util.IdentityHashMap;
     
    143146    Create a new object.
    144147  */
     148  @SuppressWarnings("unchecked")
    145149  DbControl(SessionControl sc)
    146150    throws BaseException
    147151  {
    148152    this.sc = sc;
    149     LogManagerFactory logManagerFactory = Application.getLogManagerFactory();
     153   
     154    // Initialize logging extensions...
     155    ExtensionsManager xtManager = Application.getExtensionsManager();
     156    ClientContext context = new ClientContext(sc);
     157    ExtensionsInvoker<LogManagerFactory> invoker = (ExtensionsInvoker<LogManagerFactory>)xtManager.getRegistry().useExtensions(
     158      context, xtManager.getSettings(), "net.sf.basedb.core.log-manager");   
    150159    LoggingInterceptor interceptor = null;
    151     if (logManagerFactory != null)
     160    if (invoker.getNumExtensions() > 0)
    152161    {
    153162      logControl = new LogControl(this);
    154       interceptor = new LoggingInterceptor(logControl, logManagerFactory);
    155     }
     163      interceptor = new LoggingInterceptor(logControl, invoker);
     164    }
     165
    156166    hSession = new SessionWrapper(HibernateUtil.newSession(interceptor, null));
    157167    hTransaction = HibernateUtil.newTransaction(hSession);
  • trunk/src/core/net/sf/basedb/core/Install.java

    r6061 r6079  
    7171import net.sf.basedb.util.Values;
    7272import net.sf.basedb.util.XMLUtil;
     73import net.sf.basedb.util.extensions.manager.Settings;
    7374import net.sf.basedb.util.extensions.xml.PluginInfo;
    7475import net.sf.basedb.util.extensions.xml.XmlLoader;
     
    939940        createNews(version + " installed", "Welcome to your new BASE server.");
    940941      }
    941    
     942     
     943      if (!update || schemaVersion.getSchemaVersion() < 108)
     944      {
     945        // The DbLogManager should be disabled by default unless the (old)
     946        // base.config setting has enabled it when installing or updating from
     947        // pre BASE 3.2
     948        Settings xtSettings = Application.getExtensionsManager().getSettings();
     949        xtSettings.enableExtension("net.sf.basedb.core.db-log-manager",
     950          "net.sf.basedb.core.log.db.DbLogManagerFactory".equals(Config.getString("changelog.factory")));
     951        xtSettings.save();
     952      }
     953     
    942954      if (progress != null)
    943955      {
  • trunk/src/core/net/sf/basedb/core/log/EntityDetails.java

    r5218 r6079  
    4848{
    4949
    50   private final EntityLogger logger;
    5150  private final Object entity;
    5251  private final ChangeType changeType;
     
    5756  private final int[] dirty;
    5857 
    59   public EntityDetails(EntityLogger logger, Object entity, ChangeType changeType,
     58  public EntityDetails(Object entity, ChangeType changeType,
    6059      Object[] state, Object[] previousState, String[] properties, Type[] types)
    6160  {
    62     this.logger = logger;
    6361    this.entity = entity;
    6462    this.changeType = changeType;
     
    7068    findDirtyCollections();
    7169  }
    72  
    73   /**
    74     Get the entity logger that handles the logging for this
    75     event.
    76   */
    77   public EntityLogger getEntityLogger()
    78   {
    79     return logger;
    80   }
    81  
     70   
    8271  /**
    8372    Get the entity that was changed.
  • trunk/src/core/net/sf/basedb/core/log/LogManagerFactory.java

    r5038 r6079  
    2323
    2424import net.sf.basedb.core.LogControl;
     25import net.sf.basedb.util.extensions.Action;
    2526
    2627/**
     
    4546*/
    4647public interface LogManagerFactory
     48  extends Action
    4749{
    4850 
  • trunk/src/core/net/sf/basedb/core/log/LoggingInterceptor.java

    r5384 r6079  
    2727import java.io.ObjectOutputStream;
    2828import java.io.Serializable;
     29import java.util.ArrayList;
    2930import java.util.Iterator;
    3031import java.util.LinkedList;
     
    3334
    3435import net.sf.basedb.core.LogControl;
     36import net.sf.basedb.util.extensions.ExtensionsInvoker;
    3537
    3638import org.hibernate.EmptyInterceptor;
     
    6668  private static final long serialVersionUID = -9108587050205509572L;
    6769  private final LogControl logControl;
    68   private final LogManagerFactory logManagerFactory;
    69   private LogManager logManager;
    70   private List<EntityDetails> changes;
     70  private final ExtensionsInvoker<LogManagerFactory> logInvoker;
     71  private List<LogManagerAndFactory> logHandlers;
     72  private List<LogDetails> changes;
    7173 
    7274  /**
    7375    Creates a new interceptor.
    7476    @param logControl The LogControl that is managing the current transaction
    75     @param logManagerFactory The log manager factory to use for logging
    76   */
    77   public LoggingInterceptor(LogControl logControl, LogManagerFactory logManagerFactory)
     77    @param logInvoker The extension invoker that create log manager factories
     78  */
     79  public LoggingInterceptor(LogControl logControl, ExtensionsInvoker<LogManagerFactory> logInvoker)
    7880  {
    7981    this.logControl = logControl;
    80     this.logManagerFactory = logManagerFactory;
     82    this.logInvoker = logInvoker;
    8183  }
    8284 
     
    128130    if (changes != null && changes.size() > 0)
    129131    {
    130       for (EntityDetails entry : changes)
    131       {
    132         entry.getEntityLogger().logChanges(logManager, entry);
     132      for (LogDetails entry : changes)
     133      {
     134        entry.logger.logChanges(entry.manager, entry.details);
    133135      }
    134136      // NOTE! A flush may happen more than once during the lifetime of a
     
    147149  public void afterTransactionCompletion(Transaction tx)
    148150  {
    149     if (logManager != null)
    150     {
    151       if (tx.wasRolledBack())
    152       {
    153         logManager.afterRollback();
    154       }
    155       else
    156       {
    157         logManager.afterCommit();
    158       }
    159     }
    160     logManager = null;
     151    if (logHandlers == null)
     152    {
     153      boolean rollback = tx.wasRolledBack();
     154      for (LogManagerAndFactory handler : logHandlers)
     155      {
     156        try
     157        {
     158          if (rollback)
     159          {
     160            handler.manager.afterRollback();
     161          }
     162          else
     163          {
     164            handler.manager.afterCommit();
     165          }
     166        }
     167        catch (RuntimeException ex)
     168        {}
     169      }
     170    }
     171    logHandlers = null;
    161172    changes = null;
    162173  }
     
    171182      Object[] previousState, String[] propertyNames, Type[] types)
    172183  {
    173     if (logManager == null)
    174     {
    175       this.logManager = logManagerFactory.getLogManager(logControl);
    176       this.changes = new LinkedList<EntityDetails>();
    177     }
    178     EntityLogger logger = logManagerFactory.getEntityLogger(logManager, entity);
    179     if (logger != null)
    180     {
    181       changes.add(new EntityDetails(logger, entity, action,
    182           state, previousState, propertyNames, types));
    183     }
    184 
    185   }
    186  
     184    if (logHandlers == null)
     185    {
     186      // First detected change, create log managers and space for recording changes
     187      this.logHandlers = new ArrayList<LogManagerAndFactory>(logInvoker.getNumExtensions());
     188      this.changes = new LinkedList<LogDetails>();
     189     
     190      for (LogManagerFactory factory : logInvoker)
     191      {
     192        logHandlers.add(new LogManagerAndFactory(factory, factory.getLogManager(logControl)));
     193      }
     194     
     195    }
     196   
     197    EntityDetails details = null;
     198    for (LogManagerAndFactory handler : logHandlers)
     199    {
     200      EntityLogger logger = handler.factory.getEntityLogger(handler.manager, entity);
     201      if (logger != null)
     202      {
     203        if (details == null) details = new EntityDetails(entity, action,
     204            state, previousState, propertyNames, types);
     205        changes.add(new LogDetails(handler.manager, logger, details));
     206      }
     207    }
     208  }
    187209 
    188210  // This class is not serializable
     
    198220  }
    199221
     222 
     223  static class LogManagerAndFactory
     224  {
     225    final LogManagerFactory factory;
     226    final LogManager manager;
     227   
     228    LogManagerAndFactory(LogManagerFactory factory, LogManager manager)
     229    {
     230      this.factory = factory;
     231      this.manager = manager;
     232    }
     233  }
     234 
     235  static class LogDetails
     236  {
     237    final LogManager manager;
     238    final EntityLogger logger;
     239    final EntityDetails details;
     240   
     241    LogDetails(LogManager manager, EntityLogger logger, EntityDetails details)
     242    {
     243      this.manager = manager;
     244      this.logger = logger;
     245      this.details = details;
     246    }
     247  }
    200248}
  • trunk/src/core/net/sf/basedb/core/log/db/DbLogManagerFactory.java

    r5652 r6079  
    3636import net.sf.basedb.core.log.LogManager;
    3737import net.sf.basedb.core.log.LogManagerFactory;
     38import net.sf.basedb.util.extensions.ActionFactory;
     39import net.sf.basedb.util.extensions.InvokationContext;
    3840
    3941/**
     
    4749*/
    4850public class DbLogManagerFactory
    49   implements LogManagerFactory
     51  implements LogManagerFactory, ActionFactory<LogManagerFactory>
    5052{
    5153 
     
    6567    setSpecialLogger(AnnotationSetData.class, new AnnotationSetLogger(detailedProperties));
    6668  }
     69 
     70  /*
     71    From the ActionFactory interface
     72    --------------------------------
     73  */
     74  @Override
     75  public boolean prepareContext(InvokationContext<? super LogManagerFactory> context)
     76  {
     77    return true;
     78  }
     79 
     80  @Override
     81  public LogManagerFactory[] getActions(InvokationContext<? super LogManagerFactory> context)
     82  {
     83    return new LogManagerFactory[] { this };
     84  }
     85  // -----------------------------------
    6786
    6887  /*
Note: See TracChangeset for help on using the changeset viewer.