Class JdbcExecuteInterceptor

  • All Implemented Interfaces:
    software.amazon.disco.agent.interception.Installable

    public class JdbcExecuteInterceptor
    extends java.lang.Object
    implements software.amazon.disco.agent.interception.Installable
    This class represents the Disco interception of SQL queries performed using the JDBC. Some relevant information to know about the JDBC is that there are 3 Statement interfaces, which are implemented by various SQL databases such as MySQL. Statement classes are used to define queries then execute them. The inheritance of the Statement interfaces is: CallableStatement extends PreparedStatement extends Statement Callable and Prepared statements are typically used for queries whose query strings are defined in advanced and reused several times, whereas the base Statement class is more often used for one-off queries. Each statement interface defines three methods to execute queries, which are explained more below.
    • Field Summary

      Fields 
      Modifier and Type Field Description
      static software.amazon.disco.agent.logging.Logger log  
      static java.lang.String SQL_ORIGIN  
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      static software.amazon.disco.agent.event.ServiceRequestEvent enter​(java.lang.Object[] args, java.lang.String origin, java.sql.Statement stmt)
      This method is inlined at the beginning of all execute methods matched by buildMethodMatcher().
      static void exit​(software.amazon.disco.agent.event.ServiceRequestEvent requestEvent, java.lang.Object response, java.lang.Throwable thrown)
      This method is inlined with an execute method at the moment it would return or throw a Throwable.
      net.bytebuddy.agent.builder.AgentBuilder install​(net.bytebuddy.agent.builder.AgentBuilder agentBuilder)
      Installs the Disco SQL interception library into a Java program.
      static java.lang.String parseQueryFromStatement​(java.sql.Statement stmt, java.lang.Object[] params)
      This helper method attempts to get the query string in two ways before giving up and returning null.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
      • Methods inherited from interface software.amazon.disco.agent.interception.Installable

        handleArguments
    • Field Detail

      • log

        public static final software.amazon.disco.agent.logging.Logger log
    • Constructor Detail

      • JdbcExecuteInterceptor

        public JdbcExecuteInterceptor()
    • Method Detail

      • enter

        @OnMethodEnter
        public static software.amazon.disco.agent.event.ServiceRequestEvent enter​(@AllArguments
                                                                                  java.lang.Object[] args,
                                                                                  @Origin
                                                                                  java.lang.String origin,
                                                                                  @This
                                                                                  java.sql.Statement stmt)
        This method is inlined at the beginning of all execute methods matched by buildMethodMatcher(). It extracts some information from the intercepted execute method and calling object, then publishes a SQL query request event as a ServiceDownstreamRequestEvent. The Query "service" is modeled as: Origin = "SQL" Service = Target database name Operation = SQL query string Request = JDBC Statement object constructed by user, intercepted by ByteBuddy Must be public for use in Advice methods https://github.com/raphw/byte-buddy/issues/761
        Parameters:
        args - parameters passed to execute method, potentially including the query string
        origin - Identifier of the intercepted method, for debugging/logging
        stmt - concrete statement class being used to make the query
        Returns:
        a ServiceDownstreamRequestEvent with fields populated on a best effort basis
      • exit

        @OnMethodExit(onThrowable=java.lang.Throwable.class)
        public static void exit​(@Enter
                                software.amazon.disco.agent.event.ServiceRequestEvent requestEvent,
                                @Return
                                java.lang.Object response,
                                @Thrown
                                java.lang.Throwable thrown)
        This method is inlined with an execute method at the moment it would return or throw a Throwable. It extracts the response and throwable if any and publishes a ServiceDownstreamResponseEvent. See enter(java.lang.Object[], java.lang.String, java.sql.Statement) for Event model. Must be public for use in Advice methods https://github.com/raphw/byte-buddy/issues/761
        Parameters:
        requestEvent - the returned value of enter(java.lang.Object[], java.lang.String, java.sql.Statement) method, passed in using the Enter annotation
        response - the response of the JDBC execute method or null if an exception was thrown, passed in using the Return annotation
        thrown - the Throwable thrown by the query, or null if query was successful. Passed in using the Thrown annotation. Typically a SQLException.
      • install

        public net.bytebuddy.agent.builder.AgentBuilder install​(net.bytebuddy.agent.builder.AgentBuilder agentBuilder)
        Installs the Disco SQL interception library into a Java program. Intended to be invoked during an agent's premain.
        Specified by:
        install in interface software.amazon.disco.agent.interception.Installable
        Parameters:
        agentBuilder - - an AgentBuilder to append instructions to
        Returns:
        - the AgentBuilder object for chaining
      • parseQueryFromStatement

        public static java.lang.String parseQueryFromStatement​(java.sql.Statement stmt,
                                                               java.lang.Object[] params)
                                                        throws java.lang.NoSuchMethodException
        This helper method attempts to get the query string in two ways before giving up and returning null. The first is just retrieving it from the arguments passed to the execute method being intercepted. If it is not present there, then we must be dealing with a Prepared or Callable statement that had its query string pre-loaded rather than passed as an argument. In this case, there is no way provided by the JDBC to extract the query. However many DB Drivers implement the toString method on their PreparedStatement class to return the pre-loaded SQL query string. So the second way is to check if the toString method is overridden, and if so we use it. See: https://stackoverflow.com/questions/2382532/how-can-i-get-the-sql-of-a-preparedstatement Must be public for use in Advice methods https://github.com/raphw/byte-buddy/issues/761
        Parameters:
        stmt - the JDBC Statement object being used to make the query
        params - the parameters passed for the execution of the SQL query. If they exist, they must contain the SQL query string.
        Returns:
        the query string used in this SQL query if readable, or null otherwise
        Throws:
        java.lang.NoSuchMethodException