Auditing Inserts

Posts   
 
    
matdone
User
Posts: 12
Joined: 02-Oct-2007
# Posted on: 18-Oct-2007 07:28:08   

Hi, I am trying to setup the Auditing for my entities. I have successfully been able to get the auditing of updates working but not inserts. It seems as though the AuditInsertOfNewEntity never gets called. Here are my solution details.

I am using .net Remoting.

SD.LLBLGen.Pro.ORMSupportClasses.NET20 Version: v2.0.50727 (V2.5)

Web Config Settings

    
<configSections>
        <section name="dependencyInjectionInformation" 
                 type="SD.LLBLGen.Pro.ORMSupportClasses.DependencyInjectionSectionHandler, 
        SD.LLBLGen.Pro.ORMSupportClasses.NET20, Version=2.5.0.0, Culture=neutral, 
                 PublicKeyToken=ca73b74ba4e3ff27"/>
</configSections>

<dependencyInjectionInformation>
    <additionalAssemblies>
         <assembly filename="MBL.CAG.FOD.RACS.Helper.dll"/>
         <assembly fullName="MBL.CAG.FOD.RACS.Helper, Version=1.0.0.0, Culture=neutral, 
                          PublicKeyToken=null"/>
    </additionalAssemblies>
    <instanceTypeFilters>
        <instanceTypeFilter namespace="MBL.CAG.FOD.RACS.Helper"/>
    </instanceTypeFilters>
</dependencyInjectionInformation>

Save Method Details


public ReturnObject<bool> SaveRuleCriteria(LeadScheduleAutomationEntity entity)
   {        
            ReturnObject<bool> returnObject = new ReturnObject<bool>();     
            adapter.StartTransaction(IsolationLevel.ReadCommitted, "SaveAutomationRule");  
            try
            {
                entity.CreatedBy = UserShortName;
                entity.CreatedDate = DateTime.Now;

                adapter.SaveEntity(entity, false);
                adapter.Commit();
                returnObject.ReturnValue = true;
                returnObject.UIMessages.Add("Rule Successfully Save");              
            }
            catch (Exception ex)
            {
                adapter.Rollback();
                returnObject.ReturnValue = false;
                returnObject.UIMessages.Add("Rule Save Failed");
                returnObject.ErrorMessage.Add(ex.Message);
            }
            finally
            {
                adapter.Dispose();
            }
}

Audit Class Details.

        
namespace MBL.CAG.FOD.RACS.Helper
{
    [DependencyInjectionInfo(typeof(IEntity2), "AuditorToUse")]
    [Serializable]
    public class EntityAuditor : AuditorBase
    {
        private enum AuditType
        {
            DeleteOfEntity = 1,
            DirectDeleteOfEntities,
            DirectUpdateOfEntities,
            DereferenceOfRelatedEntity,
            ReferenceOfRelatedEntity,
            EntityFieldSet,
            InsertOfNewEntity,
            UpdateOfExistingEntity
        }

        private List<AuditLogEntity> _auditLogEntities;
        //private BaseClass.BLLRemoteBase _remoteBase;

        /// <summary>CTor </summary>
        public EntityAuditor()
        {
            _auditLogEntities = new List<AuditLogEntity>();
            //_remoteBase = new BLLRemoteBase();
        }


       public override void AuditInsertOfNewEntity(IEntityCore entity)
        {
            if (entity.LLBLGenProEntityName != "AuditLogEntity")
            {
                AuditLogEntity auditLog = new AuditLogEntity();
                auditLog.TableName = entity.LLBLGenProEntityName;
                auditLog.CreateDate = DateTime.Now;
                auditLog.CreatedBy = UserShortName();

                auditLog.AuditRecordTypeId = (int)AuditType.InsertOfNewEntity;
                _auditLogEntities.Add(auditLog);
            }
        }

        public override System.Collections.IList GetAuditEntitiesToSave()
        {
            return _auditLogEntities;
        }

        public override void TransactionCommitted()
        {
            _auditLogEntities.Clear();
        } 
   }
}

If anybody can see where I have gone wrong, that would be great.

Thanks, Matt.

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 18-Oct-2007 08:49:20   

Everything seems to be OK disappointed .

Could you confirm that a Insert is performed?

Also could yo confirm that the Auditor is injected (is present at output and successfully injected at your entities)?

David Elizondo | LLBLGen Support Team
matdone
User
Posts: 12
Joined: 02-Oct-2007
# Posted on: 18-Oct-2007 08:54:33   

I can confirm that the update method of my Auditor Class gets called and does everything I want it to do when I update and existing entity. When I save a new record no methods get called in the auditor class. The Save Method is used for both new entities and existing ones.

I have checked the logs and an Insert Statement is definitely been generated and my new record is created in the database. I also checked the entity property; IsNew and it is true for a new entities. None of the Auditor methods are called for new records.

Thanks for you help.

Regards, Matt.

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 18-Oct-2007 11:22:51   

Please provide the LLBLGen Pro runtime library version, the one you have specified is not the RTL version number. Consult: http://www.llblgen.com/TinyForum/Messages.aspx?ThreadID=7722

