From 0ad3d27cb628327410dc3020f33b460362c930df Mon Sep 17 00:00:00 2001 From: liuyangming Date: Mon, 6 Mar 2017 09:57:20 +0800 Subject: [PATCH] =?UTF-8?q?*=20=E6=8F=90=E5=8D=87=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E8=87=B30.3.0-RC5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bytejta-core/pom.xml | 2 +- bytejta-supports/pom.xml | 4 +- .../dubbo/DubboConfigPostProcessor.java | 192 ++++++++++++++++++ .../supports/dubbo/DubboConfigValidator.java | 24 +++ .../validator/ApplicationConfigValidator.java | 45 ++++ .../validator/ProtocolConfigValidator.java | 50 +++++ .../validator/ProviderConfigValidator.java | 36 ++++ .../validator/ReferenceConfigValidator.java | 119 +++++++++++ .../validator/ServiceConfigValidator.java | 79 +++++++ .../TransactionManagerPostProcessor.java | 93 +++++++++ .../src/main/resources/bytejta-all.xml | 3 +- .../{bytejta.xml => bytejta-core.xml} | 4 +- .../src/main/resources/bytejta-dubbo.xml | 20 ++ pom.xml | 2 +- 14 files changed, 667 insertions(+), 6 deletions(-) create mode 100644 bytejta-supports/src/main/java/org/bytesoft/bytejta/supports/dubbo/DubboConfigPostProcessor.java create mode 100644 bytejta-supports/src/main/java/org/bytesoft/bytejta/supports/dubbo/DubboConfigValidator.java create mode 100644 bytejta-supports/src/main/java/org/bytesoft/bytejta/supports/dubbo/validator/ApplicationConfigValidator.java create mode 100644 bytejta-supports/src/main/java/org/bytesoft/bytejta/supports/dubbo/validator/ProtocolConfigValidator.java create mode 100644 bytejta-supports/src/main/java/org/bytesoft/bytejta/supports/dubbo/validator/ProviderConfigValidator.java create mode 100644 bytejta-supports/src/main/java/org/bytesoft/bytejta/supports/dubbo/validator/ReferenceConfigValidator.java create mode 100644 bytejta-supports/src/main/java/org/bytesoft/bytejta/supports/dubbo/validator/ServiceConfigValidator.java create mode 100644 bytejta-supports/src/main/java/org/bytesoft/bytejta/supports/spring/TransactionManagerPostProcessor.java rename bytejta-supports/src/main/resources/{bytejta.xml => bytejta-core.xml} (93%) create mode 100644 bytejta-supports/src/main/resources/bytejta-dubbo.xml diff --git a/bytejta-core/pom.xml b/bytejta-core/pom.xml index ef427d6..5eda609 100644 --- a/bytejta-core/pom.xml +++ b/bytejta-core/pom.xml @@ -5,7 +5,7 @@ org.bytesoft bytejta-parent - 0.3.0-RC4 + 0.3.0-RC5 bytejta-core jar diff --git a/bytejta-supports/pom.xml b/bytejta-supports/pom.xml index 395f52d..651cf5b 100644 --- a/bytejta-supports/pom.xml +++ b/bytejta-supports/pom.xml @@ -5,7 +5,7 @@ org.bytesoft bytejta-parent - 0.3.0-RC4 + 0.3.0-RC5 bytejta-supports jar @@ -22,7 +22,7 @@ org.bytesoft bytejta-core - 0.3.0-RC4 + 0.3.0-RC5 javax.jms diff --git a/bytejta-supports/src/main/java/org/bytesoft/bytejta/supports/dubbo/DubboConfigPostProcessor.java b/bytejta-supports/src/main/java/org/bytesoft/bytejta/supports/dubbo/DubboConfigPostProcessor.java new file mode 100644 index 0000000..c72f730 --- /dev/null +++ b/bytejta-supports/src/main/java/org/bytesoft/bytejta/supports/dubbo/DubboConfigPostProcessor.java @@ -0,0 +1,192 @@ +/** + * Copyright 2014-2017 yangming.liu. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, see . + */ +package org.bytesoft.bytejta.supports.dubbo; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.bytesoft.bytejta.supports.dubbo.validator.ApplicationConfigValidator; +import org.bytesoft.bytejta.supports.dubbo.validator.ProtocolConfigValidator; +import org.bytesoft.bytejta.supports.dubbo.validator.ProviderConfigValidator; +import org.bytesoft.bytejta.supports.dubbo.validator.ReferenceConfigValidator; +import org.bytesoft.bytejta.supports.dubbo.validator.ServiceConfigValidator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeansException; +import org.springframework.beans.FatalBeanException; +import org.springframework.beans.MutablePropertyValues; +import org.springframework.beans.PropertyValue; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.BeanFactoryPostProcessor; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; + +public class DubboConfigPostProcessor implements BeanFactoryPostProcessor { + static final Logger logger = LoggerFactory.getLogger(DubboConfigPostProcessor.class); + + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + + List appNameList = new ArrayList(); + List providerList = new ArrayList(); + List consumerList = new ArrayList(); + List protocolList = new ArrayList(); + List registryList = new ArrayList(); + + Map serviceMap = new HashMap(); + Map referenceMap = new HashMap(); + + Map> clazzMap = new HashMap>(); + + String[] beanNameArray = beanFactory.getBeanDefinitionNames(); + for (int i = 0; i < beanNameArray.length; i++) { + String beanName = beanNameArray[i]; + BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName); + String beanClassName = beanDef.getBeanClassName(); + + Class beanClass = null; + try { + beanClass = cl.loadClass(beanClassName); + } catch (Exception ex) { + logger.debug("Cannot load class {}, beanId= {}!", beanClassName, beanName, ex); + continue; + } + + clazzMap.put(beanClassName, beanClass); + } + + for (int i = 0; i < beanNameArray.length; i++) { + String beanName = beanNameArray[i]; + BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName); + String beanClassName = beanDef.getBeanClassName(); + + Class beanClass = clazzMap.get(beanClassName); + + if (com.alibaba.dubbo.config.ApplicationConfig.class.equals(beanClass)) { + appNameList.add(beanDef); + } else if (com.alibaba.dubbo.config.ProtocolConfig.class.equals(beanClass)) { + protocolList.add(beanDef); + } else if (com.alibaba.dubbo.config.RegistryConfig.class.equals(beanClass)) { + registryList.add(beanDef); + } else if (com.alibaba.dubbo.config.ProviderConfig.class.equals(beanClass)) { + providerList.add(beanDef); + } else if (com.alibaba.dubbo.config.ConsumerConfig.class.equals(beanClass)) { + consumerList.add(beanDef); + } else if (com.alibaba.dubbo.config.spring.ServiceBean.class.equals(beanClass)) { + MutablePropertyValues mpv = beanDef.getPropertyValues(); + PropertyValue group = mpv.getPropertyValue("group"); + if (group == null || group.getValue() == null // + || ("org.bytesoft.bytejta".equals(group.getValue()) + || String.valueOf(group.getValue()).startsWith("org.bytesoft.bytejta-")) == false) { + continue; + } + + serviceMap.put(beanName, beanDef); + } else if (com.alibaba.dubbo.config.spring.ReferenceBean.class.equals(beanClass)) { + MutablePropertyValues mpv = beanDef.getPropertyValues(); + PropertyValue group = mpv.getPropertyValue("group"); + if (group == null || group.getValue() == null // + || ("org.bytesoft.bytejta".equals(group.getValue()) + || String.valueOf(group.getValue()).startsWith("org.bytesoft.bytejta-")) == false) { + continue; + } + + referenceMap.put(beanName, beanDef); + } + } + + Set providerSet = new HashSet(); + Set protocolSet = new HashSet(); + for (Iterator> itr = serviceMap.entrySet().iterator(); itr.hasNext();) { + Map.Entry entry = itr.next(); + BeanDefinition beanDef = entry.getValue(); + MutablePropertyValues mpv = beanDef.getPropertyValues(); + PropertyValue provider = mpv.getPropertyValue("provider"); + PropertyValue protocol = mpv.getPropertyValue("protocol"); + + String providerValue = provider == null ? null : String.valueOf(provider.getValue()); + if (providerValue == null) { + if (providerList.size() > 0) { + providerSet.add(providerList.get(0)); + } + } else if ("N/A".equals(providerValue) == false) { + String[] keyArray = providerValue.split("\\s*,\\s*"); + for (int j = 0; j < keyArray.length; j++) { + String key = keyArray[j]; + BeanDefinition def = beanFactory.getBeanDefinition(key); + providerSet.add(def); + } + } + + String protocolValue = protocol == null ? null : String.valueOf(protocol.getValue()); + if (protocolValue == null) { + if (protocolList.size() > 0) { + protocolSet.add(protocolList.get(0)); + } + } else if ("N/A".equals(protocolValue) == false) { + String[] keyArray = protocolValue.split("\\s*,\\s*"); + for (int i = 0; i < keyArray.length; i++) { + String key = keyArray[i]; + BeanDefinition def = beanFactory.getBeanDefinition(key); + protocolSet.add(def); + } + } + } + + ApplicationConfigValidator appConfigValidator = new ApplicationConfigValidator(); + appConfigValidator.setDefinitionList(appNameList); + appConfigValidator.validate(); + + if (protocolList.size() == 0) { + throw new FatalBeanException("There is no protocol config specified!"); + } + + for (Iterator itr = protocolSet.iterator(); itr.hasNext();) { + BeanDefinition beanDef = itr.next(); + ProtocolConfigValidator validator = new ProtocolConfigValidator(); + validator.setBeanDefinition(beanDef); + validator.validate(); + } + + for (Iterator itr = providerSet.iterator(); itr.hasNext();) { + BeanDefinition beanDef = itr.next(); + ProviderConfigValidator validator = new ProviderConfigValidator(); + validator.setBeanDefinition(beanDef); + validator.validate(); + } + + for (Iterator> itr = serviceMap.entrySet().iterator(); itr.hasNext();) { + Map.Entry entry = itr.next(); + ServiceConfigValidator validator = new ServiceConfigValidator(); + validator.setBeanName(entry.getKey()); + validator.setBeanDefinition(entry.getValue()); + validator.validate(); // retries, loadbalance, cluster, filter, group + } + + for (Iterator> itr = referenceMap.entrySet().iterator(); itr.hasNext();) { + Map.Entry entry = itr.next(); + ReferenceConfigValidator validator = new ReferenceConfigValidator(); + validator.setBeanName(entry.getKey()); + validator.setBeanDefinition(entry.getValue()); + validator.validate(); // retries, loadbalance, cluster, filter + } + } + +} diff --git a/bytejta-supports/src/main/java/org/bytesoft/bytejta/supports/dubbo/DubboConfigValidator.java b/bytejta-supports/src/main/java/org/bytesoft/bytejta/supports/dubbo/DubboConfigValidator.java new file mode 100644 index 0000000..fda94c0 --- /dev/null +++ b/bytejta-supports/src/main/java/org/bytesoft/bytejta/supports/dubbo/DubboConfigValidator.java @@ -0,0 +1,24 @@ +/** + * Copyright 2014-2016 yangming.liu. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, see . + */ +package org.bytesoft.bytejta.supports.dubbo; + +import org.springframework.beans.BeansException; + +public interface DubboConfigValidator { + + public void validate() throws BeansException; + +} diff --git a/bytejta-supports/src/main/java/org/bytesoft/bytejta/supports/dubbo/validator/ApplicationConfigValidator.java b/bytejta-supports/src/main/java/org/bytesoft/bytejta/supports/dubbo/validator/ApplicationConfigValidator.java new file mode 100644 index 0000000..9ebe560 --- /dev/null +++ b/bytejta-supports/src/main/java/org/bytesoft/bytejta/supports/dubbo/validator/ApplicationConfigValidator.java @@ -0,0 +1,45 @@ +/** + * Copyright 2014-2017 yangming.liu. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, see . + */ +package org.bytesoft.bytejta.supports.dubbo.validator; + +import java.util.List; + +import org.bytesoft.bytejta.supports.dubbo.DubboConfigValidator; +import org.springframework.beans.BeansException; +import org.springframework.beans.FatalBeanException; +import org.springframework.beans.factory.config.BeanDefinition; + +public class ApplicationConfigValidator implements DubboConfigValidator { + + private List definitionList; + + public void validate() throws BeansException { + if (this.definitionList == null || this.definitionList.isEmpty()) { + throw new FatalBeanException("There is no application name specified!"); + } else if (this.definitionList.size() > 1) { + throw new FatalBeanException("There are more than one application name specified!"); + } + } + + public List getDefinitionList() { + return definitionList; + } + + public void setDefinitionList(List definitionList) { + this.definitionList = definitionList; + } + +} diff --git a/bytejta-supports/src/main/java/org/bytesoft/bytejta/supports/dubbo/validator/ProtocolConfigValidator.java b/bytejta-supports/src/main/java/org/bytesoft/bytejta/supports/dubbo/validator/ProtocolConfigValidator.java new file mode 100644 index 0000000..e525feb --- /dev/null +++ b/bytejta-supports/src/main/java/org/bytesoft/bytejta/supports/dubbo/validator/ProtocolConfigValidator.java @@ -0,0 +1,50 @@ +/** + * Copyright 2014-2017 yangming.liu. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, see . + */ +package org.bytesoft.bytejta.supports.dubbo.validator; + +import org.bytesoft.bytejta.supports.dubbo.DubboConfigValidator; +import org.springframework.beans.BeansException; +import org.springframework.beans.FatalBeanException; +import org.springframework.beans.MutablePropertyValues; +import org.springframework.beans.PropertyValue; +import org.springframework.beans.factory.config.BeanDefinition; + +public class ProtocolConfigValidator implements DubboConfigValidator { + + private BeanDefinition beanDefinition; + + public void validate() throws BeansException { + MutablePropertyValues mpv = this.beanDefinition.getPropertyValues(); + PropertyValue pv = mpv.getPropertyValue("port"); + Object value = pv == null ? null : pv.getValue(); + if (pv == null || value == null) { + throw new FatalBeanException( + "The value of the attribute 'port' () must be explicitly specified."); + } else if ("-1".equals(value)) { + throw new FatalBeanException( + "The value of the attribute 'port' () must be explicitly specified and not equal to -1."); + } + } + + public BeanDefinition getBeanDefinition() { + return beanDefinition; + } + + public void setBeanDefinition(BeanDefinition beanDefinition) { + this.beanDefinition = beanDefinition; + } + +} diff --git a/bytejta-supports/src/main/java/org/bytesoft/bytejta/supports/dubbo/validator/ProviderConfigValidator.java b/bytejta-supports/src/main/java/org/bytesoft/bytejta/supports/dubbo/validator/ProviderConfigValidator.java new file mode 100644 index 0000000..415557d --- /dev/null +++ b/bytejta-supports/src/main/java/org/bytesoft/bytejta/supports/dubbo/validator/ProviderConfigValidator.java @@ -0,0 +1,36 @@ +/** + * Copyright 2014-2017 yangming.liu. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, see . + */ +package org.bytesoft.bytejta.supports.dubbo.validator; + +import org.bytesoft.bytejta.supports.dubbo.DubboConfigValidator; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanDefinition; + +public class ProviderConfigValidator implements DubboConfigValidator { + private BeanDefinition beanDefinition; + + public void validate() throws BeansException { + } + + public BeanDefinition getBeanDefinition() { + return beanDefinition; + } + + public void setBeanDefinition(BeanDefinition beanDefinition) { + this.beanDefinition = beanDefinition; + } + +} diff --git a/bytejta-supports/src/main/java/org/bytesoft/bytejta/supports/dubbo/validator/ReferenceConfigValidator.java b/bytejta-supports/src/main/java/org/bytesoft/bytejta/supports/dubbo/validator/ReferenceConfigValidator.java new file mode 100644 index 0000000..e463e5f --- /dev/null +++ b/bytejta-supports/src/main/java/org/bytesoft/bytejta/supports/dubbo/validator/ReferenceConfigValidator.java @@ -0,0 +1,119 @@ +/** + * Copyright 2014-2017 yangming.liu. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, see . + */ +package org.bytesoft.bytejta.supports.dubbo.validator; + +import java.lang.reflect.Method; + +import org.bytesoft.bytejta.supports.dubbo.DubboConfigValidator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeansException; +import org.springframework.beans.FatalBeanException; +import org.springframework.beans.MutablePropertyValues; +import org.springframework.beans.PropertyValue; +import org.springframework.beans.factory.config.BeanDefinition; + +import com.alibaba.dubbo.remoting.RemotingException; + +public class ReferenceConfigValidator implements DubboConfigValidator { + static final Logger logger = LoggerFactory.getLogger(ReferenceConfigValidator.class); + + private String beanName; + private BeanDefinition beanDefinition; + + public void validate() throws BeansException { + MutablePropertyValues mpv = this.beanDefinition.getPropertyValues(); + PropertyValue group = mpv.getPropertyValue("group"); + PropertyValue retries = mpv.getPropertyValue("retries"); + PropertyValue loadbalance = mpv.getPropertyValue("loadbalance"); + PropertyValue cluster = mpv.getPropertyValue("cluster"); + PropertyValue filter = mpv.getPropertyValue("filter"); + + if (group == null || group.getValue() == null // + || ("org.bytesoft.bytejta".equals(group.getValue()) + || String.valueOf(group.getValue()).startsWith("org.bytesoft.bytejta-")) == false) { + throw new FatalBeanException(String.format( + "The value of attr 'group'(beanId= %s) should be 'org.bytesoft.bytejta' or starts with 'org.bytesoft.bytejta-'.", + this.beanName)); + } else if (retries == null || retries.getValue() == null || "0".equals(retries.getValue()) == false) { + throw new FatalBeanException( + String.format("The value of attr 'retries'(beanId= %s) should be '0'.", this.beanName)); + } else if (loadbalance == null || loadbalance.getValue() == null + || "transaction".equals(loadbalance.getValue()) == false) { + throw new FatalBeanException( + String.format("The value of attr 'loadbalance'(beanId= %s) should be 'transaction'.", this.beanName)); + } else if (cluster == null || cluster.getValue() == null || "failfast".equals(cluster.getValue()) == false) { + throw new FatalBeanException( + String.format("The value of attribute 'cluster' (beanId= %s) must be 'failfast'.", this.beanName)); + } else if (filter == null || filter.getValue() == null || "transaction".equals(filter.getValue()) == false) { + throw new FatalBeanException( + String.format("The value of attr 'filter'(beanId= %s) should be 'transaction'.", this.beanName)); + } + + PropertyValue pv = mpv.getPropertyValue("interface"); + String clazzName = String.valueOf(pv.getValue()); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + + Class clazz = null; + try { + clazz = cl.loadClass(clazzName); + } catch (Exception ex) { + throw new FatalBeanException(String.format("Cannot load class %s.", clazzName)); + } + + Method[] methodArray = clazz.getMethods(); + for (int i = 0; i < methodArray.length; i++) { + Method method = methodArray[i]; + boolean declared = false; + Class[] exceptionTypeArray = method.getExceptionTypes(); + for (int j = 0; j < exceptionTypeArray.length; j++) { + Class exceptionType = exceptionTypeArray[j]; + if (RemotingException.class.isAssignableFrom(exceptionType)) { + declared = true; + break; + } + } + + if (declared == false) { + // throw new FatalBeanException(String.format( + // "The remote call method(%s) must be declared to throw a remote exception: + // org.bytesoft.compensable.RemotingException!", + // method)); + logger.warn("The remote call method({}) should be declared to throw a remote exception: {}!", method, + RemotingException.class.getName()); + } + + } + + } + + public String getBeanName() { + return beanName; + } + + public void setBeanName(String beanName) { + this.beanName = beanName; + } + + public BeanDefinition getBeanDefinition() { + return beanDefinition; + } + + public void setBeanDefinition(BeanDefinition beanDefinition) { + this.beanDefinition = beanDefinition; + } + +} diff --git a/bytejta-supports/src/main/java/org/bytesoft/bytejta/supports/dubbo/validator/ServiceConfigValidator.java b/bytejta-supports/src/main/java/org/bytesoft/bytejta/supports/dubbo/validator/ServiceConfigValidator.java new file mode 100644 index 0000000..775d123 --- /dev/null +++ b/bytejta-supports/src/main/java/org/bytesoft/bytejta/supports/dubbo/validator/ServiceConfigValidator.java @@ -0,0 +1,79 @@ +/** + * Copyright 2014-2017 yangming.liu. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, see . + */ +package org.bytesoft.bytejta.supports.dubbo.validator; + +import org.bytesoft.bytejta.supports.dubbo.DubboConfigValidator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeansException; +import org.springframework.beans.FatalBeanException; +import org.springframework.beans.MutablePropertyValues; +import org.springframework.beans.PropertyValue; +import org.springframework.beans.factory.config.BeanDefinition; + +public class ServiceConfigValidator implements DubboConfigValidator { + static final Logger logger = LoggerFactory.getLogger(ServiceConfigValidator.class); + + private String beanName; + private BeanDefinition beanDefinition; + + public void validate() throws BeansException { + MutablePropertyValues mpv = this.beanDefinition.getPropertyValues(); + PropertyValue retries = mpv.getPropertyValue("retries"); + PropertyValue loadbalance = mpv.getPropertyValue("loadbalance"); + PropertyValue cluster = mpv.getPropertyValue("cluster"); + PropertyValue filter = mpv.getPropertyValue("filter"); + PropertyValue group = mpv.getPropertyValue("group"); + + if (retries == null || retries.getValue() == null || "0".equals(retries.getValue()) == false) { + throw new FatalBeanException( + String.format("The value of attr 'retries'(beanId= %s) should be '0'.", this.beanName)); + } else if (loadbalance == null || loadbalance.getValue() == null + || "transaction".equals(loadbalance.getValue()) == false) { + throw new FatalBeanException( + String.format("The value of attr 'loadbalance'(beanId= %s) should be 'transaction'.", this.beanName)); + } else if (cluster == null || cluster.getValue() == null || "failfast".equals(cluster.getValue()) == false) { + throw new FatalBeanException( + String.format("The value of attribute 'cluster' (beanId= %s) must be 'failfast'.", this.beanName)); + } else if (filter == null || filter.getValue() == null || "transaction".equals(filter.getValue()) == false) { + throw new FatalBeanException( + String.format("The value of attr 'filter'(beanId= %s) should be 'transaction'.", this.beanName)); + } else if (group == null || group.getValue() == null // + || ("org.bytesoft.bytejta".equals(group.getValue()) + || String.valueOf(group.getValue()).startsWith("org.bytesoft.bytejta-")) == false) { + throw new FatalBeanException(String.format( + "The value of attr 'group'(beanId= %s) should be 'org.bytesoft.bytejta' or starts with 'org.bytesoft.bytejta-'.", + this.beanName)); + } + } + + public String getBeanName() { + return beanName; + } + + public void setBeanName(String beanName) { + this.beanName = beanName; + } + + public BeanDefinition getBeanDefinition() { + return beanDefinition; + } + + public void setBeanDefinition(BeanDefinition beanDefinition) { + this.beanDefinition = beanDefinition; + } + +} diff --git a/bytejta-supports/src/main/java/org/bytesoft/bytejta/supports/spring/TransactionManagerPostProcessor.java b/bytejta-supports/src/main/java/org/bytesoft/bytejta/supports/spring/TransactionManagerPostProcessor.java new file mode 100644 index 0000000..da3ea43 --- /dev/null +++ b/bytejta-supports/src/main/java/org/bytesoft/bytejta/supports/spring/TransactionManagerPostProcessor.java @@ -0,0 +1,93 @@ +/** + * Copyright 2014-2017 yangming.liu. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, see . + */ +package org.bytesoft.bytejta.supports.spring; + +import java.util.ArrayList; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeansException; +import org.springframework.beans.FatalBeanException; +import org.springframework.beans.MutablePropertyValues; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.BeanFactoryPostProcessor; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.beans.factory.config.RuntimeBeanReference; + +public class TransactionManagerPostProcessor implements BeanFactoryPostProcessor { + static final Logger logger = LoggerFactory.getLogger(TransactionManagerPostProcessor.class); + + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + + String transactionManagerBeanName = null; + String userTransactionBeanName = null; + String jtaTransactionManagerBeanName = null; + final List beanNameList = new ArrayList(); + + String[] beanNameArray = beanFactory.getBeanDefinitionNames(); + for (int i = 0; i < beanNameArray.length; i++) { + String beanName = beanNameArray[i]; + BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName); + String beanClassName = beanDef.getBeanClassName(); + + Class beanClass = null; + try { + beanClass = cl.loadClass(beanClassName); + } catch (Exception ex) { + logger.debug("Cannot load class {}, beanId= {}!", beanClassName, beanName, ex); + continue; + } + + if (org.bytesoft.bytejta.supports.jdbc.LocalXADataSource.class.equals(beanClass)) { + beanNameList.add(beanName); + } else if (org.bytesoft.bytejta.UserTransactionImpl.class.equals(beanClass)) { + beanNameList.add(beanName); + userTransactionBeanName = beanName; + } else if (org.bytesoft.bytejta.TransactionManagerImpl.class.equals(beanClass)) { + transactionManagerBeanName = beanName; + } else if (org.springframework.transaction.jta.JtaTransactionManager.class.equals(beanClass)) { + beanNameList.add(beanName); + jtaTransactionManagerBeanName = beanName; + } + + } + + if (transactionManagerBeanName == null) { + throw new FatalBeanException("No configuration of class org.bytesoft.bytetcc.TransactionManagerImpl was found."); + } + + if (jtaTransactionManagerBeanName == null) { + throw new FatalBeanException( + "No configuration of org.springframework.transaction.jta.JtaTransactionManager was found."); + } + + for (int i = 0; i < beanNameList.size(); i++) { + String beanName = beanNameList.get(i); + BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName); + MutablePropertyValues mpv = beanDef.getPropertyValues(); + RuntimeBeanReference beanRef = new RuntimeBeanReference(transactionManagerBeanName); + mpv.addPropertyValue("transactionManager", beanRef); + } + + BeanDefinition jtaTransactionManagerBeanDef = beanFactory.getBeanDefinition(jtaTransactionManagerBeanName); + MutablePropertyValues jtaTransactionManagerMPV = jtaTransactionManagerBeanDef.getPropertyValues(); + RuntimeBeanReference userTransactionBeanRef = new RuntimeBeanReference(userTransactionBeanName); + jtaTransactionManagerMPV.addPropertyValue("userTransaction", userTransactionBeanRef); + } + +} diff --git a/bytejta-supports/src/main/resources/bytejta-all.xml b/bytejta-supports/src/main/resources/bytejta-all.xml index 61f6cbd..103cfdf 100644 --- a/bytejta-supports/src/main/resources/bytejta-all.xml +++ b/bytejta-supports/src/main/resources/bytejta-all.xml @@ -11,7 +11,8 @@ http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> - + + diff --git a/bytejta-supports/src/main/resources/bytejta.xml b/bytejta-supports/src/main/resources/bytejta-core.xml similarity index 93% rename from bytejta-supports/src/main/resources/bytejta.xml rename to bytejta-supports/src/main/resources/bytejta-core.xml index 59ba672..247d81b 100644 --- a/bytejta-supports/src/main/resources/bytejta.xml +++ b/bytejta-supports/src/main/resources/bytejta-core.xml @@ -14,9 +14,11 @@ The bytejta transaction manager module - + + + diff --git a/bytejta-supports/src/main/resources/bytejta-dubbo.xml b/bytejta-supports/src/main/resources/bytejta-dubbo.xml new file mode 100644 index 0000000..e9370c6 --- /dev/null +++ b/bytejta-supports/src/main/resources/bytejta-dubbo.xml @@ -0,0 +1,20 @@ + + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 6087359..d128c8e 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.bytesoft bytejta-parent - 0.3.0-RC4 + 0.3.0-RC5 pom bytejta-parent ByteJTA is a XA-complicant transaction manager.