diff --git a/sofa-boot-project/sofa-boot-autoconfigure/pom.xml b/sofa-boot-project/sofa-boot-autoconfigure/pom.xml index 23da6d5c6..c87b24f05 100644 --- a/sofa-boot-project/sofa-boot-autoconfigure/pom.xml +++ b/sofa-boot-project/sofa-boot-autoconfigure/pom.xml @@ -108,6 +108,42 @@ true + + com.alipay.sofa + sofa-tracer-kafkamq-plugin + true + + + + com.alipay.sofa + sofa-tracer-rabbitmq-plugin + true + + + + com.alipay.sofa + sofa-tracer-rocketmq-plugin + true + + + + com.alipay.sofa + sofa-tracer-springmessage-plugin + true + + + + com.alipay.sofa + sofa-tracer-redis-plugin + true + + + + com.alipay.sofa + sofa-tracer-mongodb-plugin + true + + org.springframework.cloud @@ -120,6 +156,42 @@ javax.servlet-api provided + + + org.springframework.kafka + spring-kafka + provided + + + + org.springframework.boot + spring-boot-starter-amqp + provided + + + + org.apache.rocketmq + rocketmq-spring-boot-starter + provided + + + + org.springframework.cloud + spring-cloud-stream + provided + + + + org.springframework.boot + spring-boot-starter-data-redis + provided + + + + org.springframework.boot + spring-boot-starter-data-mongodb + provided + org.jmockit diff --git a/sofa-boot-project/sofa-boot-autoconfigure/src/main/java/com/alipay/sofa/boot/autoconfigure/tracer/SofaTracerKafkaAutoConfiguration.java b/sofa-boot-project/sofa-boot-autoconfigure/src/main/java/com/alipay/sofa/boot/autoconfigure/tracer/SofaTracerKafkaAutoConfiguration.java new file mode 100644 index 000000000..45965e8de --- /dev/null +++ b/sofa-boot-project/sofa-boot-autoconfigure/src/main/java/com/alipay/sofa/boot/autoconfigure/tracer/SofaTracerKafkaAutoConfiguration.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.boot.autoconfigure.tracer; + +import com.alipay.sofa.tracer.boot.kafka.processor.KafkaConsumerFactoryPostProcessor; +import com.alipay.sofa.tracer.boot.kafka.processor.KafkaProducerFactoryPostProcessor; +import com.sofa.alipay.tracer.plugins.kafkamq.aspect.KafkaListenerSofaTracerAspect; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.kafka.core.ConsumerFactory; +import org.springframework.kafka.core.ProducerFactory; + +/** + * @author chenchen6 2020/9/2 21:56 + * @since 3.9.1 + */ +@Configuration(proxyBeanMethods = false) +@AutoConfigureAfter(KafkaAutoConfiguration.class) +@ConditionalOnClass({ ProducerFactory.class, ConsumerFactory.class }) +@EnableAspectJAutoProxy(proxyTargetClass = true) +@ConditionalOnProperty(name = "com.alipay.tracer.kafka.enabled", havingValue = "true", matchIfMissing = true) +public class SofaTracerKafkaAutoConfiguration { + + @Bean + @ConditionalOnMissingBean + public KafkaConsumerFactoryPostProcessor kafkaConsumerFactoryPostProcessor() { + return new KafkaConsumerFactoryPostProcessor(); + } + + @Bean + @ConditionalOnMissingBean + public KafkaProducerFactoryPostProcessor kafkaProducerFactoryPostProcessor() { + return new KafkaProducerFactoryPostProcessor(); + } + + @Bean + @ConditionalOnMissingBean + public KafkaListenerSofaTracerAspect kafkaListenerSofaTracerAspect() { + return new KafkaListenerSofaTracerAspect(); + } +} diff --git a/sofa-boot-project/sofa-boot-autoconfigure/src/main/java/com/alipay/sofa/boot/autoconfigure/tracer/SofaTracerMongoAutoConfiguration.java b/sofa-boot-project/sofa-boot-autoconfigure/src/main/java/com/alipay/sofa/boot/autoconfigure/tracer/SofaTracerMongoAutoConfiguration.java new file mode 100644 index 000000000..1dec9fb52 --- /dev/null +++ b/sofa-boot-project/sofa-boot-autoconfigure/src/main/java/com/alipay/sofa/boot/autoconfigure/tracer/SofaTracerMongoAutoConfiguration.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.boot.autoconfigure.tracer; + +import com.alipay.sofa.tracer.boot.mongodb.SofaTracerMongoClientSettingsBuilderCustomizer; +import com.mongodb.client.MongoClient; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * SofaTracerMongoAutoConfiguration + * + * @author linnan + * @since 3.9.1 + **/ +@Configuration(proxyBeanMethods = false) +@AutoConfigureBefore({ MongoAutoConfiguration.class }) +@ConditionalOnClass({ MongoClient.class }) +@ConditionalOnProperty(name = "com.alipay.tracer.mongodb.enabled", havingValue = "true", matchIfMissing = true) +public class SofaTracerMongoAutoConfiguration { + + @Bean + @ConditionalOnMissingBean + SofaTracerMongoClientSettingsBuilderCustomizer sofaTracerMongoClientSettingsBuilderCustomizer() { + return new SofaTracerMongoClientSettingsBuilderCustomizer(); + } +} diff --git a/sofa-boot-project/sofa-boot-autoconfigure/src/main/java/com/alipay/sofa/boot/autoconfigure/tracer/SofaTracerRabbitMqAutoConfiguration.java b/sofa-boot-project/sofa-boot-autoconfigure/src/main/java/com/alipay/sofa/boot/autoconfigure/tracer/SofaTracerRabbitMqAutoConfiguration.java new file mode 100644 index 000000000..d62568bb0 --- /dev/null +++ b/sofa-boot-project/sofa-boot-autoconfigure/src/main/java/com/alipay/sofa/boot/autoconfigure/tracer/SofaTracerRabbitMqAutoConfiguration.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.boot.autoconfigure.tracer; + +import com.alipay.sofa.tracer.boot.rabbitmq.processor.SofaTracerRabbitMqBeanPostProcessor; +import com.sofa.alipay.tracer.plugins.rabbitmq.aspect.SofaTracerSendMessageAspect; +import org.springframework.amqp.core.Message; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.EnableAspectJAutoProxy; + +/** + * SofaTracerRabbitMqAutoConfiguration. + * + * @author chenchen6 2020/8/09 20:44 + * @since 3.9.1 + */ +@Configuration(proxyBeanMethods = false) +@AutoConfigureAfter(RabbitAutoConfiguration.class) +@ConditionalOnClass({ Message.class, RabbitTemplate.class }) +@ConditionalOnProperty(prefix = "com.alipay.sofa.tracer.rabbitmq", value = "enable", matchIfMissing = true) +@EnableAspectJAutoProxy(proxyTargetClass = true) +public class SofaTracerRabbitMqAutoConfiguration { + + @ConditionalOnBean(RabbitTemplate.class) + @Bean + public SofaTracerSendMessageAspect rabbitMqSendTracingAspect(RabbitTemplate rabbitTemplate) { + return new SofaTracerSendMessageAspect(rabbitTemplate.getExchange(), + rabbitTemplate.getRoutingKey(), rabbitTemplate.getMessageConverter(), rabbitTemplate); + } + + @ConditionalOnMissingBean + @Bean + public SofaTracerRabbitMqBeanPostProcessor sofaTracerRabbitMqBeanPostProcessor() { + return new SofaTracerRabbitMqBeanPostProcessor(); + } +} diff --git a/sofa-boot-project/sofa-boot-autoconfigure/src/main/java/com/alipay/sofa/boot/autoconfigure/tracer/SofaTracerRedisAutoConfiguration.java b/sofa-boot-project/sofa-boot-autoconfigure/src/main/java/com/alipay/sofa/boot/autoconfigure/tracer/SofaTracerRedisAutoConfiguration.java new file mode 100644 index 000000000..ddd106211 --- /dev/null +++ b/sofa-boot-project/sofa-boot-autoconfigure/src/main/java/com/alipay/sofa/boot/autoconfigure/tracer/SofaTracerRedisAutoConfiguration.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.boot.autoconfigure.tracer; + +import com.sofa.alipay.tracer.plugins.spring.redis.SofaTracerRCFBeanPostProcessor; +import com.sofa.alipay.tracer.plugins.spring.redis.common.RedisActionWrapperHelper; + +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; + +/** + * @author guolei.sgl (guolei.sgl@antfin.com) 2019/11/19 8:03 PM + * @since 3.9.1 + **/ +@Configuration(proxyBeanMethods = false) +@ConditionalOnClass({ RedisConnectionFactory.class, RedisActionWrapperHelper.class }) +@ConditionalOnProperty(name = "com.alipay.sofa.tracer.redis.enabled", havingValue = "true", matchIfMissing = true) +@AutoConfigureAfter(SofaTracerAutoConfiguration.class) +public class SofaTracerRedisAutoConfiguration { + + @Bean + @ConditionalOnMissingBean + RedisActionWrapperHelper redisActionWrapperHelper() { + return new RedisActionWrapperHelper(); + } + + @Bean + @ConditionalOnMissingBean + SofaTracerRCFBeanPostProcessor sofaTracerRCFBeanPostProcessor(RedisActionWrapperHelper redisActionWrapperHelper) { + return new SofaTracerRCFBeanPostProcessor(redisActionWrapperHelper); + } +} diff --git a/sofa-boot-project/sofa-boot-autoconfigure/src/main/java/com/alipay/sofa/boot/autoconfigure/tracer/SofaTracerRocketMqAutoConfiguration.java b/sofa-boot-project/sofa-boot-autoconfigure/src/main/java/com/alipay/sofa/boot/autoconfigure/tracer/SofaTracerRocketMqAutoConfiguration.java new file mode 100644 index 000000000..199a1d007 --- /dev/null +++ b/sofa-boot-project/sofa-boot-autoconfigure/src/main/java/com/alipay/sofa/boot/autoconfigure/tracer/SofaTracerRocketMqAutoConfiguration.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.boot.autoconfigure.tracer; + +import com.alipay.sofa.tracer.boot.rocketmq.processor.SofaTracerRocketMqConsumerPostProcessor; +import com.alipay.sofa.tracer.boot.rocketmq.processor.SofaTracerRocketMqProducerPostProcessor; +import org.apache.rocketmq.client.producer.MQProducer; +import org.apache.rocketmq.spring.autoconfigure.RocketMQAutoConfiguration; +import org.apache.rocketmq.spring.support.RocketMQListenerContainer; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * SofaTracerRocketMqAutoConfiguration. + * + * @author linnan + * @since 3.9.1 + */ +@Configuration(proxyBeanMethods = false) +@AutoConfigureBefore(RocketMQAutoConfiguration.class) +@ConditionalOnClass({ MQProducer.class, RocketMQListenerContainer.class }) +@ConditionalOnProperty(prefix = "com.alipay.sofa.tracer.rocketmq", value = "enable", matchIfMissing = true) +public class SofaTracerRocketMqAutoConfiguration { + + @ConditionalOnMissingBean + @Bean + public SofaTracerRocketMqProducerPostProcessor sofaTracerRocketMqProducerPostProcessor() { + return new SofaTracerRocketMqProducerPostProcessor(); + } + + @ConditionalOnMissingBean + @Bean + public SofaTracerRocketMqConsumerPostProcessor sofaTracerRocketMqConsumerPostProcessor() { + return new SofaTracerRocketMqConsumerPostProcessor(); + } +} diff --git a/sofa-boot-project/sofa-boot-autoconfigure/src/main/java/com/alipay/sofa/boot/autoconfigure/tracer/SpringMessageAutoConfiguration.java b/sofa-boot-project/sofa-boot-autoconfigure/src/main/java/com/alipay/sofa/boot/autoconfigure/tracer/SpringMessageAutoConfiguration.java new file mode 100644 index 000000000..9a1ec83d8 --- /dev/null +++ b/sofa-boot-project/sofa-boot-autoconfigure/src/main/java/com/alipay/sofa/boot/autoconfigure/tracer/SpringMessageAutoConfiguration.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.boot.autoconfigure.tracer; + +import com.alipay.sofa.tracer.boot.message.processor.StreamRocketMQTracerBeanPostProcessor; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.cloud.stream.messaging.DirectWithAttributesChannel; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.integration.channel.AbstractMessageChannel; +import org.springframework.messaging.support.ChannelInterceptor; + +/** + * @author guolei.sgl (guolei.sgl@antfin.com) 2019/12/4 10:34 PM + * @since 3.9.1 + **/ +@Configuration(proxyBeanMethods = false) +@ConditionalOnClass({ AbstractMessageChannel.class, ChannelInterceptor.class, + DirectWithAttributesChannel.class }) +@ConditionalOnProperty(prefix = "com.alipay.sofa.tracer.message", value = "enable", matchIfMissing = true) +public class SpringMessageAutoConfiguration { + + @Bean + @ConditionalOnMissingBean + public StreamRocketMQTracerBeanPostProcessor streamRocketMQTracerBeanPostProcessor() { + return new StreamRocketMQTracerBeanPostProcessor(); + } +} diff --git a/sofa-boot-project/sofa-boot-autoconfigure/src/main/resources/META-INF/spring.factories b/sofa-boot-project/sofa-boot-autoconfigure/src/main/resources/META-INF/spring.factories index 40e0a03b2..8f07a9d63 100644 --- a/sofa-boot-project/sofa-boot-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/sofa-boot-project/sofa-boot-autoconfigure/src/main/resources/META-INF/spring.factories @@ -8,6 +8,12 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.alipay.sofa.boot.autoconfigure.tracer.SofaTracerFeignClientAutoConfiguration,\ com.alipay.sofa.boot.autoconfigure.tracer.ZipkinSofaTracerAutoConfiguration,\ com.alipay.sofa.boot.autoconfigure.tracer.SofaTracerRestTemplateAutoConfiguration,\ + com.alipay.sofa.boot.autoconfigure.tracer.SofaTracerKafkaAutoConfiguration,\ + com.alipay.sofa.boot.autoconfigure.tracer.SofaTracerRabbitMqAutoConfiguration,\ + com.alipay.sofa.boot.autoconfigure.tracer.SofaTracerRocketMqAutoConfiguration,\ + com.alipay.sofa.boot.autoconfigure.tracer.SpringMessageAutoConfiguration,\ + com.alipay.sofa.boot.autoconfigure.tracer.SofaTracerRedisAutoConfiguration,\ + com.alipay.sofa.boot.autoconfigure.tracer.SofaTracerMongoAutoConfiguration,\ com.alipay.sofa.boot.autoconfigure.tracer.TracerAnnotationAutoConfiguration,\ com.alipay.sofa.boot.autoconfigure.startup.SofaStartupAutoConfiguration,\ com.alipay.sofa.boot.autoconfigure.startup.SofaStartupIsleAutoConfiguration diff --git a/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/pom.xml b/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/pom.xml index 124aeced0..dd20ff62c 100644 --- a/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/pom.xml +++ b/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/pom.xml @@ -70,17 +70,89 @@ provided + + com.alipay.sofa + sofa-tracer-kafkamq-plugin + true + + + + com.alipay.sofa + sofa-tracer-rabbitmq-plugin + true + + + + com.alipay.sofa + sofa-tracer-rocketmq-plugin + true + + + + com.alipay.sofa + sofa-tracer-springmessage-plugin + true + + + + com.alipay.sofa + sofa-tracer-redis-plugin + true + + + + com.alipay.sofa + sofa-tracer-mongodb-plugin + true + + org.springframework.cloud spring-cloud-starter-openfeign true + + org.springframework.kafka + spring-kafka + true + + + + org.springframework.boot + spring-boot-starter-amqp + true + + + + org.apache.rocketmq + rocketmq-spring-boot-starter + true + + + + org.springframework.cloud + spring-cloud-stream + true + + + + org.springframework.boot + spring-boot-starter-data-mongodb + provided + + junit junit + + org.springframework.boot + spring-boot-starter-test + test + + diff --git a/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/src/main/java/com/alipay/sofa/tracer/boot/kafka/processor/KafkaConsumerFactoryPostProcessor.java b/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/src/main/java/com/alipay/sofa/tracer/boot/kafka/processor/KafkaConsumerFactoryPostProcessor.java new file mode 100644 index 000000000..a9efe4180 --- /dev/null +++ b/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/src/main/java/com/alipay/sofa/tracer/boot/kafka/processor/KafkaConsumerFactoryPostProcessor.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.tracer.boot.kafka.processor; + +import com.sofa.alipay.tracer.plugins.kafkamq.factories.SofaTracerKafkaConsumerFactory; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.kafka.core.ConsumerFactory; + +/** + * KafkaConsumerFactoryPostProcessor. + * + * @author chenchen6 2020/9/3 22:18 + * @since 3.9.1 + */ +public class KafkaConsumerFactoryPostProcessor implements BeanPostProcessor { + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) + throws BeansException { + return bean; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) + throws BeansException { + if (bean instanceof ConsumerFactory && !(bean instanceof SofaTracerKafkaConsumerFactory)) { + return new SofaTracerKafkaConsumerFactory((ConsumerFactory) bean); + } + return bean; + } +} diff --git a/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/src/main/java/com/alipay/sofa/tracer/boot/kafka/processor/KafkaProducerFactoryPostProcessor.java b/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/src/main/java/com/alipay/sofa/tracer/boot/kafka/processor/KafkaProducerFactoryPostProcessor.java new file mode 100644 index 000000000..e690779c3 --- /dev/null +++ b/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/src/main/java/com/alipay/sofa/tracer/boot/kafka/processor/KafkaProducerFactoryPostProcessor.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.tracer.boot.kafka.processor; + +import com.sofa.alipay.tracer.plugins.kafkamq.factories.SofaTracerKafkaProducerFactory; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.kafka.core.ProducerFactory; + +/** + * KafkaProducerFactoryPostProcessor。 + * + * @author chenchen6 2020/9/3 22:15 + * @since 3.9.1 + */ +public class KafkaProducerFactoryPostProcessor implements BeanPostProcessor { + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) + throws BeansException { + return bean; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) + throws BeansException { + if (bean instanceof ProducerFactory && !(bean instanceof SofaTracerKafkaProducerFactory)) { + return new SofaTracerKafkaProducerFactory((ProducerFactory) bean); + } + return bean; + } +} diff --git a/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/src/main/java/com/alipay/sofa/tracer/boot/message/processor/StreamRocketMQTracerBeanPostProcessor.java b/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/src/main/java/com/alipay/sofa/tracer/boot/message/processor/StreamRocketMQTracerBeanPostProcessor.java new file mode 100644 index 000000000..bd7bfc1a3 --- /dev/null +++ b/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/src/main/java/com/alipay/sofa/tracer/boot/message/processor/StreamRocketMQTracerBeanPostProcessor.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.tracer.boot.message.processor; + +import com.alipay.common.tracer.core.configuration.SofaTracerConfiguration; +import com.alipay.sofa.tracer.plugins.message.interceptor.SofaTracerChannelInterceptor; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.context.EnvironmentAware; +import org.springframework.core.PriorityOrdered; +import org.springframework.core.env.Environment; +import org.springframework.integration.channel.AbstractMessageChannel; + +/** + * @author guolei.sgl (guolei.sgl@antfin.com) 2019/12/4 11:07 AM + * @since 3.9.1 + **/ +public class StreamRocketMQTracerBeanPostProcessor implements BeanPostProcessor, EnvironmentAware, + PriorityOrdered { + + private Environment environment; + + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) + throws BeansException { + if (bean instanceof AbstractMessageChannel) { + String appName = environment.getProperty(SofaTracerConfiguration.TRACER_APPNAME_KEY); + ((AbstractMessageChannel) bean).addInterceptor(SofaTracerChannelInterceptor + .create(appName)); + } + return bean; + } + + @Override + public void setEnvironment(Environment environment) { + this.environment = environment; + } + + @Override + public int getOrder() { + return LOWEST_PRECEDENCE; + } +} diff --git a/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/src/main/java/com/alipay/sofa/tracer/boot/mongodb/SofaTracerMongoClientSettingsBuilderCustomizer.java b/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/src/main/java/com/alipay/sofa/tracer/boot/mongodb/SofaTracerMongoClientSettingsBuilderCustomizer.java new file mode 100644 index 000000000..7bedb0fcf --- /dev/null +++ b/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/src/main/java/com/alipay/sofa/tracer/boot/mongodb/SofaTracerMongoClientSettingsBuilderCustomizer.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.tracer.boot.mongodb; + +import com.alipay.common.tracer.core.configuration.SofaTracerConfiguration; +import com.alipay.sofa.tracer.plugins.mongodb.SofaTracerCommandListener; +import com.mongodb.MongoClientSettings.Builder; +import org.springframework.boot.autoconfigure.mongo.MongoClientSettingsBuilderCustomizer; +import org.springframework.context.EnvironmentAware; +import org.springframework.core.env.Environment; + +/** + * @author linnan + * @since 3.9.1 + */ +public class SofaTracerMongoClientSettingsBuilderCustomizer implements + MongoClientSettingsBuilderCustomizer, + EnvironmentAware { + private Environment environment; + + @Override + public void setEnvironment(Environment environment) { + this.environment = environment; + } + + @Override + public void customize(Builder clientSettingsBuilder) { + String appName = environment.getProperty(SofaTracerConfiguration.TRACER_APPNAME_KEY); + SofaTracerCommandListener commandListener = new SofaTracerCommandListener(appName); + clientSettingsBuilder.addCommandListener(commandListener); + } +} diff --git a/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/src/main/java/com/alipay/sofa/tracer/boot/rabbitmq/processor/SofaTracerRabbitMqBeanPostProcessor.java b/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/src/main/java/com/alipay/sofa/tracer/boot/rabbitmq/processor/SofaTracerRabbitMqBeanPostProcessor.java new file mode 100644 index 000000000..2bfca1dfa --- /dev/null +++ b/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/src/main/java/com/alipay/sofa/tracer/boot/rabbitmq/processor/SofaTracerRabbitMqBeanPostProcessor.java @@ -0,0 +1,104 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.tracer.boot.rabbitmq.processor; + +import com.sofa.alipay.tracer.plugins.rabbitmq.interceptor.SofaTracerConsumeInterceptor; +import org.aopalliance.aop.Advice; +import org.springframework.amqp.rabbit.config.AbstractRabbitListenerContainerFactory; +import org.springframework.amqp.rabbit.config.DirectRabbitListenerContainerFactory; +import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory; +import org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer; +import org.springframework.amqp.rabbit.listener.DirectMessageListenerContainer; +import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.core.PriorityOrdered; +import org.springframework.util.ReflectionUtils; + +import java.lang.reflect.Field; + +/** + * SofaTracerRabbitMqBeanPostProcessor. + * + * @author chenchen6 2020/8/09 20:44 + * @since 3.9.1 + */ +public class SofaTracerRabbitMqBeanPostProcessor implements BeanPostProcessor, PriorityOrdered { + + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) + throws BeansException { + if (bean instanceof SimpleRabbitListenerContainerFactory) { + SimpleRabbitListenerContainerFactory factory = (SimpleRabbitListenerContainerFactory) bean; + registerTracingInterceptor(factory); + } else if (bean instanceof SimpleMessageListenerContainer) { + SimpleMessageListenerContainer container = (SimpleMessageListenerContainer) bean; + registerTracingInterceptor(container); + } else if (bean instanceof DirectRabbitListenerContainerFactory) { + DirectRabbitListenerContainerFactory factory = (DirectRabbitListenerContainerFactory) bean; + registerTracingInterceptor(factory); + } else if (bean instanceof DirectMessageListenerContainer) { + DirectMessageListenerContainer container = (DirectMessageListenerContainer) bean; + registerTracingInterceptor(container); + } + return bean; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) + throws BeansException { + return bean; + } + + private void registerTracingInterceptor(AbstractRabbitListenerContainerFactory factory) { + Advice[] chain = factory.getAdviceChain(); + Advice[] adviceChainWithTracing = getAdviceChainOrAddInterceptorToChain(chain); + factory.setAdviceChain(adviceChainWithTracing); + } + + private void registerTracingInterceptor(AbstractMessageListenerContainer container) { + Field adviceChainField = ReflectionUtils.findField(AbstractMessageListenerContainer.class, + "adviceChain"); + ReflectionUtils.makeAccessible(adviceChainField); + Advice[] chain = (Advice[]) ReflectionUtils.getField(adviceChainField, container); + Advice[] adviceChainWithTracing = getAdviceChainOrAddInterceptorToChain(chain); + container.setAdviceChain(adviceChainWithTracing); + } + + private Advice[] getAdviceChainOrAddInterceptorToChain(Advice... existingAdviceChain) { + if (existingAdviceChain == null) { + return new Advice[] { new SofaTracerConsumeInterceptor() }; + } + + for (Advice advice : existingAdviceChain) { + if (advice instanceof SofaTracerConsumeInterceptor) { + return existingAdviceChain; + } + } + + Advice[] newChain = new Advice[existingAdviceChain.length + 1]; + System.arraycopy(existingAdviceChain, 0, newChain, 0, existingAdviceChain.length); + newChain[existingAdviceChain.length] = new SofaTracerConsumeInterceptor(); + + return newChain; + } + + @Override + public int getOrder() { + return LOWEST_PRECEDENCE; + } +} diff --git a/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/src/main/java/com/alipay/sofa/tracer/boot/rocketmq/processor/SofaTracerRocketMqConsumerPostProcessor.java b/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/src/main/java/com/alipay/sofa/tracer/boot/rocketmq/processor/SofaTracerRocketMqConsumerPostProcessor.java new file mode 100644 index 000000000..deac36745 --- /dev/null +++ b/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/src/main/java/com/alipay/sofa/tracer/boot/rocketmq/processor/SofaTracerRocketMqConsumerPostProcessor.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.tracer.boot.rocketmq.processor; + +import com.alipay.common.tracer.core.configuration.SofaTracerConfiguration; +import com.alipay.sofa.tracer.plugins.rocketmq.interceptor.SofaTracerConsumeMessageHook; +import org.apache.rocketmq.spring.support.DefaultRocketMQListenerContainer; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.context.EnvironmentAware; +import org.springframework.core.PriorityOrdered; +import org.springframework.core.env.Environment; + +/** + * @author linnan + * @since 3.9.1 + */ +public class SofaTracerRocketMqConsumerPostProcessor implements BeanPostProcessor, + EnvironmentAware, PriorityOrdered { + private Environment environment; + + @Override + public void setEnvironment(Environment environment) { + this.environment = environment; + } + + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) + throws BeansException { + return bean; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) + throws BeansException { + if (bean instanceof DefaultRocketMQListenerContainer) { + DefaultRocketMQListenerContainer container = (DefaultRocketMQListenerContainer) bean; + String appName = environment.getProperty(SofaTracerConfiguration.TRACER_APPNAME_KEY); + SofaTracerConsumeMessageHook hook = new SofaTracerConsumeMessageHook(appName); + container.getConsumer().getDefaultMQPushConsumerImpl().registerConsumeMessageHook(hook); + return container; + } + return bean; + } + + @Override + public int getOrder() { + return LOWEST_PRECEDENCE; + } +} diff --git a/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/src/main/java/com/alipay/sofa/tracer/boot/rocketmq/processor/SofaTracerRocketMqProducerPostProcessor.java b/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/src/main/java/com/alipay/sofa/tracer/boot/rocketmq/processor/SofaTracerRocketMqProducerPostProcessor.java new file mode 100644 index 000000000..d1990139f --- /dev/null +++ b/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/src/main/java/com/alipay/sofa/tracer/boot/rocketmq/processor/SofaTracerRocketMqProducerPostProcessor.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.tracer.boot.rocketmq.processor; + +import com.alipay.common.tracer.core.configuration.SofaTracerConfiguration; +import com.alipay.sofa.tracer.plugins.rocketmq.interceptor.SofaTracerSendMessageHook; +import org.apache.rocketmq.client.producer.DefaultMQProducer; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.context.EnvironmentAware; +import org.springframework.core.PriorityOrdered; +import org.springframework.core.env.Environment; + +/** + * @author linnan + * @since 3.9.1 + */ +public class SofaTracerRocketMqProducerPostProcessor implements BeanPostProcessor, + EnvironmentAware, PriorityOrdered { + private Environment environment; + + @Override + public void setEnvironment(Environment environment) { + this.environment = environment; + } + + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) + throws BeansException { + return bean; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) + throws BeansException { + if (bean instanceof DefaultMQProducer) { + DefaultMQProducer producer = (DefaultMQProducer) bean; + String appName = environment.getProperty(SofaTracerConfiguration.TRACER_APPNAME_KEY); + SofaTracerSendMessageHook hook = new SofaTracerSendMessageHook(appName); + producer.getDefaultMQProducerImpl().registerSendMessageHook(hook); + return producer; + } + return bean; + } + + @Override + public int getOrder() { + return LOWEST_PRECEDENCE; + } +} diff --git a/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/src/test/com/alipay/sofa/tracer/boot/mongodb/SofaTracerMongoClientSettingsBuilderCustomizerTest.java b/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/src/test/com/alipay/sofa/tracer/boot/mongodb/SofaTracerMongoClientSettingsBuilderCustomizerTest.java new file mode 100644 index 000000000..6d581b6f8 --- /dev/null +++ b/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/src/test/com/alipay/sofa/tracer/boot/mongodb/SofaTracerMongoClientSettingsBuilderCustomizerTest.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.tracer.boot.mongodb; + +import com.alipay.sofa.tracer.plugins.mongodb.SofaTracerCommandListener; +import com.mongodb.MongoClientSettings; +import com.mongodb.event.CommandListener; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; + +import java.util.List; + +/** + * @author linnan + * @since 3.9.1 + */ +@RunWith(SpringRunner.class) +@SpringBootTest +@TestPropertySource(properties = "spring.application.name=SofaTracerMongoClientSettingsBuilderCustomizerTest") +public class SofaTracerMongoClientSettingsBuilderCustomizerTest { + + @Autowired + private SofaTracerMongoClientSettingsBuilderCustomizer sofaTracerMongoClientSettingsBuilderCustomizer; + + @Test + public void customize() { + MongoClientSettings.Builder builder = MongoClientSettings.builder(); + sofaTracerMongoClientSettingsBuilderCustomizer.customize(builder); + MongoClientSettings settings = builder.build(); + List commandListeners = settings.getCommandListeners(); + Assert.assertNotNull(commandListeners); + Assert.assertFalse(commandListeners.isEmpty()); + CommandListener commandListener = commandListeners.get(commandListeners.size() - 1); + Assert.assertTrue(commandListener instanceof SofaTracerCommandListener); + } + + @Configuration(proxyBeanMethods = false) + static class SofaTracerMongoClientSettingsBuilderCustomizerTestConfiguration { + @Bean + public SofaTracerMongoClientSettingsBuilderCustomizer sofaTracerMongoClientSettingsBuilderCustomizer() { + return new SofaTracerMongoClientSettingsBuilderCustomizer(); + } + } +} diff --git a/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/src/test/com/alipay/sofa/tracer/boot/rocketmq/processor/SofaTracerRocketMqConsumerPostProcessorTest.java b/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/src/test/com/alipay/sofa/tracer/boot/rocketmq/processor/SofaTracerRocketMqConsumerPostProcessorTest.java new file mode 100644 index 000000000..ad57b1996 --- /dev/null +++ b/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/src/test/com/alipay/sofa/tracer/boot/rocketmq/processor/SofaTracerRocketMqConsumerPostProcessorTest.java @@ -0,0 +1,100 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.tracer.boot.rocketmq.processor; + +import com.alipay.sofa.tracer.plugins.rocketmq.interceptor.SofaTracerConsumeMessageHook; +import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer; +import org.apache.rocketmq.client.hook.ConsumeMessageHook; +import org.apache.rocketmq.client.impl.consumer.DefaultMQPushConsumerImpl; +import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; +import org.apache.rocketmq.spring.core.RocketMQListener; +import org.apache.rocketmq.spring.support.DefaultRocketMQListenerContainer; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.util.ReflectionUtils; + +import java.lang.reflect.Field; +import java.util.ArrayList; + +/** + * @author linnan + * @since 3.9.1 + */ +@RunWith(SpringRunner.class) +@SpringBootTest +@TestPropertySource(properties = "spring.application.name=SofaTracerRocketMqConsumerPostProcessorTest") +public class SofaTracerRocketMqConsumerPostProcessorTest { + + @Autowired + private DefaultRocketMQListenerContainer defaultRocketMQListenerContainer; + + @Test + public void postProcessAfterInitialization() { + DefaultMQPushConsumer consumer = defaultRocketMQListenerContainer.getConsumer(); + DefaultMQPushConsumerImpl defaultMQPushConsumerImpl = consumer.getDefaultMQPushConsumerImpl(); + Assert.assertTrue(defaultMQPushConsumerImpl.hasHook()); + Field field = ReflectionUtils.findField(DefaultMQPushConsumerImpl.class, + "consumeMessageHookList"); + Assert.assertNotNull(field); + field.setAccessible(true); + Object value = ReflectionUtils.getField(field, defaultMQPushConsumerImpl); + Assert.assertTrue(value instanceof ArrayList); + ArrayList consumeMessageHookList = (ArrayList) value; + ConsumeMessageHook consumeMessageHook = consumeMessageHookList.get( + consumeMessageHookList.size() - 1); + Assert.assertTrue(consumeMessageHook instanceof SofaTracerConsumeMessageHook); + } + + @Configuration(proxyBeanMethods = false) + static class SofaTracerRocketMqConsumerPostProcessorTestConfiguration { + @Bean + public SofaTracerRocketMqConsumerPostProcessor sofaTracerRocketMqConsumerPostProcessor() { + return new SofaTracerRocketMqConsumerPostProcessor(); + } + + @Bean + public DefaultRocketMQListenerContainer defaultRocketMQListenerContainer() { + MockListener mockListener = new MockListener(); + RocketMQMessageListener annotation = AnnotationUtils.findAnnotation(MockListener.class, + RocketMQMessageListener.class); + DefaultRocketMQListenerContainer container = new DefaultRocketMQListenerContainer(); + DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(); + container.setConsumer(consumer); + container.setConsumerGroup(annotation.consumerGroup()); + container.setNameServer("127.0.0.1:9876"); + container.setTopic(annotation.topic()); + container.setRocketMQMessageListener(annotation); + container.setRocketMQListener(mockListener); + return container; + } + } + + @RocketMQMessageListener(consumerGroup = "sofa-group", topic = "sofa-topic") + static class MockListener implements RocketMQListener { + @Override + public void onMessage(String message) { + } + } +} diff --git a/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/src/test/com/alipay/sofa/tracer/boot/rocketmq/processor/SofaTracerRocketMqProducerPostProcessorTest.java b/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/src/test/com/alipay/sofa/tracer/boot/rocketmq/processor/SofaTracerRocketMqProducerPostProcessorTest.java new file mode 100644 index 000000000..7ecaba9b2 --- /dev/null +++ b/sofa-boot-project/sofa-boot-core/tracer-sofa-boot/src/test/com/alipay/sofa/tracer/boot/rocketmq/processor/SofaTracerRocketMqProducerPostProcessorTest.java @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.tracer.boot.rocketmq.processor; + +import com.alipay.sofa.tracer.plugins.rocketmq.interceptor.SofaTracerSendMessageHook; +import org.apache.rocketmq.client.hook.SendMessageHook; +import org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl; +import org.apache.rocketmq.client.producer.DefaultMQProducer; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.util.ReflectionUtils; + +import java.lang.reflect.Field; +import java.util.ArrayList; + +/** + * @author linnan + * @since 3.9.1 + */ +@RunWith(SpringRunner.class) +@SpringBootTest +@TestPropertySource(properties = "spring.application.name=SofaTracerRocketMqProducerPostProcessorTest") +public class SofaTracerRocketMqProducerPostProcessorTest { + + @Autowired + private DefaultMQProducer defaultMQProducer; + + @Test + public void postProcessAfterInitialization() { + DefaultMQProducerImpl producer = defaultMQProducer.getDefaultMQProducerImpl(); + Assert.assertTrue(producer.hasSendMessageHook()); + Field field = ReflectionUtils.findField(DefaultMQProducerImpl.class, + "sendMessageHookList"); + Assert.assertNotNull(field); + field.setAccessible(true); + Object value = ReflectionUtils.getField(field, producer); + Assert.assertTrue(value instanceof ArrayList); + ArrayList sendMessageHookList = (ArrayList) value; + SendMessageHook sendMessageHook = sendMessageHookList.get(sendMessageHookList.size() - 1); + Assert.assertTrue(sendMessageHook instanceof SofaTracerSendMessageHook); + } + + @Configuration(proxyBeanMethods = false) + static class SofaTracerRocketMqProducerPostProcessorTestConfiguration { + @Bean + public SofaTracerRocketMqProducerPostProcessor sofaTracerRocketMqProducerPostProcessor() { + return new SofaTracerRocketMqProducerPostProcessor(); + } + + @Bean + public DefaultMQProducer defaultMQProducer() { + return new DefaultMQProducer(); + } + } +} diff --git a/sofa-boot-project/sofa-boot-parent/pom.xml b/sofa-boot-project/sofa-boot-parent/pom.xml index 0050bb64e..b5334c1be 100644 --- a/sofa-boot-project/sofa-boot-parent/pom.xml +++ b/sofa-boot-project/sofa-boot-parent/pom.xml @@ -30,6 +30,8 @@ 2.22.2 + 2.1.0.RELEASE + 2.0.2 3.0.5 3.1.0 9.0.54 @@ -71,6 +73,20 @@ provided + + org.springframework.cloud + spring-cloud-stream + ${spring.cloud.stream.version} + provided + + + + org.apache.rocketmq + rocketmq-spring-boot-starter + ${rocketmq.spring.boot.starter.version} + provided + + javax.servlet javax.servlet-api diff --git a/sofa-boot-project/sofaboot-dependencies/pom.xml b/sofa-boot-project/sofaboot-dependencies/pom.xml index acf0e1425..627448c21 100644 --- a/sofa-boot-project/sofaboot-dependencies/pom.xml +++ b/sofa-boot-project/sofaboot-dependencies/pom.xml @@ -325,6 +325,42 @@ ${tracer.core.version} + + com.alipay.sofa + sofa-tracer-kafkamq-plugin + ${tracer.core.version} + + + + com.alipay.sofa + sofa-tracer-rabbitmq-plugin + ${tracer.core.version} + + + + com.alipay.sofa + sofa-tracer-rocketmq-plugin + ${tracer.core.version} + + + + com.alipay.sofa + sofa-tracer-springmessage-plugin + ${tracer.core.version} + + + + com.alipay.sofa + sofa-tracer-redis-plugin + ${tracer.core.version} + + + + com.alipay.sofa + sofa-tracer-mongodb-plugin + ${tracer.core.version} + + com.alipay.sofa registry-client-all