Would you please place a break point at the following line?

adapter.SaveEntity(entity, false);

And check whether the entity.Validator is set and that it's not null.

matdone
User
Posts: 12
Joined: 02-Oct-2007
# Posted on: 19-Oct-2007 02:40:26   

The Validator is set to null. I haven't seen in the documentation anything that says this need to be set in order to get an insert audit of an entity to work.

BTW: The validator is null for updates but they seem to get audited ok.

I am using 2.5.7.827. The version number I supplied is copied from Visual Studio 2005 properties; Runtime Version. (shouldn't they be the same??)

Thanks for you help. Matt

G.I.
User
Posts: 172
Joined: 09-Jun-2005
# Posted on: 19-Oct-2007 10:15:21   

Runtime version v2.0.50727 is the version of the .Net Framework ... if you look in Visual Studio at properties, version is the version of the DLL.

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 19-Oct-2007 11:59:41   

Validator, who said Validator frowning ? How stupid of me?!!

I meant entity.AuditorToUse Would you please check it out?

matdone
User
Posts: 12
Joined: 02-Oct-2007
# Posted on: 22-Oct-2007 01:43:05   

I have checked the AuditorToUse property of the entity for an insert action and it is set to null. I checked it for an update and it was set correctly to MBL.CAG.FOD.RACS.Helper.EntityAuditor. It looks like the dependency injection is not happening for inserts.

Thanks for your help Walaa.

Matt.

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 22-Oct-2007 04:46:17   

Hi Matt,

Weird... Dependency injection only injects the instance of the auditor to the AuditorToUse entity property, so your entity should have set that, even if no AuditoOfInsert is fired.

Could you post the code snippet where you instantiate the toUpdate entity and the toInsert entity?

Could you confirm that behavior with a small test project?

You can also email us the project to see what's wrong.

David Elizondo | LLBLGen Support Team
matdone
User
Posts: 12
Joined: 02-Oct-2007
# Posted on: 22-Oct-2007 09:39:49   

I am fairly sure the problem is caused with remoting and the LLBLGen dependency injection implementation. Here is the weird thing. When I first tried to implement the dependency injection I had to have the auditor class on the web server even though I included the dependency injection config vals on the remoting side. Therefore what I think is happening is that if a new object is instantiated on the web app side it is injecting the dependency on the web side and this isn't flowing through to the remoting server. If I instantiate a new object on the remoting side both Inserts and Update audits work.

I also tried instantiate an entity on the web server side and tried an update and it didn't work.

So it appears there is some sort of problem with the dependency injection and distributed remoting architectures.

If I had a spare couple of hours in my day I would try and investigate further but I am a bit pushed for time at the present.

In summary to replicate the problem follow these steps. 1. Create a Remote Server 2. Add Dependency Injection Config Values in Remoting Web.config as above. 3. Create a Web Server (standard web app configuration) 4. Create your Auditor implementation assembly 5. Create a Class that inherits from MarshalByRefObject in another Assembly that will be run via the remoting server (include wellknown entries in web.config). Include in this class a method that excepts and entity. 6. On the Web app; create an new instance of an entity via a web form button click or something. 7. Create a remoting channel and pass an entity to remoted class. 8. Execute Adapter.SaveEntity(entity). 9. Audit methods are not hit.

Maybe I have missed something simple but any help would be appreciated. Regards, Matt.

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 22-Oct-2007 11:21:05   

When I first tried to implement the dependency injection I had to have the auditor class on the web server even though I included the dependency injection config vals on the remoting side.

Web server is the remoting client side, and the remoting server is the remoting server side, right?

Dependancy Injection injects the Auditor class to the AuditorToUse property of an entity, when it is instanciated. So where ever you are going to create an instance of an entity, you should have the auditor class available and the DI sections written on the config file.

So if you are creating an instance on the client side but you don't have the DI section written on the client web.config, then the Auditor won't be injected.

If I'm missing something, please create a simple repro solution (client and server sides), that would be clearer for us to understand.

Thanks. Walaa

matdone
User
Posts: 12
Joined: 02-Oct-2007
# Posted on: 23-Oct-2007 02:21:46   

Well thats the answer. You need to put the dependency injection declarations into both web.config files. The remoting side and the web side. I'm am still undecided weather or not this is good software design on my behalf, but at least it works now.

Thanks again for your help. Regards, Matt.

matdone
User
Posts: 12
Joined: 02-Oct-2007
# Posted on: 23-Oct-2007 05:10:45   

Just a thought; Might it be better to inject the dependency into the adapter class. If you had some properties like you do with the entities (AuditorToUse). You would then only be auditing at the Business layer of your application and the UI would not have any dependency on the AuditorClass. This would therefore abstract the UI a bit better than it is now. Just a thought.

Matt.

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 23-Oct-2007 10:43:16   

The issue is that DI workds when the entity is created and you do that at client side. Another option is not to use DI to inject the AuditorToUse and rather set it manually in the BL when you are processing the entity.