From cdd78443fbdf5fa51449ffb82c3107dc2746727f Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Thu, 27 May 2021 12:21:01 +0300 Subject: [PATCH 1/5] Hibernate query span naming --- .../hibernate/v3_3/QueryInstrumentation.java | 2 +- .../src/test/groovy/QueryTest.groovy | 12 +- .../src/test/groovy/SessionTest.groovy | 8 +- .../hibernate/v4_0/QueryInstrumentation.java | 2 +- .../src/test/groovy/QueryTest.groovy | 12 +- .../src/test/groovy/SessionTest.groovy | 8 +- .../javaagent/hibernate-4.3-javaagent.gradle | 3 +- .../groovy/SpringJpaTest.groovy | 198 +++++++ .../src/hibernate6Test/java/Value.java | 45 ++ .../java/spring/jpa/Customer.java | 78 +++ .../java/spring/jpa/CustomerRepository.java | 14 + .../java/spring/jpa/PersistenceConfig.java | 65 +++ .../test/groovy/AbstractHibernateTest.groovy | 39 ++ .../src/test/groovy/CriteriaTest.groovy | 75 +++ .../src/test/groovy/QueryTest.groovy | 187 +++++++ .../src/test/groovy/SessionTest.groovy | 520 ++++++++++++++++++ .../src/test/resources/hibernate-h2.cfg.xml | 29 + .../hibernate/SessionMethodUtils.java | 39 +- 18 files changed, 1312 insertions(+), 24 deletions(-) create mode 100644 instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/groovy/SpringJpaTest.groovy create mode 100644 instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/java/Value.java create mode 100644 instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/java/spring/jpa/Customer.java create mode 100644 instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/java/spring/jpa/CustomerRepository.java create mode 100644 instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/java/spring/jpa/PersistenceConfig.java create mode 100644 instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/AbstractHibernateTest.groovy create mode 100644 instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/CriteriaTest.groovy create mode 100644 instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/QueryTest.groovy create mode 100644 instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/SessionTest.groovy create mode 100644 instrumentation/hibernate/hibernate-4.3/javaagent/src/test/resources/hibernate-h2.cfg.xml diff --git a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/QueryInstrumentation.java b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/QueryInstrumentation.java index 45714ee933c9..2150f234350d 100644 --- a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/QueryInstrumentation.java +++ b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/QueryInstrumentation.java @@ -53,7 +53,7 @@ public static void startMethod( ContextStore contextStore = InstrumentationContext.get(Query.class, Context.class); - context = SessionMethodUtils.startSpanFrom(contextStore, query, query.getQueryString(), null); + context = SessionMethodUtils.startSpanFromQuery(contextStore, query, query.getQueryString()); if (context != null) { scope = context.makeCurrent(); } diff --git a/instrumentation/hibernate/hibernate-3.3/javaagent/src/test/groovy/QueryTest.groovy b/instrumentation/hibernate/hibernate-3.3/javaagent/src/test/groovy/QueryTest.groovy index ab3fde82ac5c..ac0bc2e60f60 100644 --- a/instrumentation/hibernate/hibernate-3.3/javaagent/src/test/groovy/QueryTest.groovy +++ b/instrumentation/hibernate/hibernate-3.3/javaagent/src/test/groovy/QueryTest.groovy @@ -105,25 +105,25 @@ class QueryTest extends AbstractHibernateTest { where: queryMethodName | expectedSpanName | requiresTransaction | queryInteraction - "Query.list" | "from Value" | false | { sess -> + "Query.list" | "SELECT Value" | false | { sess -> Query q = sess.createQuery("from Value") q.list() } - "Query.executeUpdate" | "update Value set name = ?" | true | { sess -> + "Query.executeUpdate" | "UPDATE Value" | true | { sess -> Query q = sess.createQuery("update Value set name = ?") q.setParameter(0, "alyx") q.executeUpdate() } - "Query.uniqueResult" | "from Value where id = ?" | false | { sess -> + "Query.uniqueResult" | "SELECT Value" | false | { sess -> Query q = sess.createQuery("from Value where id = ?") q.setParameter(0, 1L) q.uniqueResult() } - "Query.iterate" | "from Value" | false | { sess -> + "Query.iterate" | "SELECT Value" | false | { sess -> Query q = sess.createQuery("from Value") q.iterate() } - "Query.scroll" | "from Value" | false | { sess -> + "Query.scroll" | "SELECT Value" | false | { sess -> Query q = sess.createQuery("from Value") q.scroll() } @@ -153,7 +153,7 @@ class QueryTest extends AbstractHibernateTest { } } span(1) { - name "from Value" + name "SELECT Value" kind INTERNAL childOf span(0) attributes { diff --git a/instrumentation/hibernate/hibernate-3.3/javaagent/src/test/groovy/SessionTest.groovy b/instrumentation/hibernate/hibernate-3.3/javaagent/src/test/groovy/SessionTest.groovy index 8c43da3b476e..b7986bb1d4d4 100644 --- a/instrumentation/hibernate/hibernate-3.3/javaagent/src/test/groovy/SessionTest.groovy +++ b/instrumentation/hibernate/hibernate-3.3/javaagent/src/test/groovy/SessionTest.groovy @@ -440,10 +440,10 @@ class SessionTest extends AbstractHibernateTest { } where: - queryMethodName | expectedSpanName | queryBuildMethod - "createQuery" | "from Value" | { sess -> sess.createQuery("from Value") } - "getNamedQuery" | "from Value" | { sess -> sess.getNamedQuery("TestNamedQuery") } - "createSQLQuery" | "SELECT * FROM Value" | { sess -> sess.createSQLQuery("SELECT * FROM Value") } + queryMethodName | expectedSpanName | queryBuildMethod + "createQuery" | "SELECT Value" | { sess -> sess.createQuery("from Value") } + "getNamedQuery" | "SELECT Value" | { sess -> sess.getNamedQuery("TestNamedQuery") } + "createSQLQuery" | "SELECT Value" | { sess -> sess.createSQLQuery("SELECT * FROM Value") } } diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/QueryInstrumentation.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/QueryInstrumentation.java index dfa2b13d306c..be693d2c1e52 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/QueryInstrumentation.java +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/QueryInstrumentation.java @@ -53,7 +53,7 @@ public static void startMethod( ContextStore contextStore = InstrumentationContext.get(Query.class, Context.class); - context = SessionMethodUtils.startSpanFrom(contextStore, query, query.getQueryString(), null); + context = SessionMethodUtils.startSpanFromQuery(contextStore, query, query.getQueryString()); if (context != null) { scope = context.makeCurrent(); } diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/groovy/QueryTest.groovy b/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/groovy/QueryTest.groovy index 1cbb52f29661..db6905c08528 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/groovy/QueryTest.groovy +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/groovy/QueryTest.groovy @@ -105,25 +105,25 @@ class QueryTest extends AbstractHibernateTest { where: queryMethodName | expectedSpanName | requiresTransaction | queryInteraction - "query/list" | "from Value" | false | { sess -> + "query/list" | "SELECT Value" | false | { sess -> Query q = sess.createQuery("from Value") q.list() } - "query/executeUpdate" | "update Value set name = ?" | true | { sess -> + "query/executeUpdate" | "UPDATE Value" | true | { sess -> Query q = sess.createQuery("update Value set name = ?") q.setParameter(0, "alyx") q.executeUpdate() } - "query/uniqueResult" | "from Value where id = ?" | false | { sess -> + "query/uniqueResult" | "SELECT Value" | false | { sess -> Query q = sess.createQuery("from Value where id = ?") q.setParameter(0, 1L) q.uniqueResult() } - "iterate" | "from Value" | false | { sess -> + "iterate" | "SELECT Value" | false | { sess -> Query q = sess.createQuery("from Value") q.iterate() } - "query/scroll" | "from Value" | false | { sess -> + "query/scroll" | "SELECT Value" | false | { sess -> Query q = sess.createQuery("from Value") q.scroll() } @@ -153,7 +153,7 @@ class QueryTest extends AbstractHibernateTest { } } span(1) { - name "from Value" + name "SELECT Value" kind INTERNAL childOf span(0) attributes { diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/groovy/SessionTest.groovy b/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/groovy/SessionTest.groovy index b82fe56d7043..5eb5a9fa81bd 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/groovy/SessionTest.groovy +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/groovy/SessionTest.groovy @@ -379,10 +379,10 @@ class SessionTest extends AbstractHibernateTest { } where: - queryMethodName | resource | queryBuildMethod - "createQuery" | "from Value" | { sess -> sess.createQuery("from Value") } - "getNamedQuery" | "from Value" | { sess -> sess.getNamedQuery("TestNamedQuery") } - "createSQLQuery" | "SELECT * FROM Value" | { sess -> sess.createSQLQuery("SELECT * FROM Value") } + queryMethodName | resource | queryBuildMethod + "createQuery" | "SELECT Value" | { sess -> sess.createQuery("from Value") } + "getNamedQuery" | "SELECT Value" | { sess -> sess.getNamedQuery("TestNamedQuery") } + "createSQLQuery" | "SELECT Value" | { sess -> sess.createSQLQuery("SELECT * FROM Value") } } diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/hibernate-4.3-javaagent.gradle b/instrumentation/hibernate/hibernate-4.3/javaagent/hibernate-4.3-javaagent.gradle index f340c1012f76..75d1c14d95f1 100644 --- a/instrumentation/hibernate/hibernate-4.3/javaagent/hibernate-4.3-javaagent.gradle +++ b/instrumentation/hibernate/hibernate-4.3/javaagent/hibernate-4.3-javaagent.gradle @@ -15,7 +15,7 @@ testSets { dirName = 'test' } version6Test { - dirName = 'test' + dirName = 'hibernate6Test' } latestDepTest { @@ -38,6 +38,7 @@ dependencies { testImplementation "org.hibernate:hibernate-core:4.3.0.Final" testImplementation "org.hibernate:hibernate-entitymanager:4.3.0.Final" testImplementation "org.hsqldb:hsqldb:2.0.0" + testImplementation "com.h2database:h2:1.4.197" //First version to work with Java 14 testImplementation "org.springframework.data:spring-data-jpa:1.8.0.RELEASE" diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/groovy/SpringJpaTest.groovy b/instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/groovy/SpringJpaTest.groovy new file mode 100644 index 000000000000..7cc1ce6264dd --- /dev/null +++ b/instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/groovy/SpringJpaTest.groovy @@ -0,0 +1,198 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +import static io.opentelemetry.api.trace.SpanKind.CLIENT + +import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification +import io.opentelemetry.semconv.trace.attributes.SemanticAttributes +import org.springframework.context.annotation.AnnotationConfigApplicationContext +import spock.lang.Shared +import spring.jpa.Customer +import spring.jpa.CustomerRepository +import spring.jpa.PersistenceConfig + +/** + * Unfortunately this test verifies that our hibernate instrumentation doesn't currently work with Spring Data Repositories. + */ +class SpringJpaTest extends AgentInstrumentationSpecification { + + @Shared + def context = new AnnotationConfigApplicationContext(PersistenceConfig) + + @Shared + def repo = context.getBean(CustomerRepository) + + def "test CRUD"() { + setup: + def customer = new Customer("Bob", "Anonymous") + + expect: + customer.id == null + !repo.findAll().iterator().hasNext() + + assertTraces(1) { + trace(0, 1) { + span(0) { + name "SELECT test.Customer" + kind CLIENT + attributes { + "${SemanticAttributes.DB_SYSTEM.key}" "hsqldb" + "${SemanticAttributes.DB_NAME.key}" "test" + "${SemanticAttributes.DB_USER.key}" "sa" + "${SemanticAttributes.DB_CONNECTION_STRING.key}" "hsqldb:mem:" + "${SemanticAttributes.DB_STATEMENT.key}" ~/select ([^\.]+)\.id([^\,]*), ([^\.]+)\.firstName([^\,]*), ([^\.]+)\.lastName(.*)from Customer(.*)/ + "${SemanticAttributes.DB_OPERATION.key}" "SELECT" + "${SemanticAttributes.DB_SQL_TABLE.key}" "Customer" + } + } + } + } + clearExportedData() + + when: + repo.save(customer) + def savedId = customer.id + + then: + customer.id != null + // Behavior changed in new version: + def extraTrace = traces.size() == 2 + assertTraces(extraTrace ? 2 : 1) { + if (extraTrace) { + trace(0, 1) { + span(0) { + name "test" + kind CLIENT + attributes { + "${SemanticAttributes.DB_SYSTEM.key}" "hsqldb" + "${SemanticAttributes.DB_NAME.key}" "test" + "${SemanticAttributes.DB_USER.key}" "sa" + "${SemanticAttributes.DB_STATEMENT.key}" "call next value for hibernate_sequence" + "${SemanticAttributes.DB_CONNECTION_STRING.key}" "hsqldb:mem:" + } + } + } + } + trace(extraTrace ? 1 : 0, 1) { + span(0) { + name "INSERT test.Customer" + kind CLIENT + attributes { + "${SemanticAttributes.DB_SYSTEM.key}" "hsqldb" + "${SemanticAttributes.DB_NAME.key}" "test" + "${SemanticAttributes.DB_USER.key}" "sa" + "${SemanticAttributes.DB_CONNECTION_STRING.key}" "hsqldb:mem:" + "${SemanticAttributes.DB_STATEMENT.key}" ~/insert into Customer \(.*\) values \(.*, \?, \?\)/ + "${SemanticAttributes.DB_OPERATION.key}" "INSERT" + "${SemanticAttributes.DB_SQL_TABLE.key}" "Customer" + } + } + } + } + clearExportedData() + + when: + customer.firstName = "Bill" + repo.save(customer) + + then: + customer.id == savedId + assertTraces(2) { + trace(0, 1) { + span(0) { + name "SELECT test.Customer" + kind CLIENT + attributes { + "${SemanticAttributes.DB_SYSTEM.key}" "hsqldb" + "${SemanticAttributes.DB_NAME.key}" "test" + "${SemanticAttributes.DB_USER.key}" "sa" + "${SemanticAttributes.DB_CONNECTION_STRING.key}" "hsqldb:mem:" + "${SemanticAttributes.DB_STATEMENT.key}" ~/select ([^\.]+)\.id([^\,]*), ([^\.]+)\.firstName([^\,]*), ([^\.]+)\.lastName (.*)from Customer (.*)where ([^\.]+)\.id( ?)=( ?)\?/ + "${SemanticAttributes.DB_OPERATION.key}" "SELECT" + "${SemanticAttributes.DB_SQL_TABLE.key}" "Customer" + } + } + } + trace(1, 1) { + span(0) { + name "UPDATE test.Customer" + kind CLIENT + attributes { + "${SemanticAttributes.DB_SYSTEM.key}" "hsqldb" + "${SemanticAttributes.DB_NAME.key}" "test" + "${SemanticAttributes.DB_USER.key}" "sa" + "${SemanticAttributes.DB_CONNECTION_STRING.key}" "hsqldb:mem:" + "${SemanticAttributes.DB_STATEMENT.key}" "update Customer set firstName=?, lastName=? where id=?" + "${SemanticAttributes.DB_OPERATION.key}" "UPDATE" + "${SemanticAttributes.DB_SQL_TABLE.key}" "Customer" + } + } + } + } + clearExportedData() + + when: + customer = repo.findByLastName("Anonymous")[0] + + then: + customer.id == savedId + customer.firstName == "Bill" + assertTraces(1) { + trace(0, 1) { + span(0) { + name "SELECT test.Customer" + kind CLIENT + attributes { + "${SemanticAttributes.DB_SYSTEM.key}" "hsqldb" + "${SemanticAttributes.DB_NAME.key}" "test" + "${SemanticAttributes.DB_USER.key}" "sa" + "${SemanticAttributes.DB_CONNECTION_STRING.key}" "hsqldb:mem:" + "${SemanticAttributes.DB_STATEMENT.key}" ~/select ([^\.]+)\.id([^\,]*), ([^\.]+)\.firstName([^\,]*), ([^\.]+)\.lastName (.*)from Customer (.*)(where ([^\.]+)\.lastName( ?)=( ?)\?|)/ + "${SemanticAttributes.DB_OPERATION.key}" "SELECT" + "${SemanticAttributes.DB_SQL_TABLE.key}" "Customer" + } + } + } + } + clearExportedData() + + when: + repo.delete(customer) + + then: + assertTraces(2) { + trace(0, 1) { + span(0) { + name "SELECT test.Customer" + kind CLIENT + attributes { + "${SemanticAttributes.DB_SYSTEM.key}" "hsqldb" + "${SemanticAttributes.DB_NAME.key}" "test" + "${SemanticAttributes.DB_USER.key}" "sa" + "${SemanticAttributes.DB_CONNECTION_STRING.key}" "hsqldb:mem:" + "${SemanticAttributes.DB_STATEMENT.key}" ~/select ([^\.]+)\.id([^\,]*), ([^\.]+)\.firstName([^\,]*), ([^\.]+)\.lastName (.*)from Customer (.*)where ([^\.]+)\.id( ?)=( ?)\?/ + "${SemanticAttributes.DB_OPERATION.key}" "SELECT" + "${SemanticAttributes.DB_SQL_TABLE.key}" "Customer" + } + } + } + trace(1, 1) { + span(0) { + name "DELETE test.Customer" + kind CLIENT + attributes { + "${SemanticAttributes.DB_SYSTEM.key}" "hsqldb" + "${SemanticAttributes.DB_NAME.key}" "test" + "${SemanticAttributes.DB_USER.key}" "sa" + "${SemanticAttributes.DB_CONNECTION_STRING.key}" "hsqldb:mem:" + "${SemanticAttributes.DB_STATEMENT.key}" "delete from Customer where id=?" + "${SemanticAttributes.DB_OPERATION.key}" "DELETE" + "${SemanticAttributes.DB_SQL_TABLE.key}" "Customer" + } + } + } + } + } +} diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/java/Value.java b/instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/java/Value.java new file mode 100644 index 000000000000..996b544bbde0 --- /dev/null +++ b/instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/java/Value.java @@ -0,0 +1,45 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; +import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.NamedQuery; + +@Entity +@Table +@NamedQuery(name = "TestNamedQuery", query = "FROM Value") +public class Value { + + private Long id; + private String name; + + public Value() {} + + public Value(String name) { + this.name = name; + } + + @Id + @GeneratedValue(generator = "increment") + @GenericGenerator(name = "increment", strategy = "increment") + public Long getId() { + return id; + } + + private void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String title) { + name = title; + } +} diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/java/spring/jpa/Customer.java b/instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/java/spring/jpa/Customer.java new file mode 100644 index 000000000000..27e7d6894055 --- /dev/null +++ b/instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/java/spring/jpa/Customer.java @@ -0,0 +1,78 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package spring.jpa; + +import java.util.Objects; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity +public class Customer { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + private String firstName; + private String lastName; + + protected Customer() {} + + public Customer(String firstName, String lastName) { + this.firstName = firstName; + this.lastName = lastName; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + @Override + public String toString() { + return String.format("Customer[id=%d, firstName='%s', lastName='%s']", id, firstName, lastName); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof Customer)) { + return false; + } + Customer other = (Customer) obj; + return Objects.equals(id, other.id) + && Objects.equals(firstName, other.firstName) + && Objects.equals(lastName, other.lastName); + } + + @Override + public int hashCode() { + return Objects.hash(id, firstName, lastName); + } +} diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/java/spring/jpa/CustomerRepository.java b/instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/java/spring/jpa/CustomerRepository.java new file mode 100644 index 000000000000..9662f2a4b59c --- /dev/null +++ b/instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/java/spring/jpa/CustomerRepository.java @@ -0,0 +1,14 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package spring.jpa; + +import java.util.List; +import org.springframework.data.repository.CrudRepository; + +public interface CustomerRepository extends CrudRepository { + + List findByLastName(String lastName); +} diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/java/spring/jpa/PersistenceConfig.java b/instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/java/spring/jpa/PersistenceConfig.java new file mode 100644 index 000000000000..98afef6b75d7 --- /dev/null +++ b/instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/java/spring/jpa/PersistenceConfig.java @@ -0,0 +1,65 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package spring.jpa; + +import java.util.Properties; +import javax.sql.DataSource; +import org.springframework.context.annotation.Bean; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.jdbc.datasource.DriverManagerDataSource; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.orm.jpa.vendor.Database; +import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; +import org.springframework.transaction.PlatformTransactionManager; + +@EnableJpaRepositories(basePackages = "spring/jpa") +public class PersistenceConfig { + + @Bean(name = "transactionManager") + public PlatformTransactionManager dbTransactionManager() { + JpaTransactionManager transactionManager = new JpaTransactionManager(); + transactionManager.setEntityManagerFactory(entityManagerFactory().getObject()); + return transactionManager; + } + + @Bean + public LocalContainerEntityManagerFactoryBean entityManagerFactory() { + + HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); + vendorAdapter.setDatabase(Database.HSQL); + vendorAdapter.setGenerateDdl(true); + + LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); + em.setDataSource(dataSource()); + em.setPackagesToScan("spring/jpa"); + em.setJpaVendorAdapter(vendorAdapter); + em.setJpaProperties(additionalProperties()); + + return em; + } + + @Bean + public DataSource dataSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("org.hsqldb.jdbcDriver"); + dataSource.setUrl("jdbc:hsqldb:mem:test"); + dataSource.setUsername("sa"); + dataSource.setPassword("1"); + return dataSource; + } + + private Properties additionalProperties() { + Properties properties = new Properties(); + properties.setProperty("hibernate.show_sql", "true"); + properties.setProperty("hibernate.hbm2ddl.auto", "create"); + properties.setProperty("hibernate.dialect", "org.hibernate.dialect.HSQLDialect"); + // properties.setProperty( + // "hibernate.format_sql", + // env.getProperty("spring.jpa.properties.hibernate.format_sql")); + return properties; + } +} diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/AbstractHibernateTest.groovy b/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/AbstractHibernateTest.groovy new file mode 100644 index 000000000000..3fa0ad045b76 --- /dev/null +++ b/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/AbstractHibernateTest.groovy @@ -0,0 +1,39 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification +import org.hibernate.Session +import org.hibernate.SessionFactory +import org.hibernate.cfg.Configuration +import spock.lang.Shared + +abstract class AbstractHibernateTest extends AgentInstrumentationSpecification { + + @Shared + protected SessionFactory sessionFactory + + @Shared + protected List prepopulated + + def setupSpec() { + sessionFactory = new Configuration().configure("/hibernate-h2.cfg.xml").buildSessionFactory() + // Pre-populate the DB, so delete/update can be tested. + Session writer = sessionFactory.openSession() + writer.beginTransaction() + prepopulated = new ArrayList<>() + for (int i = 0; i < 2; i++) { + prepopulated.add(new Value("Hello :) " + i)) + writer.save(prepopulated.get(i)) + } + writer.getTransaction().commit() + writer.close() + } + + def cleanupSpec() { + if (sessionFactory != null) { + sessionFactory.close() + } + } +} diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/CriteriaTest.groovy b/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/CriteriaTest.groovy new file mode 100644 index 000000000000..946748153573 --- /dev/null +++ b/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/CriteriaTest.groovy @@ -0,0 +1,75 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +import static io.opentelemetry.api.trace.SpanKind.CLIENT +import static io.opentelemetry.api.trace.SpanKind.INTERNAL + +import io.opentelemetry.semconv.trace.attributes.SemanticAttributes +import org.hibernate.Criteria +import org.hibernate.Session +import org.hibernate.criterion.Order +import org.hibernate.criterion.Restrictions + +class CriteriaTest extends AbstractHibernateTest { + + def "test criteria.#methodName"() { + setup: + Session session = sessionFactory.openSession() + session.beginTransaction() + Criteria criteria = session.createCriteria(Value) + .add(Restrictions.like("name", "Hello")) + .addOrder(Order.desc("name")) + interaction.call(criteria) + session.getTransaction().commit() + session.close() + + expect: + assertTraces(1) { + trace(0, 4) { + span(0) { + name "Session" + kind INTERNAL + hasNoParent() + attributes { + } + } + span(1) { + name "Criteria.$methodName" + kind INTERNAL + childOf span(0) + attributes { + } + } + span(2) { + name "SELECT db1.Value" + kind CLIENT + childOf span(1) + attributes { + "${SemanticAttributes.DB_SYSTEM.key}" "h2" + "${SemanticAttributes.DB_NAME.key}" "db1" + "${SemanticAttributes.DB_USER.key}" "sa" + "${SemanticAttributes.DB_CONNECTION_STRING.key}" "h2:mem:" + "${SemanticAttributes.DB_STATEMENT.key}" ~/^select / + "${SemanticAttributes.DB_OPERATION.key}" "SELECT" + "${SemanticAttributes.DB_SQL_TABLE.key}" "Value" + } + } + span(3) { + name "Transaction.commit" + kind INTERNAL + childOf span(0) + attributes { + } + } + } + } + + where: + methodName | interaction + "list" | { c -> c.list() } + "uniqueResult" | { c -> c.uniqueResult() } + "scroll" | { c -> c.scroll() } + } +} diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/QueryTest.groovy b/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/QueryTest.groovy new file mode 100644 index 000000000000..0841d35bb01b --- /dev/null +++ b/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/QueryTest.groovy @@ -0,0 +1,187 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +import static io.opentelemetry.api.trace.SpanKind.CLIENT +import static io.opentelemetry.api.trace.SpanKind.INTERNAL + +import io.opentelemetry.semconv.trace.attributes.SemanticAttributes +import org.hibernate.Query +import org.hibernate.Session + +class QueryTest extends AbstractHibernateTest { + + def "test hibernate query.#queryMethodName single call"() { + setup: + + // With Transaction + Session session = sessionFactory.openSession() + session.beginTransaction() + queryInteraction(session) + session.getTransaction().commit() + session.close() + + // Without Transaction + if (!requiresTransaction) { + session = sessionFactory.openSession() + queryInteraction(session) + session.close() + } + + expect: + assertTraces(requiresTransaction ? 1 : 2) { + // With Transaction + trace(0, 4) { + span(0) { + name "Session" + kind INTERNAL + hasNoParent() + attributes { + } + } + span(1) { + name expectedSpanName + kind INTERNAL + childOf span(0) + attributes { + } + } + span(2) { + kind CLIENT + childOf span(1) + attributes { + "${SemanticAttributes.DB_SYSTEM.key}" "h2" + "${SemanticAttributes.DB_NAME.key}" "db1" + "${SemanticAttributes.DB_USER.key}" "sa" + "${SemanticAttributes.DB_CONNECTION_STRING.key}" "h2:mem:" + "${SemanticAttributes.DB_STATEMENT.key}" String + "${SemanticAttributes.DB_OPERATION.key}" String + "${SemanticAttributes.DB_SQL_TABLE.key}" "Value" + } + } + span(3) { + name "Transaction.commit" + kind INTERNAL + childOf span(0) + attributes { + } + } + } + if (!requiresTransaction) { + // Without Transaction + trace(1, 3) { + span(0) { + name "Session" + kind INTERNAL + hasNoParent() + attributes { + } + } + span(1) { + name expectedSpanName + kind INTERNAL + childOf span(0) + attributes { + } + } + span(2) { + name "SELECT db1.Value" + kind CLIENT + childOf span(1) + attributes { + "${SemanticAttributes.DB_SYSTEM.key}" "h2" + "${SemanticAttributes.DB_NAME.key}" "db1" + "${SemanticAttributes.DB_USER.key}" "sa" + "${SemanticAttributes.DB_CONNECTION_STRING.key}" "h2:mem:" + "${SemanticAttributes.DB_STATEMENT.key}" ~/^select / + "${SemanticAttributes.DB_OPERATION.key}" "SELECT" + "${SemanticAttributes.DB_SQL_TABLE.key}" "Value" + } + } + } + } + } + + where: + queryMethodName | expectedSpanName | requiresTransaction | queryInteraction + "query/list" | "SELECT Value" | false | { sess -> + Query q = sess.createQuery("from Value") + q.list() + } + "query/executeUpdate" | "UPDATE Value" | true | { sess -> + Query q = sess.createQuery("update Value set name = :name") + q.setParameter("name", "alyx") + q.executeUpdate() + } + "query/uniqueResult" | "SELECT Value" | false | { sess -> + Query q = sess.createQuery("from Value where id = :id") + q.setParameter("id", 1L) + q.uniqueResult() + } + "iterate" | "SELECT Value" | false | { sess -> + Query q = sess.createQuery("from Value") + q.iterate() + } + "query/scroll" | "SELECT Value" | false | { sess -> + Query q = sess.createQuery("from Value") + q.scroll() + } + } + + def "test hibernate query.iterate"() { + setup: + + Session session = sessionFactory.openSession() + session.beginTransaction() + Query q = session.createQuery("from Value") + Iterator it = q.iterate() + while (it.hasNext()) { + it.next() + } + session.getTransaction().commit() + session.close() + + expect: + assertTraces(1) { + trace(0, 4) { + span(0) { + name "Session" + kind INTERNAL + hasNoParent() + attributes { + } + } + span(1) { + name "SELECT Value" + kind INTERNAL + childOf span(0) + attributes { + } + } + span(2) { + name "SELECT db1.Value" + kind CLIENT + childOf span(1) + attributes { + "${SemanticAttributes.DB_SYSTEM.key}" "h2" + "${SemanticAttributes.DB_NAME.key}" "db1" + "${SemanticAttributes.DB_USER.key}" "sa" + "${SemanticAttributes.DB_CONNECTION_STRING.key}" "h2:mem:" + "${SemanticAttributes.DB_STATEMENT.key}" ~/^select / + "${SemanticAttributes.DB_OPERATION.key}" "SELECT" + "${SemanticAttributes.DB_SQL_TABLE.key}" "Value" + } + } + span(3) { + name "Transaction.commit" + kind INTERNAL + childOf span(0) + attributes { + } + } + } + } + } + +} diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/SessionTest.groovy b/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/SessionTest.groovy new file mode 100644 index 000000000000..5eb5a9fa81bd --- /dev/null +++ b/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/SessionTest.groovy @@ -0,0 +1,520 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +import static io.opentelemetry.api.trace.SpanKind.CLIENT +import static io.opentelemetry.api.trace.SpanKind.INTERNAL +import static io.opentelemetry.api.trace.StatusCode.ERROR +import static io.opentelemetry.instrumentation.test.utils.TraceUtils.runUnderTrace + +import io.opentelemetry.semconv.trace.attributes.SemanticAttributes +import org.hibernate.LockMode +import org.hibernate.MappingException +import org.hibernate.Query +import org.hibernate.ReplicationMode +import org.hibernate.Session +import spock.lang.Shared + +class SessionTest extends AbstractHibernateTest { + + @Shared + private Closure sessionBuilder = { return sessionFactory.openSession() } + @Shared + private Closure statelessSessionBuilder = { return sessionFactory.openStatelessSession() } + + + def "test hibernate action #testName"() { + setup: + + // Test for each implementation of Session. + for (def buildSession : sessionImplementations) { + def session = buildSession() + session.beginTransaction() + + try { + sessionMethodTest.call(session, prepopulated.get(0)) + } catch (Exception e) { + // We expected this, we should see the error field set on the span. + } + + session.getTransaction().commit() + session.close() + } + + expect: + assertTraces(sessionImplementations.size()) { + for (int i = 0; i < sessionImplementations.size(); i++) { + trace(i, 4) { + span(0) { + name "Session" + kind INTERNAL + hasNoParent() + attributes { + } + } + span(1) { + name "Session.$methodName $resource" + kind INTERNAL + childOf span(0) + attributes { + } + } + span(2) { + childOf span(1) + kind CLIENT + attributes { + "${SemanticAttributes.DB_SYSTEM.key}" "h2" + "${SemanticAttributes.DB_NAME.key}" "db1" + "${SemanticAttributes.DB_USER.key}" "sa" + "${SemanticAttributes.DB_CONNECTION_STRING.key}" "h2:mem:" + "${SemanticAttributes.DB_STATEMENT.key}" String + "${SemanticAttributes.DB_OPERATION.key}" String + "${SemanticAttributes.DB_SQL_TABLE.key}" "Value" + } + } + span(3) { + name "Transaction.commit" + kind INTERNAL + childOf span(0) + attributes { + } + } + } + } + } + + where: + testName | methodName | resource | sessionImplementations | sessionMethodTest + "lock" | "lock" | "Value" | [sessionBuilder] | { sesh, val -> + sesh.lock(val, LockMode.READ) + } + "refresh" | "refresh" | "Value" | [sessionBuilder, statelessSessionBuilder] | { sesh, val -> + sesh.refresh(val) + } + "get" | "get" | "Value" | [sessionBuilder, statelessSessionBuilder] | { sesh, val -> + sesh.get("Value", val.getId()) + } + "insert" | "insert" | "Value" | [statelessSessionBuilder] | { sesh, val -> + sesh.insert("Value", new Value("insert me")) + } + "update (StatelessSession)" | "update" | "Value" | [statelessSessionBuilder] | { sesh, val -> + val.setName("New name") + sesh.update(val) + } + "update by entityName (StatelessSession)" | "update" | "Value" | [statelessSessionBuilder] | { sesh, val -> + val.setName("New name") + sesh.update("Value", val) + } + "delete (Session)" | "delete" | "Value" | [statelessSessionBuilder] | { sesh, val -> + sesh.delete(val) + } + } + + def "test hibernate replicate: #testName"() { + setup: + + // Test for each implementation of Session. + def session = sessionFactory.openSession() + session.beginTransaction() + + try { + sessionMethodTest.call(session, prepopulated.get(0)) + } catch (Exception e) { + // We expected this, we should see the error field set on the span. + } + + session.getTransaction().commit() + session.close() + + expect: + assertTraces(1) { + trace(0, 5) { + span(0) { + name "Session" + kind INTERNAL + hasNoParent() + attributes { + } + } + span(1) { + name "Session.$methodName $resource" + kind INTERNAL + childOf span(0) + attributes { + } + } + span(2) { + name "SELECT db1.Value" + kind CLIENT + childOf span(1) + attributes { + "${SemanticAttributes.DB_SYSTEM.key}" "h2" + "${SemanticAttributes.DB_NAME.key}" "db1" + "${SemanticAttributes.DB_USER.key}" "sa" + "${SemanticAttributes.DB_CONNECTION_STRING.key}" "h2:mem:" + "${SemanticAttributes.DB_STATEMENT.key}" ~/^select / + "${SemanticAttributes.DB_OPERATION.key}" "SELECT" + "${SemanticAttributes.DB_SQL_TABLE.key}" "Value" + } + } + span(3) { + name "Transaction.commit" + kind INTERNAL + childOf span(0) + attributes { + } + } + span(4) { + kind CLIENT + childOf span(3) + attributes { + "${SemanticAttributes.DB_SYSTEM.key}" "h2" + "${SemanticAttributes.DB_NAME.key}" "db1" + "${SemanticAttributes.DB_USER.key}" "sa" + "${SemanticAttributes.DB_CONNECTION_STRING.key}" "h2:mem:" + "${SemanticAttributes.DB_STATEMENT.key}" String + "${SemanticAttributes.DB_OPERATION.key}" String + "${SemanticAttributes.DB_SQL_TABLE.key}" "Value" + } + } + } + + } + + where: + testName | methodName | resource | sessionMethodTest + "replicate" | "replicate" | "Value" | { sesh, val -> + Value replicated = new Value(val.getName() + " replicated") + replicated.setId(val.getId()) + sesh.replicate(replicated, ReplicationMode.OVERWRITE) + } + "replicate by entityName" | "replicate" | "Value" | { sesh, val -> + Value replicated = new Value(val.getName() + " replicated") + replicated.setId(val.getId()) + sesh.replicate("Value", replicated, ReplicationMode.OVERWRITE) + } + } + + def "test hibernate failed replicate"() { + setup: + + // Test for each implementation of Session. + def session = sessionFactory.openSession() + session.beginTransaction() + + try { + session.replicate(new Long(123) /* Not a valid entity */, ReplicationMode.OVERWRITE) + } catch (Exception e) { + // We expected this, we should see the error field set on the span. + } + + session.getTransaction().commit() + session.close() + + expect: + assertTraces(1) { + trace(0, 3) { + span(0) { + name "Session" + kind INTERNAL + hasNoParent() + attributes { + } + } + span(1) { + name "Session.replicate" + kind INTERNAL + childOf span(0) + status ERROR + errorEvent(MappingException, "Unknown entity: java.lang.Long") + } + span(2) { + name "Transaction.commit" + kind INTERNAL + childOf span(0) + attributes { + } + } + } + + } + } + + + def "test hibernate commit action #testName"() { + setup: + + def session = sessionBuilder() + session.beginTransaction() + + try { + sessionMethodTest.call(session, prepopulated.get(0)) + } catch (Exception e) { + // We expected this, we should see the error field set on the span. + } + + session.getTransaction().commit() + session.close() + + expect: + assertTraces(1) { + trace(0, 4) { + span(0) { + name "Session" + kind INTERNAL + hasNoParent() + attributes { + } + } + span(1) { + name "Session.$methodName $resource" + kind INTERNAL + childOf span(0) + attributes { + } + } + span(2) { + name "Transaction.commit" + kind INTERNAL + childOf span(0) + attributes { + } + } + span(3) { + kind CLIENT + childOf span(2) + attributes { + "${SemanticAttributes.DB_SYSTEM.key}" "h2" + "${SemanticAttributes.DB_NAME.key}" "db1" + "${SemanticAttributes.DB_USER.key}" "sa" + "${SemanticAttributes.DB_CONNECTION_STRING.key}" "h2:mem:" + "${SemanticAttributes.DB_STATEMENT.key}" String + "${SemanticAttributes.DB_OPERATION.key}" String + "${SemanticAttributes.DB_SQL_TABLE.key}" "Value" + } + } + } + } + + where: + testName | methodName | resource | sessionMethodTest + "save" | "save" | "Value" | { sesh, val -> + sesh.save(new Value("Another value")) + } + "saveOrUpdate save" | "saveOrUpdate" | "Value" | { sesh, val -> + sesh.saveOrUpdate(new Value("Value")) + } + "saveOrUpdate update" | "saveOrUpdate" | "Value" | { sesh, val -> + val.setName("New name") + sesh.saveOrUpdate(val) + } + "merge" | "merge" | "Value" | { sesh, val -> + sesh.merge(new Value("merge me in")) + } + "persist" | "persist" | "Value" | { sesh, val -> + sesh.persist(new Value("merge me in")) + } + "update (Session)" | "update" | "Value" | { sesh, val -> + val.setName("New name") + sesh.update(val) + } + "update by entityName (Session)" | "update" | "Value" | { sesh, val -> + val.setName("New name") + sesh.update("Value", val) + } + "delete (Session)" | "delete" | "Value" | { sesh, val -> + sesh.delete(val) + } + } + + + def "test attaches State to query created via #queryMethodName"() { + setup: + Session session = sessionFactory.openSession() + session.beginTransaction() + Query query = queryBuildMethod(session) + query.list() + session.getTransaction().commit() + session.close() + + expect: + assertTraces(1) { + trace(0, 4) { + span(0) { + name "Session" + kind INTERNAL + hasNoParent() + attributes { + } + } + span(1) { + name resource + kind INTERNAL + childOf span(0) + attributes { + } + } + span(2) { + kind CLIENT + childOf span(1) + attributes { + "${SemanticAttributes.DB_SYSTEM.key}" "h2" + "${SemanticAttributes.DB_NAME.key}" "db1" + "${SemanticAttributes.DB_USER.key}" "sa" + "${SemanticAttributes.DB_CONNECTION_STRING.key}" "h2:mem:" + "${SemanticAttributes.DB_STATEMENT.key}" String + "${SemanticAttributes.DB_OPERATION.key}" "SELECT" + "${SemanticAttributes.DB_SQL_TABLE.key}" "Value" + } + } + span(3) { + name "Transaction.commit" + kind INTERNAL + childOf span(0) + attributes { + } + } + } + } + + where: + queryMethodName | resource | queryBuildMethod + "createQuery" | "SELECT Value" | { sess -> sess.createQuery("from Value") } + "getNamedQuery" | "SELECT Value" | { sess -> sess.getNamedQuery("TestNamedQuery") } + "createSQLQuery" | "SELECT Value" | { sess -> sess.createSQLQuery("SELECT * FROM Value") } + } + + + def "test hibernate overlapping Sessions"() { + setup: + + runUnderTrace("overlapping Sessions") { + def session1 = sessionFactory.openSession() + session1.beginTransaction() + def session2 = sessionFactory.openStatelessSession() + def session3 = sessionFactory.openSession() + + def value1 = new Value("Value 1") + session1.save(value1) + session2.insert(new Value("Value 2")) + session3.save(new Value("Value 3")) + session1.delete(value1) + + session2.close() + session1.getTransaction().commit() + session1.close() + session3.close() + } + + expect: + assertTraces(1) { + trace(0, 12) { + span(0) { + name "overlapping Sessions" + attributes { + } + } + span(1) { + name "Session" + kind INTERNAL + childOf span(0) + attributes { + } + } + span(2) { + name "Session.save Value" + kind INTERNAL + childOf span(1) + attributes { + } + } + span(3) { + name "Session.delete Value" + kind INTERNAL + childOf span(1) + attributes { + } + } + span(4) { + name "Transaction.commit" + kind INTERNAL + childOf span(1) + attributes { + } + } + span(5) { + name "INSERT db1.Value" + kind CLIENT + childOf span(4) + attributes { + "${SemanticAttributes.DB_SYSTEM.key}" "h2" + "${SemanticAttributes.DB_NAME.key}" "db1" + "${SemanticAttributes.DB_USER.key}" "sa" + "${SemanticAttributes.DB_CONNECTION_STRING.key}" "h2:mem:" + "${SemanticAttributes.DB_STATEMENT.key}" ~/^insert / + "${SemanticAttributes.DB_OPERATION.key}" "INSERT" + "${SemanticAttributes.DB_SQL_TABLE.key}" "Value" + } + } + span(6) { + name "DELETE db1.Value" + kind CLIENT + childOf span(4) + attributes { + "${SemanticAttributes.DB_SYSTEM.key}" "h2" + "${SemanticAttributes.DB_NAME.key}" "db1" + "${SemanticAttributes.DB_USER.key}" "sa" + "${SemanticAttributes.DB_CONNECTION_STRING.key}" "h2:mem:" + "${SemanticAttributes.DB_STATEMENT.key}" ~/^delete / + "${SemanticAttributes.DB_OPERATION.key}" "DELETE" + "${SemanticAttributes.DB_SQL_TABLE.key}" "Value" + } + } + span(7) { + name "Session" + kind INTERNAL + childOf span(0) + attributes { + } + } + span(8) { + name "Session.insert Value" + kind INTERNAL + childOf span(7) + attributes { + } + } + span(9) { + name "INSERT db1.Value" + kind CLIENT + childOf span(8) + attributes { + "${SemanticAttributes.DB_SYSTEM.key}" "h2" + "${SemanticAttributes.DB_NAME.key}" "db1" + "${SemanticAttributes.DB_USER.key}" "sa" + "${SemanticAttributes.DB_CONNECTION_STRING.key}" "h2:mem:" + "${SemanticAttributes.DB_STATEMENT.key}" ~/^insert / + "${SemanticAttributes.DB_OPERATION.key}" "INSERT" + "${SemanticAttributes.DB_SQL_TABLE.key}" "Value" + } + } + span(10) { + name "Session" + kind INTERNAL + childOf span(0) + attributes { + } + } + span(11) { + name "Session.save Value" + kind INTERNAL + childOf span(10) + attributes { + } + } + } + } + } +} + diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/resources/hibernate-h2.cfg.xml b/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/resources/hibernate-h2.cfg.xml new file mode 100644 index 000000000000..fe5e5de6b155 --- /dev/null +++ b/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/resources/hibernate-h2.cfg.xml @@ -0,0 +1,29 @@ + + + + + + + + + org.h2.Driver + jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE + sa + + org.hibernate.dialect.H2Dialect + + 3 + org.hibernate.cache.internal.NoCacheProvider + true + + + create + + + + + + + diff --git a/instrumentation/hibernate/hibernate-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/SessionMethodUtils.java b/instrumentation/hibernate/hibernate-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/SessionMethodUtils.java index 74543bb0b1d4..75f995802338 100644 --- a/instrumentation/hibernate/hibernate-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/SessionMethodUtils.java +++ b/instrumentation/hibernate/hibernate-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/SessionMethodUtils.java @@ -9,11 +9,15 @@ import io.opentelemetry.api.trace.Span; import io.opentelemetry.context.Context; +import io.opentelemetry.instrumentation.api.db.SqlStatementInfo; +import io.opentelemetry.instrumentation.api.db.SqlStatementSanitizer; import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap; import io.opentelemetry.javaagent.instrumentation.api.ContextStore; import java.util.Arrays; import java.util.HashSet; +import java.util.Locale; import java.util.Set; +import java.util.function.Supplier; import org.checkerframework.checker.nullness.qual.Nullable; public class SessionMethodUtils { @@ -26,6 +30,14 @@ public static Context startSpanFrom( TARGET spanKey, String operationName, ENTITY entity) { + return startSpanFrom(contextStore, spanKey, () -> operationName, entity); + } + + private static Context startSpanFrom( + ContextStore contextStore, + TARGET spanKey, + Supplier operationNameSupplier, + ENTITY entity) { Context sessionContext = contextStore.get(spanKey); if (sessionContext == null) { @@ -37,7 +49,32 @@ public static Context startSpanFrom( return null; // This method call is being traced already. } - return tracer().startSpan(sessionContext, operationName, entity); + return tracer().startSpan(sessionContext, operationNameSupplier.get(), entity); + } + + public static Context startSpanFromQuery( + ContextStore contextStore, TARGET spanKey, String query) { + Supplier operationNameSupplier = + () -> { + // set operation to default value that is used when sql sanitizer fails to extract + // operation name + String operation = "Hibernate Query"; + String queryString = query; + // query might be hql or jpql query where select is optional, prepend select so we can use + // sql sanitizer to extract entity/table name + if (queryString.trim().toUpperCase(Locale.ROOT).startsWith("FROM ")) { + queryString = "SELECT * " + query; + } + SqlStatementInfo info = SqlStatementSanitizer.sanitize(queryString); + if (info.getOperation() != null) { + operation = info.getOperation(); + if (info.getTable() != null) { + operation += " " + info.getTable(); + } + } + return operation; + }; + return startSpanFrom(contextStore, spanKey, operationNameSupplier, null); } public static void end( From 434d2d8da5853474e0e970831e2902da7f05c39c Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Thu, 27 May 2021 19:16:07 +0300 Subject: [PATCH 2/5] remove commented out code --- .../src/hibernate6Test/java/spring/jpa/PersistenceConfig.java | 3 --- .../javaagent/src/test/java/spring/jpa/PersistenceConfig.java | 3 --- 2 files changed, 6 deletions(-) diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/java/spring/jpa/PersistenceConfig.java b/instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/java/spring/jpa/PersistenceConfig.java index 98afef6b75d7..bd6b88985bf4 100644 --- a/instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/java/spring/jpa/PersistenceConfig.java +++ b/instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/java/spring/jpa/PersistenceConfig.java @@ -57,9 +57,6 @@ private Properties additionalProperties() { properties.setProperty("hibernate.show_sql", "true"); properties.setProperty("hibernate.hbm2ddl.auto", "create"); properties.setProperty("hibernate.dialect", "org.hibernate.dialect.HSQLDialect"); - // properties.setProperty( - // "hibernate.format_sql", - // env.getProperty("spring.jpa.properties.hibernate.format_sql")); return properties; } } diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/java/spring/jpa/PersistenceConfig.java b/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/java/spring/jpa/PersistenceConfig.java index 98afef6b75d7..bd6b88985bf4 100644 --- a/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/java/spring/jpa/PersistenceConfig.java +++ b/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/java/spring/jpa/PersistenceConfig.java @@ -57,9 +57,6 @@ private Properties additionalProperties() { properties.setProperty("hibernate.show_sql", "true"); properties.setProperty("hibernate.hbm2ddl.auto", "create"); properties.setProperty("hibernate.dialect", "org.hibernate.dialect.HSQLDialect"); - // properties.setProperty( - // "hibernate.format_sql", - // env.getProperty("spring.jpa.properties.hibernate.format_sql")); return properties; } } From 5220e1536e1ecac019f84884863cdfb2efd0549e Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Thu, 27 May 2021 19:58:22 +0300 Subject: [PATCH 3/5] modify query sanitizer to accept queries that start with from clause --- instrumentation-api/src/main/jflex/SqlSanitizer.flex | 5 +++++ .../instrumentation/hibernate/SessionMethodUtils.java | 9 +-------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/instrumentation-api/src/main/jflex/SqlSanitizer.flex b/instrumentation-api/src/main/jflex/SqlSanitizer.flex index 618385c8853d..759659107935 100644 --- a/instrumentation-api/src/main/jflex/SqlSanitizer.flex +++ b/instrumentation-api/src/main/jflex/SqlSanitizer.flex @@ -295,6 +295,11 @@ WHITESPACE = [ \t\r\n]+ "FROM" { if (!insideComment && !extractionDone) { + if (operation == NoOp.INSTANCE) { + // hql/jpql queries may skip SELECT and start with FROM clause + // treat such queries as SELECT queries + setOperation(new Select()); + } extractionDone = operation.handleFrom(); } appendCurrentFragment(); diff --git a/instrumentation/hibernate/hibernate-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/SessionMethodUtils.java b/instrumentation/hibernate/hibernate-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/SessionMethodUtils.java index 75f995802338..d793a43c7c9f 100644 --- a/instrumentation/hibernate/hibernate-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/SessionMethodUtils.java +++ b/instrumentation/hibernate/hibernate-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/SessionMethodUtils.java @@ -15,7 +15,6 @@ import io.opentelemetry.javaagent.instrumentation.api.ContextStore; import java.util.Arrays; import java.util.HashSet; -import java.util.Locale; import java.util.Set; import java.util.function.Supplier; import org.checkerframework.checker.nullness.qual.Nullable; @@ -59,13 +58,7 @@ public static Context startSpanFromQuery( // set operation to default value that is used when sql sanitizer fails to extract // operation name String operation = "Hibernate Query"; - String queryString = query; - // query might be hql or jpql query where select is optional, prepend select so we can use - // sql sanitizer to extract entity/table name - if (queryString.trim().toUpperCase(Locale.ROOT).startsWith("FROM ")) { - queryString = "SELECT * " + query; - } - SqlStatementInfo info = SqlStatementSanitizer.sanitize(queryString); + SqlStatementInfo info = SqlStatementSanitizer.sanitize(query); if (info.getOperation() != null) { operation = info.getOperation(); if (info.getTable() != null) { From a2adb3e51d9c39b7f4379b26a1b5b081aafc681a Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Fri, 28 May 2021 12:05:48 +0300 Subject: [PATCH 4/5] add sql sanitizer test for queries starting with from --- .../instrumentation/api/db/SqlStatementSanitizerTest.groovy | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/instrumentation-api/src/test/groovy/io/opentelemetry/instrumentation/api/db/SqlStatementSanitizerTest.groovy b/instrumentation-api/src/test/groovy/io/opentelemetry/instrumentation/api/db/SqlStatementSanitizerTest.groovy index 5e54696cd394..991198e447d5 100644 --- a/instrumentation-api/src/test/groovy/io/opentelemetry/instrumentation/api/db/SqlStatementSanitizerTest.groovy +++ b/instrumentation-api/src/test/groovy/io/opentelemetry/instrumentation/api/db/SqlStatementSanitizerTest.groovy @@ -80,6 +80,9 @@ class SqlStatementSanitizerTest extends Specification { // whitespace normalization "SELECT * \t\r\nFROM TABLE WHERE FIELD1 = 12344 AND FIELD2 = 5678" | "SELECT * FROM TABLE WHERE FIELD1 = ? AND FIELD2 = ?" + + // hibernate/jpa query language + "FROM TABLE WHERE FIELD=1234" | "FROM TABLE WHERE FIELD=?" } @Unroll @@ -110,6 +113,9 @@ class SqlStatementSanitizerTest extends Specification { '/* update comment */ select * from table1' | SqlStatementInfo.create(sql, 'SELECT', 'table1') 'select /*((*/abc from table' | SqlStatementInfo.create(sql, 'SELECT', 'table') 'SeLeCT * FrOm TAblE' | SqlStatementInfo.create(sql, 'SELECT', 'TAblE') + // hibernate/jpa + 'FROM schema.table' | SqlStatementInfo.create(sql, 'SELECT', 'schema.table') + '/* update comment */ from table1' | SqlStatementInfo.create(sql, 'SELECT', 'table1') // Insert ' insert into table where lalala' | SqlStatementInfo.create(sql, 'INSERT', 'table') 'insert insert into table where lalala' | SqlStatementInfo.create(sql, 'INSERT', 'table') From 7681b794f964f170a46e0194e7de789e3b25159a Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Fri, 28 May 2021 13:35:05 +0300 Subject: [PATCH 5/5] rename hibernate-4.3 to hibernate-procedure-call-4.3 --- .../javaagent/hibernate-3.3-javaagent.gradle | 2 +- .../javaagent/hibernate-4.0-javaagent.gradle | 39 +- .../groovy/SpringJpaTest.groovy | 0 .../src/hibernate6Test/java/Value.java | 0 .../java/spring/jpa/Customer.java | 0 .../java/spring/jpa/CustomerRepository.java | 0 .../java/spring/jpa/PersistenceConfig.java | 0 .../src/test/groovy/QueryTest.groovy | 8 +- .../src/test/groovy/SpringJpaTest.groovy | 0 .../src/test/java/spring/jpa/Customer.java | 0 .../java/spring/jpa/CustomerRepository.java | 0 .../java/spring/jpa/PersistenceConfig.java | 0 .../javaagent/hibernate-4.3-javaagent.gradle | 61 -- .../test/groovy/AbstractHibernateTest.groovy | 39 -- .../src/test/groovy/CriteriaTest.groovy | 75 --- .../src/test/groovy/QueryTest.groovy | 187 ------- .../src/test/groovy/SessionTest.groovy | 520 ------------------ .../src/test/resources/hibernate-h2.cfg.xml | 29 - ...ernate-procedure-call-4.3-javaagent.gradle | 31 ++ .../v4_3/HibernateInstrumentationModule.java | 0 .../v4_3/ProcedureCallInstrumentation.java | 0 .../v4_3/SessionInstrumentation.java | 0 .../src/test/groovy/ProcedureCallTest.groovy | 1 - .../javaagent/src/test/java/Value.java | 0 .../src/test/resources/hibernate.cfg.xml | 0 settings.gradle | 2 +- 26 files changed, 73 insertions(+), 921 deletions(-) rename instrumentation/hibernate/{hibernate-4.3 => hibernate-4.0}/javaagent/src/hibernate6Test/groovy/SpringJpaTest.groovy (100%) rename instrumentation/hibernate/{hibernate-4.3 => hibernate-4.0}/javaagent/src/hibernate6Test/java/Value.java (100%) rename instrumentation/hibernate/{hibernate-4.3 => hibernate-4.0}/javaagent/src/hibernate6Test/java/spring/jpa/Customer.java (100%) rename instrumentation/hibernate/{hibernate-4.3 => hibernate-4.0}/javaagent/src/hibernate6Test/java/spring/jpa/CustomerRepository.java (100%) rename instrumentation/hibernate/{hibernate-4.3 => hibernate-4.0}/javaagent/src/hibernate6Test/java/spring/jpa/PersistenceConfig.java (100%) rename instrumentation/hibernate/{hibernate-4.3 => hibernate-4.0}/javaagent/src/test/groovy/SpringJpaTest.groovy (100%) rename instrumentation/hibernate/{hibernate-4.3 => hibernate-4.0}/javaagent/src/test/java/spring/jpa/Customer.java (100%) rename instrumentation/hibernate/{hibernate-4.3 => hibernate-4.0}/javaagent/src/test/java/spring/jpa/CustomerRepository.java (100%) rename instrumentation/hibernate/{hibernate-4.3 => hibernate-4.0}/javaagent/src/test/java/spring/jpa/PersistenceConfig.java (100%) delete mode 100644 instrumentation/hibernate/hibernate-4.3/javaagent/hibernate-4.3-javaagent.gradle delete mode 100644 instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/AbstractHibernateTest.groovy delete mode 100644 instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/CriteriaTest.groovy delete mode 100644 instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/QueryTest.groovy delete mode 100644 instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/SessionTest.groovy delete mode 100644 instrumentation/hibernate/hibernate-4.3/javaagent/src/test/resources/hibernate-h2.cfg.xml create mode 100644 instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/hibernate-procedure-call-4.3-javaagent.gradle rename instrumentation/hibernate/{hibernate-4.3 => hibernate-procedure-call-4.3}/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/HibernateInstrumentationModule.java (100%) rename instrumentation/hibernate/{hibernate-4.3 => hibernate-procedure-call-4.3}/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/ProcedureCallInstrumentation.java (100%) rename instrumentation/hibernate/{hibernate-4.3 => hibernate-procedure-call-4.3}/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/SessionInstrumentation.java (100%) rename instrumentation/hibernate/{hibernate-4.3 => hibernate-procedure-call-4.3}/javaagent/src/test/groovy/ProcedureCallTest.groovy (99%) rename instrumentation/hibernate/{hibernate-4.3 => hibernate-procedure-call-4.3}/javaagent/src/test/java/Value.java (100%) rename instrumentation/hibernate/{hibernate-4.3 => hibernate-procedure-call-4.3}/javaagent/src/test/resources/hibernate.cfg.xml (100%) diff --git a/instrumentation/hibernate/hibernate-3.3/javaagent/hibernate-3.3-javaagent.gradle b/instrumentation/hibernate/hibernate-3.3/javaagent/hibernate-3.3-javaagent.gradle index a33674637294..6fbb66f387a8 100644 --- a/instrumentation/hibernate/hibernate-3.3/javaagent/hibernate-3.3-javaagent.gradle +++ b/instrumentation/hibernate/hibernate-3.3/javaagent/hibernate-3.3-javaagent.gradle @@ -24,7 +24,7 @@ dependencies { testInstrumentation project(':instrumentation:jdbc:javaagent') // Added to ensure cross compatibility: testInstrumentation project(':instrumentation:hibernate:hibernate-4.0:javaagent') - testInstrumentation project(':instrumentation:hibernate:hibernate-4.3:javaagent') + testInstrumentation project(':instrumentation:hibernate:hibernate-procedure-call-4.3:javaagent') testLibrary "org.hibernate:hibernate-core:3.3.0.SP1" testImplementation "org.hibernate:hibernate-annotations:3.4.0.GA" diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/hibernate-4.0-javaagent.gradle b/instrumentation/hibernate/hibernate-4.0/javaagent/hibernate-4.0-javaagent.gradle index ec91ff6fdaf3..9ccb43df660d 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/hibernate-4.0-javaagent.gradle +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/hibernate-4.0-javaagent.gradle @@ -1,4 +1,5 @@ apply from: "$rootDir/gradle/instrumentation.gradle" +apply plugin: 'org.unbroken-dome.test-sets' muzzle { pass { @@ -9,21 +10,53 @@ muzzle { } } +testSets { + version5Test { + dirName = 'test' + } + version6Test { + dirName = 'hibernate6Test' + } + + latestDepTest { + dirName = 'test' + } +} + +test.dependsOn version5Test, version6Test + dependencies { - library "org.hibernate:hibernate-core:4.0.0.Final" + compileOnly "org.hibernate:hibernate-core:4.0.0.Final" implementation project(':instrumentation:hibernate:hibernate-common:javaagent') testInstrumentation project(':instrumentation:jdbc:javaagent') // Added to ensure cross compatibility: testInstrumentation project(':instrumentation:hibernate:hibernate-3.3:javaagent') - testInstrumentation project(':instrumentation:hibernate:hibernate-4.3:javaagent') + testInstrumentation project(':instrumentation:hibernate:hibernate-procedure-call-4.3:javaagent') testImplementation "com.h2database:h2:1.4.197" testImplementation "javax.xml.bind:jaxb-api:2.2.11" testImplementation "com.sun.xml.bind:jaxb-core:2.2.11" testImplementation "com.sun.xml.bind:jaxb-impl:2.2.11" testImplementation "javax.activation:activation:1.1.1" + testImplementation "org.hsqldb:hsqldb:2.0.0" + //First version to work with Java 14 + testImplementation "org.springframework.data:spring-data-jpa:1.8.0.RELEASE" + + testImplementation "org.hibernate:hibernate-core:4.0.0.Final" + testImplementation "org.hibernate:hibernate-entitymanager:4.0.0.Final" + + version5TestImplementation "org.hibernate:hibernate-core:5.0.0.Final" + version5TestImplementation "org.hibernate:hibernate-entitymanager:5.0.0.Final" + version5TestImplementation "org.springframework.data:spring-data-jpa:2.3.0.RELEASE" + + version6TestImplementation "org.hibernate:hibernate-core:6.0.0.Alpha6" + version6TestImplementation "org.hibernate:hibernate-entitymanager:6.0.0.Alpha6" + version6TestImplementation "org.springframework.data:spring-data-jpa:2.3.0.RELEASE" - latestDepTestLibrary "org.hibernate:hibernate-core:4.2.+" + // hibernate 6 is alpha so use 5 as latest version + latestDepTestImplementation "org.hibernate:hibernate-core:5.+" + latestDepTestImplementation "org.hibernate:hibernate-entitymanager:5.+" + latestDepTestImplementation "org.springframework.data:spring-data-jpa:(2.4.0,)" } diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/groovy/SpringJpaTest.groovy b/instrumentation/hibernate/hibernate-4.0/javaagent/src/hibernate6Test/groovy/SpringJpaTest.groovy similarity index 100% rename from instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/groovy/SpringJpaTest.groovy rename to instrumentation/hibernate/hibernate-4.0/javaagent/src/hibernate6Test/groovy/SpringJpaTest.groovy diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/java/Value.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/hibernate6Test/java/Value.java similarity index 100% rename from instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/java/Value.java rename to instrumentation/hibernate/hibernate-4.0/javaagent/src/hibernate6Test/java/Value.java diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/java/spring/jpa/Customer.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/hibernate6Test/java/spring/jpa/Customer.java similarity index 100% rename from instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/java/spring/jpa/Customer.java rename to instrumentation/hibernate/hibernate-4.0/javaagent/src/hibernate6Test/java/spring/jpa/Customer.java diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/java/spring/jpa/CustomerRepository.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/hibernate6Test/java/spring/jpa/CustomerRepository.java similarity index 100% rename from instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/java/spring/jpa/CustomerRepository.java rename to instrumentation/hibernate/hibernate-4.0/javaagent/src/hibernate6Test/java/spring/jpa/CustomerRepository.java diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/java/spring/jpa/PersistenceConfig.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/hibernate6Test/java/spring/jpa/PersistenceConfig.java similarity index 100% rename from instrumentation/hibernate/hibernate-4.3/javaagent/src/hibernate6Test/java/spring/jpa/PersistenceConfig.java rename to instrumentation/hibernate/hibernate-4.0/javaagent/src/hibernate6Test/java/spring/jpa/PersistenceConfig.java diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/groovy/QueryTest.groovy b/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/groovy/QueryTest.groovy index db6905c08528..0841d35bb01b 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/groovy/QueryTest.groovy +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/groovy/QueryTest.groovy @@ -110,13 +110,13 @@ class QueryTest extends AbstractHibernateTest { q.list() } "query/executeUpdate" | "UPDATE Value" | true | { sess -> - Query q = sess.createQuery("update Value set name = ?") - q.setParameter(0, "alyx") + Query q = sess.createQuery("update Value set name = :name") + q.setParameter("name", "alyx") q.executeUpdate() } "query/uniqueResult" | "SELECT Value" | false | { sess -> - Query q = sess.createQuery("from Value where id = ?") - q.setParameter(0, 1L) + Query q = sess.createQuery("from Value where id = :id") + q.setParameter("id", 1L) q.uniqueResult() } "iterate" | "SELECT Value" | false | { sess -> diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/SpringJpaTest.groovy b/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/groovy/SpringJpaTest.groovy similarity index 100% rename from instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/SpringJpaTest.groovy rename to instrumentation/hibernate/hibernate-4.0/javaagent/src/test/groovy/SpringJpaTest.groovy diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/java/spring/jpa/Customer.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/java/spring/jpa/Customer.java similarity index 100% rename from instrumentation/hibernate/hibernate-4.3/javaagent/src/test/java/spring/jpa/Customer.java rename to instrumentation/hibernate/hibernate-4.0/javaagent/src/test/java/spring/jpa/Customer.java diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/java/spring/jpa/CustomerRepository.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/java/spring/jpa/CustomerRepository.java similarity index 100% rename from instrumentation/hibernate/hibernate-4.3/javaagent/src/test/java/spring/jpa/CustomerRepository.java rename to instrumentation/hibernate/hibernate-4.0/javaagent/src/test/java/spring/jpa/CustomerRepository.java diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/java/spring/jpa/PersistenceConfig.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/java/spring/jpa/PersistenceConfig.java similarity index 100% rename from instrumentation/hibernate/hibernate-4.3/javaagent/src/test/java/spring/jpa/PersistenceConfig.java rename to instrumentation/hibernate/hibernate-4.0/javaagent/src/test/java/spring/jpa/PersistenceConfig.java diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/hibernate-4.3-javaagent.gradle b/instrumentation/hibernate/hibernate-4.3/javaagent/hibernate-4.3-javaagent.gradle deleted file mode 100644 index 75d1c14d95f1..000000000000 --- a/instrumentation/hibernate/hibernate-4.3/javaagent/hibernate-4.3-javaagent.gradle +++ /dev/null @@ -1,61 +0,0 @@ -apply from: "$rootDir/gradle/instrumentation.gradle" -apply plugin: 'org.unbroken-dome.test-sets' - -muzzle { - pass { - group = "org.hibernate" - module = "hibernate-core" - versions = "[4.3.0.Final,)" - assertInverse = true - } -} - -testSets { - version5Test { - dirName = 'test' - } - version6Test { - dirName = 'hibernate6Test' - } - - latestDepTest { - dirName = 'test' - } -} - -test.dependsOn version5Test, version6Test - -dependencies { - compileOnly "org.hibernate:hibernate-core:4.3.0.Final" - - implementation project(':instrumentation:hibernate:hibernate-common:javaagent') - - testInstrumentation project(':instrumentation:jdbc:javaagent') - // Added to ensure cross compatibility: - testInstrumentation project(':instrumentation:hibernate:hibernate-3.3:javaagent') - testInstrumentation project(':instrumentation:hibernate:hibernate-4.0:javaagent') - - testImplementation "org.hibernate:hibernate-core:4.3.0.Final" - testImplementation "org.hibernate:hibernate-entitymanager:4.3.0.Final" - testImplementation "org.hsqldb:hsqldb:2.0.0" - testImplementation "com.h2database:h2:1.4.197" - //First version to work with Java 14 - testImplementation "org.springframework.data:spring-data-jpa:1.8.0.RELEASE" - - version5TestImplementation "org.hibernate:hibernate-core:5.0.0.Final" - version5TestImplementation "org.hibernate:hibernate-entitymanager:5.0.0.Final" - version5TestImplementation "org.springframework.data:spring-data-jpa:2.3.0.RELEASE" - - version6TestImplementation "org.hibernate:hibernate-core:6.0.0.Alpha6" - version6TestImplementation "org.hibernate:hibernate-entitymanager:6.0.0.Alpha6" - version6TestImplementation "org.springframework.data:spring-data-jpa:2.3.0.RELEASE" - - testImplementation "javax.activation:javax.activation-api:1.2.0" - testImplementation "javax.xml.bind:jaxb-api:2.3.1" - testImplementation "org.glassfish.jaxb:jaxb-runtime:2.3.3" - - // hibernate 6 is alpha so use 5 as latest version - latestDepTestImplementation "org.hibernate:hibernate-core:5.+" - latestDepTestImplementation "org.hibernate:hibernate-entitymanager:5.+" - latestDepTestImplementation "org.springframework.data:spring-data-jpa:(2.4.0,)" -} diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/AbstractHibernateTest.groovy b/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/AbstractHibernateTest.groovy deleted file mode 100644 index 3fa0ad045b76..000000000000 --- a/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/AbstractHibernateTest.groovy +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification -import org.hibernate.Session -import org.hibernate.SessionFactory -import org.hibernate.cfg.Configuration -import spock.lang.Shared - -abstract class AbstractHibernateTest extends AgentInstrumentationSpecification { - - @Shared - protected SessionFactory sessionFactory - - @Shared - protected List prepopulated - - def setupSpec() { - sessionFactory = new Configuration().configure("/hibernate-h2.cfg.xml").buildSessionFactory() - // Pre-populate the DB, so delete/update can be tested. - Session writer = sessionFactory.openSession() - writer.beginTransaction() - prepopulated = new ArrayList<>() - for (int i = 0; i < 2; i++) { - prepopulated.add(new Value("Hello :) " + i)) - writer.save(prepopulated.get(i)) - } - writer.getTransaction().commit() - writer.close() - } - - def cleanupSpec() { - if (sessionFactory != null) { - sessionFactory.close() - } - } -} diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/CriteriaTest.groovy b/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/CriteriaTest.groovy deleted file mode 100644 index 946748153573..000000000000 --- a/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/CriteriaTest.groovy +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import static io.opentelemetry.api.trace.SpanKind.CLIENT -import static io.opentelemetry.api.trace.SpanKind.INTERNAL - -import io.opentelemetry.semconv.trace.attributes.SemanticAttributes -import org.hibernate.Criteria -import org.hibernate.Session -import org.hibernate.criterion.Order -import org.hibernate.criterion.Restrictions - -class CriteriaTest extends AbstractHibernateTest { - - def "test criteria.#methodName"() { - setup: - Session session = sessionFactory.openSession() - session.beginTransaction() - Criteria criteria = session.createCriteria(Value) - .add(Restrictions.like("name", "Hello")) - .addOrder(Order.desc("name")) - interaction.call(criteria) - session.getTransaction().commit() - session.close() - - expect: - assertTraces(1) { - trace(0, 4) { - span(0) { - name "Session" - kind INTERNAL - hasNoParent() - attributes { - } - } - span(1) { - name "Criteria.$methodName" - kind INTERNAL - childOf span(0) - attributes { - } - } - span(2) { - name "SELECT db1.Value" - kind CLIENT - childOf span(1) - attributes { - "${SemanticAttributes.DB_SYSTEM.key}" "h2" - "${SemanticAttributes.DB_NAME.key}" "db1" - "${SemanticAttributes.DB_USER.key}" "sa" - "${SemanticAttributes.DB_CONNECTION_STRING.key}" "h2:mem:" - "${SemanticAttributes.DB_STATEMENT.key}" ~/^select / - "${SemanticAttributes.DB_OPERATION.key}" "SELECT" - "${SemanticAttributes.DB_SQL_TABLE.key}" "Value" - } - } - span(3) { - name "Transaction.commit" - kind INTERNAL - childOf span(0) - attributes { - } - } - } - } - - where: - methodName | interaction - "list" | { c -> c.list() } - "uniqueResult" | { c -> c.uniqueResult() } - "scroll" | { c -> c.scroll() } - } -} diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/QueryTest.groovy b/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/QueryTest.groovy deleted file mode 100644 index 0841d35bb01b..000000000000 --- a/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/QueryTest.groovy +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import static io.opentelemetry.api.trace.SpanKind.CLIENT -import static io.opentelemetry.api.trace.SpanKind.INTERNAL - -import io.opentelemetry.semconv.trace.attributes.SemanticAttributes -import org.hibernate.Query -import org.hibernate.Session - -class QueryTest extends AbstractHibernateTest { - - def "test hibernate query.#queryMethodName single call"() { - setup: - - // With Transaction - Session session = sessionFactory.openSession() - session.beginTransaction() - queryInteraction(session) - session.getTransaction().commit() - session.close() - - // Without Transaction - if (!requiresTransaction) { - session = sessionFactory.openSession() - queryInteraction(session) - session.close() - } - - expect: - assertTraces(requiresTransaction ? 1 : 2) { - // With Transaction - trace(0, 4) { - span(0) { - name "Session" - kind INTERNAL - hasNoParent() - attributes { - } - } - span(1) { - name expectedSpanName - kind INTERNAL - childOf span(0) - attributes { - } - } - span(2) { - kind CLIENT - childOf span(1) - attributes { - "${SemanticAttributes.DB_SYSTEM.key}" "h2" - "${SemanticAttributes.DB_NAME.key}" "db1" - "${SemanticAttributes.DB_USER.key}" "sa" - "${SemanticAttributes.DB_CONNECTION_STRING.key}" "h2:mem:" - "${SemanticAttributes.DB_STATEMENT.key}" String - "${SemanticAttributes.DB_OPERATION.key}" String - "${SemanticAttributes.DB_SQL_TABLE.key}" "Value" - } - } - span(3) { - name "Transaction.commit" - kind INTERNAL - childOf span(0) - attributes { - } - } - } - if (!requiresTransaction) { - // Without Transaction - trace(1, 3) { - span(0) { - name "Session" - kind INTERNAL - hasNoParent() - attributes { - } - } - span(1) { - name expectedSpanName - kind INTERNAL - childOf span(0) - attributes { - } - } - span(2) { - name "SELECT db1.Value" - kind CLIENT - childOf span(1) - attributes { - "${SemanticAttributes.DB_SYSTEM.key}" "h2" - "${SemanticAttributes.DB_NAME.key}" "db1" - "${SemanticAttributes.DB_USER.key}" "sa" - "${SemanticAttributes.DB_CONNECTION_STRING.key}" "h2:mem:" - "${SemanticAttributes.DB_STATEMENT.key}" ~/^select / - "${SemanticAttributes.DB_OPERATION.key}" "SELECT" - "${SemanticAttributes.DB_SQL_TABLE.key}" "Value" - } - } - } - } - } - - where: - queryMethodName | expectedSpanName | requiresTransaction | queryInteraction - "query/list" | "SELECT Value" | false | { sess -> - Query q = sess.createQuery("from Value") - q.list() - } - "query/executeUpdate" | "UPDATE Value" | true | { sess -> - Query q = sess.createQuery("update Value set name = :name") - q.setParameter("name", "alyx") - q.executeUpdate() - } - "query/uniqueResult" | "SELECT Value" | false | { sess -> - Query q = sess.createQuery("from Value where id = :id") - q.setParameter("id", 1L) - q.uniqueResult() - } - "iterate" | "SELECT Value" | false | { sess -> - Query q = sess.createQuery("from Value") - q.iterate() - } - "query/scroll" | "SELECT Value" | false | { sess -> - Query q = sess.createQuery("from Value") - q.scroll() - } - } - - def "test hibernate query.iterate"() { - setup: - - Session session = sessionFactory.openSession() - session.beginTransaction() - Query q = session.createQuery("from Value") - Iterator it = q.iterate() - while (it.hasNext()) { - it.next() - } - session.getTransaction().commit() - session.close() - - expect: - assertTraces(1) { - trace(0, 4) { - span(0) { - name "Session" - kind INTERNAL - hasNoParent() - attributes { - } - } - span(1) { - name "SELECT Value" - kind INTERNAL - childOf span(0) - attributes { - } - } - span(2) { - name "SELECT db1.Value" - kind CLIENT - childOf span(1) - attributes { - "${SemanticAttributes.DB_SYSTEM.key}" "h2" - "${SemanticAttributes.DB_NAME.key}" "db1" - "${SemanticAttributes.DB_USER.key}" "sa" - "${SemanticAttributes.DB_CONNECTION_STRING.key}" "h2:mem:" - "${SemanticAttributes.DB_STATEMENT.key}" ~/^select / - "${SemanticAttributes.DB_OPERATION.key}" "SELECT" - "${SemanticAttributes.DB_SQL_TABLE.key}" "Value" - } - } - span(3) { - name "Transaction.commit" - kind INTERNAL - childOf span(0) - attributes { - } - } - } - } - } - -} diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/SessionTest.groovy b/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/SessionTest.groovy deleted file mode 100644 index 5eb5a9fa81bd..000000000000 --- a/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/SessionTest.groovy +++ /dev/null @@ -1,520 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import static io.opentelemetry.api.trace.SpanKind.CLIENT -import static io.opentelemetry.api.trace.SpanKind.INTERNAL -import static io.opentelemetry.api.trace.StatusCode.ERROR -import static io.opentelemetry.instrumentation.test.utils.TraceUtils.runUnderTrace - -import io.opentelemetry.semconv.trace.attributes.SemanticAttributes -import org.hibernate.LockMode -import org.hibernate.MappingException -import org.hibernate.Query -import org.hibernate.ReplicationMode -import org.hibernate.Session -import spock.lang.Shared - -class SessionTest extends AbstractHibernateTest { - - @Shared - private Closure sessionBuilder = { return sessionFactory.openSession() } - @Shared - private Closure statelessSessionBuilder = { return sessionFactory.openStatelessSession() } - - - def "test hibernate action #testName"() { - setup: - - // Test for each implementation of Session. - for (def buildSession : sessionImplementations) { - def session = buildSession() - session.beginTransaction() - - try { - sessionMethodTest.call(session, prepopulated.get(0)) - } catch (Exception e) { - // We expected this, we should see the error field set on the span. - } - - session.getTransaction().commit() - session.close() - } - - expect: - assertTraces(sessionImplementations.size()) { - for (int i = 0; i < sessionImplementations.size(); i++) { - trace(i, 4) { - span(0) { - name "Session" - kind INTERNAL - hasNoParent() - attributes { - } - } - span(1) { - name "Session.$methodName $resource" - kind INTERNAL - childOf span(0) - attributes { - } - } - span(2) { - childOf span(1) - kind CLIENT - attributes { - "${SemanticAttributes.DB_SYSTEM.key}" "h2" - "${SemanticAttributes.DB_NAME.key}" "db1" - "${SemanticAttributes.DB_USER.key}" "sa" - "${SemanticAttributes.DB_CONNECTION_STRING.key}" "h2:mem:" - "${SemanticAttributes.DB_STATEMENT.key}" String - "${SemanticAttributes.DB_OPERATION.key}" String - "${SemanticAttributes.DB_SQL_TABLE.key}" "Value" - } - } - span(3) { - name "Transaction.commit" - kind INTERNAL - childOf span(0) - attributes { - } - } - } - } - } - - where: - testName | methodName | resource | sessionImplementations | sessionMethodTest - "lock" | "lock" | "Value" | [sessionBuilder] | { sesh, val -> - sesh.lock(val, LockMode.READ) - } - "refresh" | "refresh" | "Value" | [sessionBuilder, statelessSessionBuilder] | { sesh, val -> - sesh.refresh(val) - } - "get" | "get" | "Value" | [sessionBuilder, statelessSessionBuilder] | { sesh, val -> - sesh.get("Value", val.getId()) - } - "insert" | "insert" | "Value" | [statelessSessionBuilder] | { sesh, val -> - sesh.insert("Value", new Value("insert me")) - } - "update (StatelessSession)" | "update" | "Value" | [statelessSessionBuilder] | { sesh, val -> - val.setName("New name") - sesh.update(val) - } - "update by entityName (StatelessSession)" | "update" | "Value" | [statelessSessionBuilder] | { sesh, val -> - val.setName("New name") - sesh.update("Value", val) - } - "delete (Session)" | "delete" | "Value" | [statelessSessionBuilder] | { sesh, val -> - sesh.delete(val) - } - } - - def "test hibernate replicate: #testName"() { - setup: - - // Test for each implementation of Session. - def session = sessionFactory.openSession() - session.beginTransaction() - - try { - sessionMethodTest.call(session, prepopulated.get(0)) - } catch (Exception e) { - // We expected this, we should see the error field set on the span. - } - - session.getTransaction().commit() - session.close() - - expect: - assertTraces(1) { - trace(0, 5) { - span(0) { - name "Session" - kind INTERNAL - hasNoParent() - attributes { - } - } - span(1) { - name "Session.$methodName $resource" - kind INTERNAL - childOf span(0) - attributes { - } - } - span(2) { - name "SELECT db1.Value" - kind CLIENT - childOf span(1) - attributes { - "${SemanticAttributes.DB_SYSTEM.key}" "h2" - "${SemanticAttributes.DB_NAME.key}" "db1" - "${SemanticAttributes.DB_USER.key}" "sa" - "${SemanticAttributes.DB_CONNECTION_STRING.key}" "h2:mem:" - "${SemanticAttributes.DB_STATEMENT.key}" ~/^select / - "${SemanticAttributes.DB_OPERATION.key}" "SELECT" - "${SemanticAttributes.DB_SQL_TABLE.key}" "Value" - } - } - span(3) { - name "Transaction.commit" - kind INTERNAL - childOf span(0) - attributes { - } - } - span(4) { - kind CLIENT - childOf span(3) - attributes { - "${SemanticAttributes.DB_SYSTEM.key}" "h2" - "${SemanticAttributes.DB_NAME.key}" "db1" - "${SemanticAttributes.DB_USER.key}" "sa" - "${SemanticAttributes.DB_CONNECTION_STRING.key}" "h2:mem:" - "${SemanticAttributes.DB_STATEMENT.key}" String - "${SemanticAttributes.DB_OPERATION.key}" String - "${SemanticAttributes.DB_SQL_TABLE.key}" "Value" - } - } - } - - } - - where: - testName | methodName | resource | sessionMethodTest - "replicate" | "replicate" | "Value" | { sesh, val -> - Value replicated = new Value(val.getName() + " replicated") - replicated.setId(val.getId()) - sesh.replicate(replicated, ReplicationMode.OVERWRITE) - } - "replicate by entityName" | "replicate" | "Value" | { sesh, val -> - Value replicated = new Value(val.getName() + " replicated") - replicated.setId(val.getId()) - sesh.replicate("Value", replicated, ReplicationMode.OVERWRITE) - } - } - - def "test hibernate failed replicate"() { - setup: - - // Test for each implementation of Session. - def session = sessionFactory.openSession() - session.beginTransaction() - - try { - session.replicate(new Long(123) /* Not a valid entity */, ReplicationMode.OVERWRITE) - } catch (Exception e) { - // We expected this, we should see the error field set on the span. - } - - session.getTransaction().commit() - session.close() - - expect: - assertTraces(1) { - trace(0, 3) { - span(0) { - name "Session" - kind INTERNAL - hasNoParent() - attributes { - } - } - span(1) { - name "Session.replicate" - kind INTERNAL - childOf span(0) - status ERROR - errorEvent(MappingException, "Unknown entity: java.lang.Long") - } - span(2) { - name "Transaction.commit" - kind INTERNAL - childOf span(0) - attributes { - } - } - } - - } - } - - - def "test hibernate commit action #testName"() { - setup: - - def session = sessionBuilder() - session.beginTransaction() - - try { - sessionMethodTest.call(session, prepopulated.get(0)) - } catch (Exception e) { - // We expected this, we should see the error field set on the span. - } - - session.getTransaction().commit() - session.close() - - expect: - assertTraces(1) { - trace(0, 4) { - span(0) { - name "Session" - kind INTERNAL - hasNoParent() - attributes { - } - } - span(1) { - name "Session.$methodName $resource" - kind INTERNAL - childOf span(0) - attributes { - } - } - span(2) { - name "Transaction.commit" - kind INTERNAL - childOf span(0) - attributes { - } - } - span(3) { - kind CLIENT - childOf span(2) - attributes { - "${SemanticAttributes.DB_SYSTEM.key}" "h2" - "${SemanticAttributes.DB_NAME.key}" "db1" - "${SemanticAttributes.DB_USER.key}" "sa" - "${SemanticAttributes.DB_CONNECTION_STRING.key}" "h2:mem:" - "${SemanticAttributes.DB_STATEMENT.key}" String - "${SemanticAttributes.DB_OPERATION.key}" String - "${SemanticAttributes.DB_SQL_TABLE.key}" "Value" - } - } - } - } - - where: - testName | methodName | resource | sessionMethodTest - "save" | "save" | "Value" | { sesh, val -> - sesh.save(new Value("Another value")) - } - "saveOrUpdate save" | "saveOrUpdate" | "Value" | { sesh, val -> - sesh.saveOrUpdate(new Value("Value")) - } - "saveOrUpdate update" | "saveOrUpdate" | "Value" | { sesh, val -> - val.setName("New name") - sesh.saveOrUpdate(val) - } - "merge" | "merge" | "Value" | { sesh, val -> - sesh.merge(new Value("merge me in")) - } - "persist" | "persist" | "Value" | { sesh, val -> - sesh.persist(new Value("merge me in")) - } - "update (Session)" | "update" | "Value" | { sesh, val -> - val.setName("New name") - sesh.update(val) - } - "update by entityName (Session)" | "update" | "Value" | { sesh, val -> - val.setName("New name") - sesh.update("Value", val) - } - "delete (Session)" | "delete" | "Value" | { sesh, val -> - sesh.delete(val) - } - } - - - def "test attaches State to query created via #queryMethodName"() { - setup: - Session session = sessionFactory.openSession() - session.beginTransaction() - Query query = queryBuildMethod(session) - query.list() - session.getTransaction().commit() - session.close() - - expect: - assertTraces(1) { - trace(0, 4) { - span(0) { - name "Session" - kind INTERNAL - hasNoParent() - attributes { - } - } - span(1) { - name resource - kind INTERNAL - childOf span(0) - attributes { - } - } - span(2) { - kind CLIENT - childOf span(1) - attributes { - "${SemanticAttributes.DB_SYSTEM.key}" "h2" - "${SemanticAttributes.DB_NAME.key}" "db1" - "${SemanticAttributes.DB_USER.key}" "sa" - "${SemanticAttributes.DB_CONNECTION_STRING.key}" "h2:mem:" - "${SemanticAttributes.DB_STATEMENT.key}" String - "${SemanticAttributes.DB_OPERATION.key}" "SELECT" - "${SemanticAttributes.DB_SQL_TABLE.key}" "Value" - } - } - span(3) { - name "Transaction.commit" - kind INTERNAL - childOf span(0) - attributes { - } - } - } - } - - where: - queryMethodName | resource | queryBuildMethod - "createQuery" | "SELECT Value" | { sess -> sess.createQuery("from Value") } - "getNamedQuery" | "SELECT Value" | { sess -> sess.getNamedQuery("TestNamedQuery") } - "createSQLQuery" | "SELECT Value" | { sess -> sess.createSQLQuery("SELECT * FROM Value") } - } - - - def "test hibernate overlapping Sessions"() { - setup: - - runUnderTrace("overlapping Sessions") { - def session1 = sessionFactory.openSession() - session1.beginTransaction() - def session2 = sessionFactory.openStatelessSession() - def session3 = sessionFactory.openSession() - - def value1 = new Value("Value 1") - session1.save(value1) - session2.insert(new Value("Value 2")) - session3.save(new Value("Value 3")) - session1.delete(value1) - - session2.close() - session1.getTransaction().commit() - session1.close() - session3.close() - } - - expect: - assertTraces(1) { - trace(0, 12) { - span(0) { - name "overlapping Sessions" - attributes { - } - } - span(1) { - name "Session" - kind INTERNAL - childOf span(0) - attributes { - } - } - span(2) { - name "Session.save Value" - kind INTERNAL - childOf span(1) - attributes { - } - } - span(3) { - name "Session.delete Value" - kind INTERNAL - childOf span(1) - attributes { - } - } - span(4) { - name "Transaction.commit" - kind INTERNAL - childOf span(1) - attributes { - } - } - span(5) { - name "INSERT db1.Value" - kind CLIENT - childOf span(4) - attributes { - "${SemanticAttributes.DB_SYSTEM.key}" "h2" - "${SemanticAttributes.DB_NAME.key}" "db1" - "${SemanticAttributes.DB_USER.key}" "sa" - "${SemanticAttributes.DB_CONNECTION_STRING.key}" "h2:mem:" - "${SemanticAttributes.DB_STATEMENT.key}" ~/^insert / - "${SemanticAttributes.DB_OPERATION.key}" "INSERT" - "${SemanticAttributes.DB_SQL_TABLE.key}" "Value" - } - } - span(6) { - name "DELETE db1.Value" - kind CLIENT - childOf span(4) - attributes { - "${SemanticAttributes.DB_SYSTEM.key}" "h2" - "${SemanticAttributes.DB_NAME.key}" "db1" - "${SemanticAttributes.DB_USER.key}" "sa" - "${SemanticAttributes.DB_CONNECTION_STRING.key}" "h2:mem:" - "${SemanticAttributes.DB_STATEMENT.key}" ~/^delete / - "${SemanticAttributes.DB_OPERATION.key}" "DELETE" - "${SemanticAttributes.DB_SQL_TABLE.key}" "Value" - } - } - span(7) { - name "Session" - kind INTERNAL - childOf span(0) - attributes { - } - } - span(8) { - name "Session.insert Value" - kind INTERNAL - childOf span(7) - attributes { - } - } - span(9) { - name "INSERT db1.Value" - kind CLIENT - childOf span(8) - attributes { - "${SemanticAttributes.DB_SYSTEM.key}" "h2" - "${SemanticAttributes.DB_NAME.key}" "db1" - "${SemanticAttributes.DB_USER.key}" "sa" - "${SemanticAttributes.DB_CONNECTION_STRING.key}" "h2:mem:" - "${SemanticAttributes.DB_STATEMENT.key}" ~/^insert / - "${SemanticAttributes.DB_OPERATION.key}" "INSERT" - "${SemanticAttributes.DB_SQL_TABLE.key}" "Value" - } - } - span(10) { - name "Session" - kind INTERNAL - childOf span(0) - attributes { - } - } - span(11) { - name "Session.save Value" - kind INTERNAL - childOf span(10) - attributes { - } - } - } - } - } -} - diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/resources/hibernate-h2.cfg.xml b/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/resources/hibernate-h2.cfg.xml deleted file mode 100644 index fe5e5de6b155..000000000000 --- a/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/resources/hibernate-h2.cfg.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - org.h2.Driver - jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE - sa - - org.hibernate.dialect.H2Dialect - - 3 - org.hibernate.cache.internal.NoCacheProvider - true - - - create - - - - - - - diff --git a/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/hibernate-procedure-call-4.3-javaagent.gradle b/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/hibernate-procedure-call-4.3-javaagent.gradle new file mode 100644 index 000000000000..fcfd02dee509 --- /dev/null +++ b/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/hibernate-procedure-call-4.3-javaagent.gradle @@ -0,0 +1,31 @@ +apply from: "$rootDir/gradle/instrumentation.gradle" + +muzzle { + pass { + group = "org.hibernate" + module = "hibernate-core" + versions = "[4.3.0.Final,)" + assertInverse = true + } +} + +dependencies { + library "org.hibernate:hibernate-core:4.3.0.Final" + + implementation project(':instrumentation:hibernate:hibernate-common:javaagent') + + testInstrumentation project(':instrumentation:jdbc:javaagent') + // Added to ensure cross compatibility: + testInstrumentation project(':instrumentation:hibernate:hibernate-3.3:javaagent') + testInstrumentation project(':instrumentation:hibernate:hibernate-4.0:javaagent') + + testLibrary "org.hibernate:hibernate-entitymanager:4.3.0.Final" + + testImplementation "org.hsqldb:hsqldb:2.0.0" + testImplementation "javax.xml.bind:jaxb-api:2.3.1" + testImplementation "org.glassfish.jaxb:jaxb-runtime:2.3.3" + + // hibernate 6 is alpha so use 5 as latest version + latestDepTestLibrary "org.hibernate:hibernate-core:5.+" + latestDepTestLibrary "org.hibernate:hibernate-entitymanager:5.+" +} diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/HibernateInstrumentationModule.java b/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/HibernateInstrumentationModule.java similarity index 100% rename from instrumentation/hibernate/hibernate-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/HibernateInstrumentationModule.java rename to instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/HibernateInstrumentationModule.java diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/ProcedureCallInstrumentation.java b/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/ProcedureCallInstrumentation.java similarity index 100% rename from instrumentation/hibernate/hibernate-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/ProcedureCallInstrumentation.java rename to instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/ProcedureCallInstrumentation.java diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/SessionInstrumentation.java b/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/SessionInstrumentation.java similarity index 100% rename from instrumentation/hibernate/hibernate-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/SessionInstrumentation.java rename to instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/SessionInstrumentation.java diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/ProcedureCallTest.groovy b/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/test/groovy/ProcedureCallTest.groovy similarity index 99% rename from instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/ProcedureCallTest.groovy rename to instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/test/groovy/ProcedureCallTest.groovy index 402d8ec67064..3ced5e988d50 100644 --- a/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/groovy/ProcedureCallTest.groovy +++ b/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/test/groovy/ProcedureCallTest.groovy @@ -23,7 +23,6 @@ import spock.lang.Shared class ProcedureCallTest extends AgentInstrumentationSpecification { - @Shared protected SessionFactory sessionFactory diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/java/Value.java b/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/test/java/Value.java similarity index 100% rename from instrumentation/hibernate/hibernate-4.3/javaagent/src/test/java/Value.java rename to instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/test/java/Value.java diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/src/test/resources/hibernate.cfg.xml b/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/test/resources/hibernate.cfg.xml similarity index 100% rename from instrumentation/hibernate/hibernate-4.3/javaagent/src/test/resources/hibernate.cfg.xml rename to instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/test/resources/hibernate.cfg.xml diff --git a/settings.gradle b/settings.gradle index e94d533f65f7..3213629251c6 100644 --- a/settings.gradle +++ b/settings.gradle @@ -139,8 +139,8 @@ include ':instrumentation:guava-10.0:library' include ':instrumentation:gwt-2.0:javaagent' include ':instrumentation:hibernate:hibernate-3.3:javaagent' include ':instrumentation:hibernate:hibernate-4.0:javaagent' -include ':instrumentation:hibernate:hibernate-4.3:javaagent' include ':instrumentation:hibernate:hibernate-common:javaagent' +include ':instrumentation:hibernate:hibernate-procedure-call-4.3:javaagent' include ':instrumentation:http-url-connection:javaagent' include ':instrumentation:hystrix-1.4:javaagent' include ':instrumentation:java-http-client:javaagent'