8 Replies Latest reply on Aug 17, 2012 9:02 AM by markaddleman

    Changing the nameInSource value for tables created through ldap translator.

    gamvi01

      Hi

       

      Is there a way to change the nameInSource value for the table created through ldapTranslator for each request ? Currently we set it up in getMetadata() but we want it to change based on the where clause of the sql ? Is there a way to change that nameInSource dynamically?

       

      @Override

          public void getMetadata(MetadataFactory metadataFactory, LdapContext conn)

                  throws TranslatorException {

              Table table = metadataFactory.addTable("people");

              table.setSupportsUpdate(true);

            

            table.setNameInSource("acf2admingrp=lids,host=xe42_im,o=ca,c=us?SUBTREE_SCOPE");

       

              Column objectClass = metadataFactory.addColumn("objectclass",

                      TypeFacility.getDataTypeNameFromSQLType(Types.VARCHAR), table);

              objectClass.setUpdatable(true);

        • 1. Re: Changing the nameInSource value for tables created through ldap translator.
          rareddy

          There is "alter view" that you can use to change the view transformation to go to a different table, however it is VDB scoped, not request scope. So, I do not think there is anything like that. With custom translator you are free do so. How are you intending to send the new NameInSource information or where are going this information form?

           

          Ramesh..

          • 2. Re: Changing the nameInSource value for tables created through ldap translator.
            gamvi01

            Hi Ramesh,

             

            we are planning to get that information through some system parameter. Its not decided yet.

             

            If we have to do so in our custom translator what do i need to modify I have set command.getNamedTable.setNameInsource("tosomethingwe need") .Apart from that i couldnt find the code which deals with setting namedInSource.

             

            I debugged LDAPUpdateExecution.executeUpdate() and saw my nameInSource string was getting carried over. But when it execute this i get the below error.


            ldapCtx.modifyAttributes(distinguishedName, updateMods);

             

            @Override

                public UpdateExecution createUpdateExecution(Command command,

                        ExecutionContext executionContext, RuntimeMetadata metadata,

                        LdapContext context) throws TranslatorException {

                    logger.debug("SecurityLdapTranslator createUpdateExecution -"

                            + executionContext);

             

                    context = updateLdapContextWithLoggedInUser(executionContext, context);

                    if(command instanceof Update){

                        Update updateCmd = (Update)command;

                        Table metadataObject = updateCmd.getTable().getMetadataObject();

                        metadataObject.setNameInSource("acf2admingrp=lids,host=xe17_im,o=ca,c=us?SUBTREE_SCOPE");

                    }

                    return super.createUpdateExecution(command, executionContext, metadata,

                            context);

                }

             

             

            15 Aug 2012 15:19:58,226 PDT DEBUG [com.ca.chorus.teiid.safety.utils.HarnessUtil] (Worker0_QueryProcessorQueue75) Adding message Message [systemLayer=SystemLayer [layer=Unknown], messageString=An unknown error has occurred: [TranslatorException]Update of acf2lid=\HUMMA03,acf2admingrp=lids,xe17_im,o=ca,c=us failed: acf2lid=\test03,acf2admingrp=lids,xe17_im,o=ca,c=us: [LDAP: error code 34 - invalid DN], messageId=NOCODE, isOverridable=true, messageTemplate=MessageTemplate [id=NOCODE, messageTemplate=An unknown error has occurred: %s, statusCode=0, reasonCode=, actionCode=For a message definition and recommended resolution, highlight the message ID and click the question mark icon in the upper-right corner of the error dialog. The Knowledge Center will open with a link to the message definition and resolution, formatCode=ERROR_XML], messageDetails=[[TranslatorException]Update of acf2lid=\test03,acf2admingrp=lids,xe17_im,o=ca,c=us failed: acf2lid=\test03,acf2admingrp=lids,xe17_im,o=ca,c=us: [LDAP: error code 34 - invalid DN]]]

            [TranslatorException]Update of acf2lid=\HUMMA03,acf2admingrp=lids,xe17_im,o=ca,c=us failed: acf2lid=\HUMMA03,acf2admingrp=lids,xe17_im,o=ca,c=us: [LDAP: error code 34 - invalid DN]

                at org.teiid.translator.ldap.LDAPUpdateExecution.executeUpdate(LDAPUpdateExecution.java:338)

                at org.teiid.translator.ldap.LDAPUpdateExecution.execute(LDAPUpdateExecution.java:111)

                at com.ca.chorus.teiid.safety.SafetyHarnessExecution.execute(SafetyHarnessExecution.java:80)

                at org.teiid.dqp.internal.datamgr.ConnectorWorkItem$1.execute(ConnectorWorkItem.java:253)

                at org.teiid.dqp.internal.datamgr.ConnectorWorkItem.execute(ConnectorWorkItem.java:273)

                at org.teiid.dqp.internal.process.DataTierTupleSource.getResults(DataTierTupleSource.java:354)

                at org.teiid.dqp.internal.process.DataTierTupleSource$1.call(DataTierTupleSource.java:143)

                at org.teiid.dqp.internal.process.DataTierTupleSource$1.call(DataTierTupleSource.java:140)

                at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)

                at java.util.concurrent.FutureTask.run(FutureTask.java:166)

                at org.teiid.dqp.internal.process.DQPCore$FutureWork.run(DQPCore.java:120)

                at org.teiid.dqp.internal.process.DQPWorkContext.runInContext(DQPWorkContext.java:232)

                at org.teiid.dqp.internal.process.ThreadReuseExecutor$RunnableWrapper.run(ThreadReuseExecutor.java:118)

                at org.teiid.dqp.internal.process.ThreadReuseExecutor$3.run(ThreadReuseExecutor.java:288)

                at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)

                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)

                at java.lang.Thread.run(Thread.java:722)

             

             

             

            Thanks

            • 3. Re: Changing the nameInSource value for tables created through ldap translator.
              rareddy

              Vineela,

               

              NameInSource is not a runtime property, so you can not set that. What I am saying is if you writing a custom translator, Teiid system does not care what you execute, as long as you are returning a result for given query.

               

              So by setting system property as you mentioned or with some custom payload (https://docs.jboss.org/author/display/TEIID/SET+Statement), you can send the new table name you want to execute against.   believe you can access this payload from CommandContext in the ExecutionContext in the translator.

               

              Ramesh..

              • 4. Re: Changing the nameInSource value for tables created through ldap translator.
                gamvi01

                Ramesh,

                 

                Its working by doing below in createUpdateExecution :

                 

                Update updateCmd = (Update)command;

                            Table metadataObject = updateCmd.getTable().getMetadataObject();

                           

                           metadataObject.setNameInSource(newNameInSource);

                 

                 

                and it happens to work.

                 

                1) Do you see any syncronization issues ?

                2) Is metadata shared ?

                • 5. Re: Changing the nameInSource value for tables created through ldap translator.
                  shawkins

                  The answer to both is yes.  So unless you lock out other requests you'd have a race condition as to which request sets their value last.  You're probably better off trying to override the place(s) in the translator where that name in source is used and take a different action there.  To do that cleanly you may need to suggest protected or other overridable methods in the ldap logic.

                   

                  Steve

                  • 6. Re: Changing the nameInSource value for tables created through ldap translator.
                    markaddleman

                    Thanks, Steven.  We'll definitely take a look at the LDAP translator's source and probably make the approach changes there or override. 

                     

                    On a related note:  Is there a way to make a deep copy of metadata objects?  That would be a clean way around this problem and, it seems, I've run into situations when rewritting Command objects that a deep copy operation could have been useful but I don't remember the specifics right now.  The thought occurs to me:  I believe the current implementation using clone() to make shallow copies so we could probably write a deep copy visitor.  Would such a thing be generally useful?  We'd be happy to contribute it.

                    • 7. Re: Changing the nameInSource value for tables created through ldap translator.
                      shawkins

                      > Is there a way to make a deep copy of metadata objects?

                       

                      Yes and no.  Since they are serializable, you can always write out and read in to produce a copy.  However the metadata objects are linked to their parents, so you will effectively be creating a copy of the entire schema.

                       

                      > That would be a clean way around this problem

                       

                      That depends on your view of the metadata objects.  If you want per request properties and can pass the copyied values where ever they are needed, then this could seem appealing.  However Teiid's built-in concept of metadata objects does not support this.  Their state is considered global to a vdb and that there should only be 1 instance per object, which implies the approach of overriding the translator behavior where needed rather than modifying a metadata object.

                       

                      > Would such a thing be generally useful?

                       

                      The engine objects to have proper deep clone methods, but that has not yet been added to the translator api.  As the apis continue to merge, then yes deep clone will be supported by the translator api objects.  Exposing a shallow clone  on AbstractMetadataRecord could be done as well, but I'd have to think more about whether we should encourage this approach.

                      • 8. Re: Changing the nameInSource value for tables created through ldap translator.
                        markaddleman

                        > Their state is considered global to a vdb and that there should only be 1 instance per object, which implies the approach of overriding the translator behavior where needed rather than modifying a metadata object.

                         

                        Got it.  We don't want to color outside the lines.  We'll take definitely take the approach of modifying the translator.