Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Audit record created for Operation even after using skipAudit

    Hi,

    I am working on SmartGWT version 12.1-p20200926. I am trying to implement a UNDO feature on ListGrid using the audit datasources.

    For the same I have my datasource like:

    Code:
    <DataSource ID="XXXSQL"
                serverType="sql"
                tableName="XXX"
                audit="true"
                xmlns:fmt="WEB-INF/">
        <fmt:bundle basename="com.yyy.client.DSMessages"/>
        <fields>
            <field name="XXX_id" type="sequence" hidden="true" primaryKey="true"/>
            <field name="XXX_type_id" type="integer" foreignKey="CDSQL.code_id" joinType="outer" required="true"/>
            <field name="cmp_id" type="text" length="36" foreignKey="cmpSQL.cmp_id" required="true"/>
            <field name="name" type="text" length="100" required="true">
                <title>
                    <fmt:message key="name"/>
                </title>
            </field>
            <field name="address1" type="text" length="35">
                <title>
                    <fmt:message key="address1"/>
                </title>
            </field>
            <field name="address2" type="text" length="35">
                <title>
                    <fmt:message key="address2"/>
                </title>
            </field>
            <field name="address3" type="text" length="35">
                <title>
                    <fmt:message key="address3"/>
                </title>
            </field>
            <field name="city" type="text" length="35">
                <title>
                    <fmt:message key="city"/>
                </title>
            </field>
                <field name="created_by" type="creator" hidden="true" >
                <title>
                    <fmt:message key="createdBy"/>
                </title>
            </field>
            <field name="created_time" type="creatorTimestamp" hidden="true" audit="never">
                <title>
                    <fmt:message key="createdTime"/>
                </title>
            </field>
            <field name="modified_by" type="modifier" hidden="true">
                <title>
                    <fmt:message key="modifiedBy"/>
                </title>
            </field>
            <field name="modified_time" type="modifierTimestamp" hidden="true" audit="never">
                <title>
                    <fmt:message key="modifiedTime"/>
                </title>
            </field>
        </fields>
        <operationBindings>
            <operationBinding operationType="update" operationId="auditUpdate" skipAudit="true"/>
            <operationBinding operationType="add" operationId="auditAdd" skipAudit="true"/>
            <operationBinding operationType="remove" operationId="auditRemove" skipAudit="true"/>
        </operationBindings>
    </DataSource>
    As you can see above I have used skipAudit with operation Bindings. even after using this, the audit entry is created for these operations.
    My code for carrying out the above operations:

    Code:
    if (DSOperationType.UPDATE.getValue().equals(operationType)) {
                            final Record changedRecord = getResultSet().find(primaryKeyName, primaryKeyValInAudit);
                            final Object[] fieldsChangedObj = (Object[]) auditRecord.getAttributeAsObject("audit_changedFields");
                            for (final Object fieldChangedObj : fieldsChangedObj) {
                                final String fieldName = fieldChangedObj.toString();
                                changedRecord.setAttribute(fieldName, auditRecord.getAttribute(fieldName));
                            }
                            auditActionProperties.setOperationId("auditUpdate");
                            auditActionProperties.setCriteria(new Criteria(primaryKeyName, primaryKeyValInAudit.toString()));
                            updateData(changedRecord, null, auditActionProperties);
                        } else if (DSOperationType.ADD.getValue().equals(operationType)) {
                            final Record changedRecord = getResultSet().find(primaryKeyName, primaryKeyValInAudit);
                            final int rowNum = getRowNum(new ListGridRecord(changedRecord));
                            auditActionProperties.setOperationId("auditRemove");
                            auditActionProperties.setCriteria(new Criteria(primaryKeyName, primaryKeyValInAudit.toString()));
                            removeData(getRecord(rowNum), null, auditActionProperties);
    
                        } else if (DSOperationType.REMOVE.getValue().equals(operationType)) {
    
                            auditRecord.setAttribute(primaryKeyName, (String) null);
                            auditActionProperties.setOperationId("auditAdd");
                            addData(auditRecord, null, auditActionProperties);
                        }
    Even after setting the operationID correctly and the same can be seen in RPC calls in smartGWTConsole:

    Click image for larger version  Name:	Capture.JPG Views:	0 Size:	18.5 KB ID:	264036
    After this call Audit entry in the audit table is still created. Also, Please note that for the DSFields "created_time" & "modified_time" I have used the audit attribute with value as never. Still in the audit entry it shows the audit_changedFields as modified_time.

    I am having my default server.properties and I have only made datasource related to it.

    Can you please let me know what am I missing and why is the audit entry being created even after marking the operation binding with skip audit. Please let me know if you need any other inputs from my side for looking into this issue

    Thanks
    Last edited by sidharth1917; 11th Nov 2020, 05:43.

    #2
    Hi,

    Please let me know in case I need to provide more details to let you look into this issue.

    Thanks.

    Comment


      #3
      Yes, in order to address this we need more details. Ideally standalone test case or just enough details for us to reproduce this issue. Thank you.

      Comment


        #4
        Hi Team,

        I was trying this on a sample project "built-in-ds". In the project I have made changes to :
        1. BuildInDS.java- Added a performUndo method and called on keyPress event. File attached
        2. animals.ds.xml - added audite attribute and new operations with SkipAudit as true.
        This code works fine and the ds.updateData call with operationID (with skipAudit as true) does not make any further AUDIT entry.

        But when I implement this same login in my application DS and ListGrid, the skipAudit operations are creating audit entries. Also, I have used
        audit="never"
        with fields, but in the audit entries the audit_changedFields still has the field names.

        Please note that my application is a Spring based GWT web application where I am using SQL data sources.

        Can you please give me some pointer to why I must be facing such an issue where as on the other hand same code works fine in the sample project.
        Attached Files

        Comment


          #5
          Just for your reference my DS.xml code is as follows:

          Code:
          <DataSource ID="ExternalCompanySQL"
                      serverType="sql"
                      tableName="external_company"
                      audit="true"
                      xmlns:fmt="WEB-INF/">
              <fmt:bundle basename="com.aaa.ppp.client.DSMessages"/>
              <fields>
                  <field name="external_company_id" type="sequence" hidden="true" primaryKey="true"/>
                  <field name="external_company_type_id" type="integer" foreignKey="CDSQL.code_id" joinType="outer" required="true"/>
                  <field name="company_id" type="text" length="36" foreignKey="CMPSQL.company_id" required="true"/>
                  <field name="name" type="text" length="100" required="true">
                      <title>
                          <fmt:message key="name"/>
                      </title>
                  </field>
                  <field name="address1" type="text" length="35">
                      <title>
                          <fmt:message key="address1"/>
                      </title>
                  </field>
                  <field name="address2" type="text" length="35">
                      <title>
                          <fmt:message key="address2"/>
                      </title>
                  </field>
                  <field name="address3" type="text" length="35">
                      <title>
                          <fmt:message key="address3"/>
                      </title>
                  </field>
                  <field name="city" type="text" length="35">
                      <title>
                          <fmt:message key="city"/>
                      </title>
                  </field>
                  <field name="state" type="text" length="2">
                      <title>
                          <fmt:message key="state"/>
                      </title>
                  </field>
                  <field name="zip" type="text" length="10">
                      <title>
                          <fmt:message key="zip"/>
                      </title>
                  </field>
                  <field name="country" type="text" length="50">
                      <title>
                          <fmt:message key="country"/>
                      </title>
                  </field>
                  <field name="phone" type="text" length="30">
                      <title>
                          <fmt:message key="phone"/>
                      </title>
                  </field>
                  <field name="fax" type="text" length="30">
                      <title>
                          <fmt:message key="fax"/>
                      </title>
                  </field>
                  <field name="email" type="text" length="100">
                      <title>
                          <fmt:message key="email"/>
                      </title>
                  </field>
                  <field name="contact_id" type="integer" foreignKey="CTSQL.contact_id" joinType="outer" hidden="true"/>
                  <field name="account_number" type="text" length="50">
                      <title>
                          <fmt:message key="accountNumber"/>
                      </title>
                  </field>
                  <field name="notes" type="text">
                      <title>
                          <fmt:message key="notes"/>
                      </title>
                  </field>
                  <field name="created_by" type="creator" hidden="true" >
                      <title>
                          <fmt:message key="createdBy"/>
                      </title>
                  </field>
                  <field name="created_time" type="creatorTimestamp" hidden="true" audit="never">
                      <title>
                          <fmt:message key="createdTime"/>
                      </title>
                  </field>
                  <field name="modified_by" type="modifier" hidden="true">
                      <title>
                          <fmt:message key="modifiedBy"/>
                      </title>
                  </field>
                  <field name="modified_time" type="modifierTimestamp" hidden="true" audit="never">
                      <title>
                          <fmt:message key="modifiedTime"/>
                      </title>
                  </field>
              </fields>
              <operationBindings>
                  <operationBinding operationType="update" operationId="auditUpdate" skipAudit="true"/>
                  <operationBinding operationType="add" operationId="auditAdd" skipAudit="true"/>
                  <operationBinding operationType="remove" operationId="auditRemove" skipAudit="true"/>
              </operationBindings>
          </DataSource>

          Comment


            #6
            The code that implements skipAudit is just a really straightforward call to DataSource.getOperationBinding().get("skipAudit").

            There's no obvious way to break it other than perhaps that your code is not actually using the DataSource you think it is (like you have two similarly-named ones around, or you added the skipAudit attribute in your IDE but never actually saved the file and restarted the server to see changes).

            Note there is also dsRequest.setSkipAudit() as a second means of skipping auditing.

            Comment


              #7
              Hi,

              For the first reason you have pointed out, I tried loading my Datasource. The loaded DS shows skipAudit as true.
              if (window.isc == undefined || window.isc.DataSource == undefined){ alert("Can't load DataSources - SmartClient runtime not loaded");}isc.DataSource.create({allowAdvancedCriteria:true,tableCode:"b482896b42b5c447755eef3abd79e115",audit:true,serverType:"sql",operationBindings:[{operationId:"auditUpdate",operationType:"update",skipAudit:true},{operationId:"auditAdd",operationType:"add",skipAudit:true},{operationId:"auditRemove",operationType:"remove",skipAudit:true}],isServerDS:true,ID:"ExternalCompanySQL",fields:[{name:"external_company_id",columnCode:"2de9bee7162adfa3f97a7ff99d78349b",hidden:true,type:"sequence",validators:[],primaryKey:true},{validators:[],joinType:"outer",name:"external_company_type_id",columnCode:"004fc495889a5405ada83480e69e601b",type:"integer",foreignKey:"CodeSQL.code_id",required:true},{validators:[],length:36,name:"company_id",columnCode:"447d30927af0c270a15f149d67f259a0",type:"text",foreignKey:"CompanySQL.company_id",required:true},{validators:[],length:100,name:"name",columnCode:"b068931cc450442b63f5b3d276ea4297",type:"text",title:"Name",required:true},{length:35,name:"address1",columnCode:"81e70cb16ec45f5ab19bb6638e8e6c2d",type:"text",title:"Address 1",validators:[]},{length:35,name:"address2",columnCode:"f669f8e9f6599d0dfcd613bc6e2f347e",type:"text",title:"Address 2",validators:[]},{length:35,name:"address3",columnCode:"87280cdb0f1e7ccb01e441b66999bd81",type:"text",title:"Address 3",validators:[]},{length:35,name:"city",columnCode:"4ed5d2eaed1a1fadcc41ad1d58ed603e",type:"text",title:"City",validators:[]},{length:2,name:"state",columnCode:"9ed39e2ea931586b6a985a6942ef573e",type:"text",title:"State",validators:[]},{length:10,name:"zip",columnCode:"adcdbd79a8d84175c229b192aadc02f2",type:"text",title:"Zip",validators:[]},{length:50,name:"country",columnCode:"e909c2d7067ea37437cf97fe11d91bd0",type:"text",title:"Country",validators:[]},{length:30,name:"phone",columnCode:"f7a42fe7211f98ac7a60a285ac3a9e87",type:"text",title:"Phone",validators:[]},{length:30,name:"fax",columnCode:"236c3b7f761221f195b428aca2f06c4b",type:"text",title:"Fax",validators:[]},{length:100,name:"email",columnCode:"0c83f57c786a0b4a39efab23731c7ebc",type:"text",title:"Email",validators:[]},{hidden:true,validators:[],joinType:"outer",name:"contact_id",columnCode:"6d82f13d88a5d6593ce9132a4fcdbf6d",type:"integer",foreignKey:"ContactSQL.contact_id"},{length:50,name:"account_number",columnCode:"e6ce04fec0627b47148e2bd197d2135c",type:"text",title:"Account Number",validators:[]},{name:"notes",columnCode:"4358b5009c67d0e31d7fbf1663fcd3bf",type:"text",title:"Notes",validators:[]},{hidden:true,validators:[],canEdit:false,name:"created_by",columnCode:"dad46b2058752ffde5eaf02f1eb6abd5",type:"creator",title:"Created By"},{hidden:true,audit:"never",validators:[],canEdit:false,name:"created_time",columnCode:"bb5855f0349346ae0b19eb381f00ab70",type:"creatorTimestamp",title:"Created Time"},{hidden:true,validators:[],canEdit:false,name:"modified_by",columnCode:"d6c05cd89c7b36759b8c0ee6c10204b8",type:"modifier",title:"Modified By"},{hidden:true,audit:"never",validators:[],canEdit:false,name:"modified_time",columnCode:"4f819a0bfbc6f5a469f90793d412b0dc",type:"modifierTimestamp",title:"Modified Time"}]})
              Also, in the posts above I have pasted the screenshot of my isc console which clearly shows the right operation ID being called.

              The second option of dsrequest.setSkipAudit(), I think this is for isomorphic DSRequest and not smartget.client DSRequest. I am making this call from client side code.

              Comment


                #8
                Well, right now you have nothing on that operationBinding but the skipAudit flag. You could add a DMI (or Server Script) that calls setSkipAudit(true).

                That would also show you whether what's going on is that the operationBinding is completely non-functional vs it's just skipAudit. The operationBinding might be non-functional if you did something in DataSource.transformRequest, or in server side code customizing early processing like IDACall, which somehow dropped the operationId.

                Comment


                  #9
                  Hi,
                  I dont think the operationBinding is completely non-functional because it is still updating the record in main DS. Also the ISC console shows operation as
                  update<auditUpdate>
                  .
                  This DS does not have a transform request. I even tried inheriting the IDACALL servlet and in my CUSTOM IDACALL servlet doing a DSRequest.setskipAudit(true). Even with this there was a audit record being created for update.

                  Please note that audit entry is only created for UPDATE operation. For ADD/REMOVE, it is working fine and no audit entry is created, as expected.

                  Comment


                    #10
                    The point was: the operationBinding does nothing except set skipAudit. So please try our suggestion, because the only other one we have is to try to isolate a test case that shows misbehavior.

                    You’ve already proven to yourself that the feature works in general, so apparently, your code does something really strange that we can’t even guess.

                    Comment


                      #11
                      Hi,

                      I even tried the server side code for the operation binding, where I logged the skipAudit value coming at the server side
                      Code:
                      @Override
                          public DSResponse test(final DSRequest dsRequest) throws Exception {
                              log.error("Audit is skipped: {}", dsRequest.isAuditSkipped());
                              return dsRequest.execute();
                          }
                      This value is logged as TRUE. Still it is not skipping the audit entry and creating an AUDIT record for the operation. It is only happening for UPDATE operation and for ADD/REMOVE operation skipAudit works fine and as expected.
                      Also, as I have mentioned earlier for the datasource fields I am using
                      Code:
                      audit="never"
                      and still when the record is updated, the field shows up in audit_changedFields and the audit entry is created.

                      As per your last comment, I was trying to implement my use case in the HibernateSpringDMI sample project (as my project is a Spring project ), but was not able to proceed as I am getting "Operation type 'fetch' not supported by this DataSource (audit_supplyItemSpringDMI)". Can you please let me know how can I make this work so that I will try my us case in this example as well and see if the same works here or not.

                      I am also attaching the changed files from the sample.


                      Please also help me in figuring out what area should I look into in my application to figure out the problem. SkipAudit workd for ADD/REMOVE operation but for UPDATE it is not working.
                      Attached Files
                      Last edited by sidharth1917; 23rd Nov 2020, 01:24.

                      Comment


                        #12
                        As far as your attempt to modify the sample, see the docs for DataSource.audit - the default is to create a DataSource that is the same type as the DataSource being audited, but if you do that in this sample, you get a DataSource that is non-functional. The docs recommend setting auditDSConstructor to "sql" if you want a fully functional audit DataSource without coding anything.

                        As far as how an audit record is still being created with skipAudit set, what you're reporting continues to seem completely impossible, and you've already demonstrated to yourself that the skipAudit feature works in general. We don't have your code and we have no way of reproducing the problem, so you need to isolate what the problem is. Let us know if you find any indication of a flaw in the framework.

                        Comment


                          #13
                          Hi,
                          Though I have verified that skipAudit works fine in BuiltInDS sample and also a I have mentioned earlier as well, it works fine for ADD & REMOVE operations. It is only for UPDATE, that the skipAudit is ignored. Regarding the indication, I have verified that on the server we are always receiving the correct value of flag and then we simply do a dsRequest.execute() and hence I feel that this has something to do with the framework. Though I also agree that you would need a standalone example for the same and I am trying to provide you the same.

                          Comment


                            #14
                            In your post #4 above, you state that with the builtin-DS sample project, you observed, as we do, that skipAudit works as expected for all operations, including UPDATE.

                            So again, we have no valid bug report and no theory as to how you could have broken this simple mechanism in your project (that we don't have), so nothing can be done on our end.

                            Comment


                              #15
                              Hi Team,

                              I have updated my smartGWT version from
                              12.1-p20200926
                              to
                              12.1-p20201118
                              . This seems to have resolved the issue.

                              Thanks for all the help and support.

                              Comment

                              Working...
                              X