revert from 2.2.0 by chao.liuc
git-svn-id: http://code.alibabatech.com/svn/dubbo/trunk@1845 1a56cb94-b969-4eaa-88fa-be21384802f2
This commit is contained in:
parent
84644d0ab0
commit
9cf1788989
|
|
@ -15,10 +15,6 @@
|
|||
*/
|
||||
package com.alibaba.dubbo.rpc.cluster.configurator;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.alibaba.dubbo.common.Constants;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.rpc.cluster.Configurator;
|
||||
|
|
@ -44,33 +40,8 @@ public abstract class AbstractConfigurator implements Configurator {
|
|||
}
|
||||
|
||||
public URL configure(URL url) {
|
||||
if (configuratorUrl == null || configuratorUrl.getHost() == null
|
||||
|| url == null || url.getHost() == null) {
|
||||
return url;
|
||||
}
|
||||
if (Constants.ANYHOST_VALUE.equals(configuratorUrl.getHost())
|
||||
|| url.getHost().equals(configuratorUrl.getHost())) {
|
||||
String configApplication = configuratorUrl.getParameter(Constants.APPLICATION_KEY, configuratorUrl.getUsername());
|
||||
String currentApplication = url.getParameter(Constants.APPLICATION_KEY, url.getUsername());
|
||||
if (configApplication == null || Constants.ANY_VALUE.equals(configApplication)
|
||||
|| configApplication.equals(currentApplication)) {
|
||||
if (configuratorUrl.getPort() == 0 || url.getPort() == configuratorUrl.getPort()) {
|
||||
Set<String> condtionKeys = new HashSet<String>();
|
||||
for (Map.Entry<String, String> entry : configuratorUrl.getParameters().entrySet()) {
|
||||
String key = entry.getKey();
|
||||
String value = entry.getValue();
|
||||
if (key.startsWith("~") || Constants.APPLICATION_KEY.equals(key)
|
||||
|| Constants.SIDE_KEY.equals(key)) {
|
||||
condtionKeys.add(key);
|
||||
if (value != null && ! Constants.ANY_VALUE.equals(value)
|
||||
&& ! value.equals(url.getParameter(key.startsWith("~") ? key.substring(1) : key))) {
|
||||
return url;
|
||||
}
|
||||
}
|
||||
}
|
||||
return doConfigure(url, configuratorUrl.removeParameters(condtionKeys));
|
||||
}
|
||||
}
|
||||
if (isMatch(getUrl(), url)) {
|
||||
return doConfigure(url);
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
|
@ -81,11 +52,30 @@ public abstract class AbstractConfigurator implements Configurator {
|
|||
}
|
||||
return getUrl().getHost().compareTo(o.getUrl().getHost());
|
||||
}
|
||||
|
||||
protected abstract URL doConfigure(URL currentUrl, URL configUrl);
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(URL.encode("timeout=100"));
|
||||
|
||||
private boolean isMatch(URL configuratorUrl, URL providerUrl) {
|
||||
if (configuratorUrl == null || configuratorUrl.getHost() == null
|
||||
|| providerUrl == null || providerUrl.getHost() == null) {
|
||||
return false;
|
||||
}
|
||||
/*if (! providerUrl.getServiceKey().equals(configuratorUrl.getServiceKey())) {
|
||||
return false;
|
||||
}*/
|
||||
if (Constants.ANYHOST_VALUE.equals(configuratorUrl.getHost())
|
||||
|| providerUrl.getHost().equals(configuratorUrl.getHost())) {
|
||||
String configApplication = configuratorUrl.getParameter(Constants.APPLICATION_KEY, configuratorUrl.getUsername());
|
||||
String providerApplication = providerUrl.getParameter(Constants.APPLICATION_KEY, providerUrl.getUsername());
|
||||
if (configApplication == null || configApplication.equals(providerApplication)) {
|
||||
if (configuratorUrl.getPort() > 0) {
|
||||
return providerUrl.getPort() == configuratorUrl.getPort();
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected abstract URL doConfigure(URL url);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ public class AbsentConfigurator extends AbstractConfigurator {
|
|||
super(url);
|
||||
}
|
||||
|
||||
public URL doConfigure(URL currentUrl, URL configUrl) {
|
||||
return currentUrl.addParametersIfAbsent(configUrl.getParameters());
|
||||
public URL doConfigure(URL url) {
|
||||
return url.addParametersIfAbsent(getUrl().getParameters());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ public class OverrideConfigurator extends AbstractConfigurator {
|
|||
super(url);
|
||||
}
|
||||
|
||||
public URL doConfigure(URL currentUrl, URL configUrl) {
|
||||
return currentUrl.addParameters(configUrl.getParameters());
|
||||
public URL doConfigure(URL providerUrl) {
|
||||
return providerUrl.addParameters(getUrl().getParameters());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -289,10 +289,6 @@ public final class URL implements Serializable {
|
|||
return port;
|
||||
}
|
||||
|
||||
public int getPort(int defaultPort) {
|
||||
return port == 0 ? defaultPort : port;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return port <= 0 ? host : host + ":" + port;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -377,7 +377,7 @@ public class UrlUtils {
|
|||
String providerClassifier = providerUrl.getParameter(Constants.CLASSIFIER_KEY, Constants.ANY_VALUE);
|
||||
return (Constants.ANY_VALUE.equals(consumerGroup) || StringUtils.isEquals(consumerGroup, providerGroup) || StringUtils.isContains(consumerGroup, providerGroup))
|
||||
&& (Constants.ANY_VALUE.equals(consumerVersion) || StringUtils.isEquals(consumerVersion, providerVersion))
|
||||
&& (consumerClassifier == null || Constants.ANY_VALUE.equals(consumerClassifier) || StringUtils.isEquals(consumerClassifier, providerClassifier));
|
||||
&& (Constants.ANY_VALUE.equals(consumerClassifier) || StringUtils.isEquals(consumerClassifier, providerClassifier));
|
||||
}
|
||||
|
||||
public static boolean isMatchGlobPattern(String pattern, String value, URL param) {
|
||||
|
|
|
|||
|
|
@ -20,53 +20,40 @@ import java.lang.reflect.Method;
|
|||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
|
||||
import com.alibaba.dubbo.common.Constants;
|
||||
import com.alibaba.dubbo.common.logger.Logger;
|
||||
import com.alibaba.dubbo.common.logger.LoggerFactory;
|
||||
import com.alibaba.dubbo.common.utils.ConcurrentHashSet;
|
||||
import com.alibaba.dubbo.common.utils.ReflectUtils;
|
||||
import com.alibaba.dubbo.config.AbstractConfig;
|
||||
import com.alibaba.dubbo.config.ApplicationConfig;
|
||||
import com.alibaba.dubbo.config.ConsumerConfig;
|
||||
import com.alibaba.dubbo.config.ModuleConfig;
|
||||
import com.alibaba.dubbo.config.MonitorConfig;
|
||||
import com.alibaba.dubbo.config.ProtocolConfig;
|
||||
import com.alibaba.dubbo.config.ProviderConfig;
|
||||
import com.alibaba.dubbo.config.ReferenceConfig;
|
||||
import com.alibaba.dubbo.config.RegistryConfig;
|
||||
import com.alibaba.dubbo.config.ServiceConfig;
|
||||
import com.alibaba.dubbo.config.annotation.Reference;
|
||||
import com.alibaba.dubbo.config.annotation.Service;
|
||||
|
||||
/**
|
||||
* AnnotationBean
|
||||
* ConsumerBean
|
||||
*
|
||||
* @author william.liangf
|
||||
*/
|
||||
public class AnnotationBean extends AbstractConfig implements DisposableBean, BeanFactoryPostProcessor, BeanPostProcessor, ApplicationContextAware {
|
||||
public class ConsumerBean extends ConsumerConfig implements DisposableBean, BeanPostProcessor, ApplicationContextAware {
|
||||
|
||||
private static final long serialVersionUID = -7582802454287589552L;
|
||||
private static final long serialVersionUID = 1036505745144610573L;
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(Logger.class);
|
||||
private static final Logger logger = LoggerFactory.getLogger(Logger.class);
|
||||
|
||||
private String annotationPackage;
|
||||
private String annotationPackage;
|
||||
|
||||
private String[] annotationPackages;
|
||||
|
||||
private final Set<ServiceConfig<?>> serviceConfigs = new ConcurrentHashSet<ServiceConfig<?>>();
|
||||
private String[] annotationPackages;
|
||||
|
||||
private final ConcurrentMap<String, ReferenceBean<?>> referenceConfigs = new ConcurrentHashMap<String, ReferenceBean<?>>();
|
||||
|
||||
|
|
@ -86,39 +73,7 @@ public class AnnotationBean extends AbstractConfig implements DisposableBean, Be
|
|||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
|
||||
throws BeansException {
|
||||
if (annotationPackage == null || annotationPackage.length() == 0) {
|
||||
return;
|
||||
}
|
||||
if (beanFactory instanceof BeanDefinitionRegistry) {
|
||||
try {
|
||||
// init scanner
|
||||
Class<?> scannerClass = ReflectUtils.forName("org.springframework.context.annotation.ClassPathBeanDefinitionScanner");
|
||||
Object scanner = scannerClass.getConstructor(new Class<?>[] {BeanDefinitionRegistry.class, boolean.class}).newInstance(new Object[] {(BeanDefinitionRegistry) beanFactory, true});
|
||||
// add filter
|
||||
Class<?> filterClass = ReflectUtils.forName("org.springframework.core.type.filter.AnnotationTypeFilter");
|
||||
Object filter = filterClass.getConstructor(Class.class).newInstance(Service.class);
|
||||
Method addIncludeFilter = scannerClass.getMethod("addIncludeFilter", ReflectUtils.forName("org.springframework.core.type.filter.TypeFilter"));
|
||||
addIncludeFilter.invoke(scanner, filter);
|
||||
// scan packages
|
||||
String[] packages = Constants.COMMA_SPLIT_PATTERN.split(annotationPackage);
|
||||
Method scan = scannerClass.getMethod("scan", new Class<?>[]{String[].class});
|
||||
scan.invoke(scanner, new Object[] {packages});
|
||||
} catch (Throwable e) {
|
||||
// spring 2.0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() throws Exception {
|
||||
for (ServiceConfig<?> serviceConfig : serviceConfigs) {
|
||||
try {
|
||||
serviceConfig.unexport();
|
||||
} catch (Throwable e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
for (ReferenceConfig<?> referenceConfig : referenceConfigs.values()) {
|
||||
try {
|
||||
referenceConfig.destroy();
|
||||
|
|
@ -127,108 +82,7 @@ public class AnnotationBean extends AbstractConfig implements DisposableBean, Be
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName)
|
||||
throws BeansException {
|
||||
if (! isMatchPackage(bean)) {
|
||||
return bean;
|
||||
}
|
||||
Service service = bean.getClass().getAnnotation(Service.class);
|
||||
if (service != null) {
|
||||
ServiceBean<Object> serviceConfig = new ServiceBean<Object>(service);
|
||||
if (void.class.equals(service.interfaceClass())
|
||||
&& "".equals(service.interfaceName())) {
|
||||
if (bean.getClass().getInterfaces().length > 0) {
|
||||
serviceConfig.setInterface(bean.getClass().getInterfaces()[0]);
|
||||
} else {
|
||||
throw new IllegalStateException("Failed to export remote service class " + bean.getClass().getName() + ", cause: The @Service undefined interfaceClass or interfaceName, and the service class unimplemented any interfaces.");
|
||||
}
|
||||
}
|
||||
if (applicationContext != null) {
|
||||
serviceConfig.setApplicationContext(applicationContext);
|
||||
if (service.registry() != null && service.registry().length > 0) {
|
||||
List<RegistryConfig> registryConfigs = new ArrayList<RegistryConfig>();
|
||||
for (String registryId : service.registry()) {
|
||||
if (registryId != null && registryId.length() > 0) {
|
||||
registryConfigs.add((RegistryConfig)applicationContext.getBean(registryId, RegistryConfig.class));
|
||||
}
|
||||
}
|
||||
serviceConfig.setRegistries(registryConfigs);
|
||||
}
|
||||
if (service.provider() != null && service.provider().length() > 0) {
|
||||
serviceConfig.setProvider((ProviderConfig)applicationContext.getBean(service.provider(),ProviderConfig.class));
|
||||
}
|
||||
if (service.monitor() != null && service.monitor().length() > 0) {
|
||||
serviceConfig.setMonitor((MonitorConfig)applicationContext.getBean(service.monitor(), MonitorConfig.class));
|
||||
}
|
||||
if (service.application() != null && service.application().length() > 0) {
|
||||
serviceConfig.setApplication((ApplicationConfig)applicationContext.getBean(service.application(), ApplicationConfig.class));
|
||||
}
|
||||
if (service.module() != null && service.module().length() > 0) {
|
||||
serviceConfig.setModule((ModuleConfig)applicationContext.getBean(service.module(), ModuleConfig.class));
|
||||
}
|
||||
if (service.provider() != null && service.provider().length() > 0) {
|
||||
serviceConfig.setProvider((ProviderConfig)applicationContext.getBean(service.provider(), ProviderConfig.class));
|
||||
} else {
|
||||
|
||||
}
|
||||
if (service.protocol() != null && service.protocol().length > 0) {
|
||||
List<ProtocolConfig> protocolConfigs = new ArrayList<ProtocolConfig>();
|
||||
for (String protocolId : service.registry()) {
|
||||
if (protocolId != null && protocolId.length() > 0) {
|
||||
protocolConfigs.add((ProtocolConfig)applicationContext.getBean(protocolId, ProtocolConfig.class));
|
||||
}
|
||||
}
|
||||
serviceConfig.setProtocols(protocolConfigs);
|
||||
}
|
||||
try {
|
||||
serviceConfig.afterPropertiesSet();
|
||||
} catch (RuntimeException e) {
|
||||
throw (RuntimeException) e;
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
serviceConfig.setRef(bean);
|
||||
serviceConfigs.add(serviceConfig);
|
||||
serviceConfig.export();
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName)
|
||||
throws BeansException {
|
||||
if (! isMatchPackage(bean)) {
|
||||
return bean;
|
||||
}
|
||||
Method[] methods = bean.getClass().getMethods();
|
||||
for (Method method : methods) {
|
||||
String name = method.getName();
|
||||
if (name.length() > 3 && name.startsWith("set")
|
||||
&& method.getParameterTypes().length == 1
|
||||
&& Modifier.isPublic(method.getModifiers())
|
||||
&& ! Modifier.isStatic(method.getModifiers())) {
|
||||
try {
|
||||
method.invoke(bean, new Object[] { refer(method.getAnnotation(Reference.class), method.getParameterTypes()[0]) });
|
||||
} catch (Throwable e) {
|
||||
throw new IllegalStateException("Failed to init remote service reference at method " + name + " in class " + bean.getClass().getName() + ", cause: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Field[] fields = bean.getClass().getDeclaredFields();
|
||||
for (Field field : fields) {
|
||||
try {
|
||||
if (! field.isAccessible()) {
|
||||
field.setAccessible(true);
|
||||
}
|
||||
field.set(bean, refer(field.getAnnotation(Reference.class), field.getType()));
|
||||
} catch (Throwable e) {
|
||||
throw new IllegalStateException("Failed to init remote service reference at filed " + field.getName() + " in class " + bean.getClass().getName() + ", cause: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
private Object refer(Reference reference, Class<?> referenceClass) { //method.getParameterTypes()[0]
|
||||
if (reference != null) {
|
||||
String interfaceName;
|
||||
|
|
@ -250,6 +104,7 @@ public class AnnotationBean extends AbstractConfig implements DisposableBean, Be
|
|||
&& referenceClass.isInterface()) {
|
||||
referenceConfig.setInterface(referenceClass);
|
||||
}
|
||||
referenceConfig.setConsumer(this);
|
||||
if (applicationContext != null) {
|
||||
referenceConfig.setApplicationContext(applicationContext);
|
||||
if (reference.registry() != null && reference.registry().length > 0) {
|
||||
|
|
@ -261,9 +116,6 @@ public class AnnotationBean extends AbstractConfig implements DisposableBean, Be
|
|||
}
|
||||
referenceConfig.setRegistries(registryConfigs);
|
||||
}
|
||||
if (reference.consumer() != null && reference.consumer().length() > 0) {
|
||||
referenceConfig.setConsumer((ConsumerConfig)applicationContext.getBean(reference.consumer(), ConsumerConfig.class));
|
||||
}
|
||||
if (reference.monitor() != null && reference.monitor().length() > 0) {
|
||||
referenceConfig.setMonitor((MonitorConfig)applicationContext.getBean(reference.monitor(), MonitorConfig.class));
|
||||
}
|
||||
|
|
@ -292,17 +144,52 @@ public class AnnotationBean extends AbstractConfig implements DisposableBean, Be
|
|||
return null;
|
||||
}
|
||||
|
||||
private boolean isMatchPackage(Object bean) {
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName)
|
||||
throws BeansException {
|
||||
if (annotationPackages == null || annotationPackages.length == 0) {
|
||||
return true;
|
||||
return bean;
|
||||
}
|
||||
String beanClassName = bean.getClass().getName();
|
||||
boolean match = false;
|
||||
for (String pkg : annotationPackages) {
|
||||
if (beanClassName.startsWith(pkg)) {
|
||||
return true;
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
if (! match) {
|
||||
return bean;
|
||||
}
|
||||
Method[] methods = bean.getClass().getMethods();
|
||||
for (Method method : methods) {
|
||||
String name = method.getName();
|
||||
if (name.length() > 3 && name.startsWith("set")
|
||||
&& method.getParameterTypes().length == 1
|
||||
&& Modifier.isPublic(method.getModifiers())
|
||||
&& ! Modifier.isStatic(method.getModifiers())) {
|
||||
try {
|
||||
method.invoke(bean, new Object[] { refer(method.getAnnotation(Reference.class), method.getParameterTypes()[0]) });
|
||||
} catch (Throwable e) {
|
||||
throw new IllegalStateException("Failed to init remote service reference at method " + name + " in class " + beanClassName + ", cause: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Field[] fields = bean.getClass().getDeclaredFields();
|
||||
for (Field field : fields) {
|
||||
try {
|
||||
if (! field.isAccessible()) {
|
||||
field.setAccessible(true);
|
||||
}
|
||||
field.set(bean, refer(field.getAnnotation(Reference.class), field.getType()));
|
||||
} catch (Throwable e) {
|
||||
throw new IllegalStateException("Failed to init remote service reference at filed " + field.getName() + " in class " + beanClassName + ", cause: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName)
|
||||
throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
* Copyright 1999-2012 Alibaba Group.
|
||||
*
|
||||
* Licensed 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.alibaba.dubbo.config.spring;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
|
||||
import org.springframework.core.type.filter.AnnotationTypeFilter;
|
||||
|
||||
import com.alibaba.dubbo.common.Constants;
|
||||
import com.alibaba.dubbo.common.logger.Logger;
|
||||
import com.alibaba.dubbo.common.logger.LoggerFactory;
|
||||
import com.alibaba.dubbo.common.utils.ConcurrentHashSet;
|
||||
import com.alibaba.dubbo.config.ApplicationConfig;
|
||||
import com.alibaba.dubbo.config.ModuleConfig;
|
||||
import com.alibaba.dubbo.config.MonitorConfig;
|
||||
import com.alibaba.dubbo.config.ProtocolConfig;
|
||||
import com.alibaba.dubbo.config.ProviderConfig;
|
||||
import com.alibaba.dubbo.config.RegistryConfig;
|
||||
import com.alibaba.dubbo.config.ServiceConfig;
|
||||
import com.alibaba.dubbo.config.annotation.Service;
|
||||
|
||||
/**
|
||||
* ProviderBean
|
||||
*
|
||||
* @author william.liangf
|
||||
*/
|
||||
public class ProviderBean extends ProviderConfig implements DisposableBean, BeanFactoryPostProcessor, BeanPostProcessor, ApplicationContextAware {
|
||||
|
||||
private static final long serialVersionUID = -849195232233637441L;
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(Logger.class);
|
||||
|
||||
private String annotationPackage;
|
||||
|
||||
private final Set<ServiceConfig<?>> serviceConfigs = new ConcurrentHashSet<ServiceConfig<?>>();
|
||||
|
||||
public String getPackage() {
|
||||
return annotationPackage;
|
||||
}
|
||||
|
||||
public void setPackage(String annotationPackage) {
|
||||
this.annotationPackage = annotationPackage;
|
||||
}
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
|
||||
throws BeansException {
|
||||
if (annotationPackage == null || annotationPackage.length() == 0) {
|
||||
return;
|
||||
}
|
||||
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner((DefaultListableBeanFactory) beanFactory);
|
||||
scanner.addIncludeFilter(new AnnotationTypeFilter(Service.class));
|
||||
String[] pkgs = Constants.COMMA_SPLIT_PATTERN.split(annotationPackage);
|
||||
for (String pkg : pkgs) {
|
||||
scanner.scan(pkg);
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() throws Exception {
|
||||
for (ServiceConfig<?> serviceConfig : serviceConfigs) {
|
||||
try {
|
||||
serviceConfig.unexport();
|
||||
} catch (Throwable e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName)
|
||||
throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName)
|
||||
throws BeansException {
|
||||
if (annotationPackage == null || annotationPackage.length() == 0) {
|
||||
return bean;
|
||||
}
|
||||
Service service = bean.getClass().getAnnotation(Service.class);
|
||||
if (service != null) {
|
||||
ServiceBean<Object> serviceConfig = new ServiceBean<Object>(service);
|
||||
if (void.class.equals(service.interfaceClass())
|
||||
&& "".equals(service.interfaceName())) {
|
||||
if (bean.getClass().getInterfaces().length > 0) {
|
||||
serviceConfig.setInterface(bean.getClass().getInterfaces()[0]);
|
||||
} else {
|
||||
throw new IllegalStateException("Failed to export remote service class " + bean.getClass().getName() + ", cause: The @Service undefined interfaceClass or interfaceName, and the service class unimplemented any interfaces.");
|
||||
}
|
||||
}
|
||||
serviceConfig.setProvider(this);
|
||||
if (applicationContext != null) {
|
||||
serviceConfig.setApplicationContext(applicationContext);
|
||||
if (service.registry() != null && service.registry().length > 0) {
|
||||
List<RegistryConfig> registryConfigs = new ArrayList<RegistryConfig>();
|
||||
for (String registryId : service.registry()) {
|
||||
if (registryId != null && registryId.length() > 0) {
|
||||
registryConfigs.add((RegistryConfig)applicationContext.getBean(registryId, RegistryConfig.class));
|
||||
}
|
||||
}
|
||||
serviceConfig.setRegistries(registryConfigs);
|
||||
}
|
||||
if (service.monitor() != null && service.monitor().length() > 0) {
|
||||
serviceConfig.setMonitor((MonitorConfig)applicationContext.getBean(service.monitor(), MonitorConfig.class));
|
||||
}
|
||||
if (service.application() != null && service.application().length() > 0) {
|
||||
serviceConfig.setApplication((ApplicationConfig)applicationContext.getBean(service.application(), ApplicationConfig.class));
|
||||
}
|
||||
if (service.module() != null && service.module().length() > 0) {
|
||||
serviceConfig.setModule((ModuleConfig)applicationContext.getBean(service.module(), ModuleConfig.class));
|
||||
}
|
||||
if (service.provider() != null && service.provider().length() > 0) {
|
||||
serviceConfig.setProvider((ProviderConfig)applicationContext.getBean(service.provider(), ProviderConfig.class));
|
||||
} else {
|
||||
|
||||
}
|
||||
if (service.protocol() != null && service.protocol().length > 0) {
|
||||
List<ProtocolConfig> protocolConfigs = new ArrayList<ProtocolConfig>();
|
||||
for (String protocolId : service.registry()) {
|
||||
if (protocolId != null && protocolId.length() > 0) {
|
||||
protocolConfigs.add((ProtocolConfig)applicationContext.getBean(protocolId, ProtocolConfig.class));
|
||||
}
|
||||
}
|
||||
serviceConfig.setProtocols(protocolConfigs);
|
||||
}
|
||||
try {
|
||||
serviceConfig.afterPropertiesSet();
|
||||
} catch (RuntimeException e) {
|
||||
throw (RuntimeException) e;
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
serviceConfig.setRef(bean);
|
||||
serviceConfigs.add(serviceConfig);
|
||||
serviceConfig.export();
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -19,7 +19,6 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
|
@ -76,7 +75,7 @@ public class ReferenceBean<T> extends ReferenceConfig<T> implements FactoryBean,
|
|||
@SuppressWarnings({ "unchecked"})
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if (getConsumer() == null) {
|
||||
Map<String, ConsumerConfig> consumerConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ConsumerConfig.class, false, false);
|
||||
Map<String, ConsumerConfig> consumerConfigMap = applicationContext == null ? null : applicationContext.getBeansOfType(ConsumerConfig.class, false, false);
|
||||
if (consumerConfigMap != null && consumerConfigMap.size() > 0) {
|
||||
ConsumerConfig consumerConfig = null;
|
||||
for (ConsumerConfig config : consumerConfigMap.values()) {
|
||||
|
|
@ -94,7 +93,7 @@ public class ReferenceBean<T> extends ReferenceConfig<T> implements FactoryBean,
|
|||
}
|
||||
if (getApplication() == null
|
||||
&& (getConsumer() == null || getConsumer().getApplication() == null)) {
|
||||
Map<String, ApplicationConfig> applicationConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ApplicationConfig.class, false, false);
|
||||
Map<String, ApplicationConfig> applicationConfigMap = applicationContext == null ? null : applicationContext.getBeansOfType(ApplicationConfig.class, false, false);
|
||||
if (applicationConfigMap != null && applicationConfigMap.size() > 0) {
|
||||
ApplicationConfig applicationConfig = null;
|
||||
for (ApplicationConfig config : applicationConfigMap.values()) {
|
||||
|
|
@ -112,7 +111,7 @@ public class ReferenceBean<T> extends ReferenceConfig<T> implements FactoryBean,
|
|||
}
|
||||
if (getModule() == null
|
||||
&& (getConsumer() == null || getConsumer().getModule() == null)) {
|
||||
Map<String, ModuleConfig> moduleConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ModuleConfig.class, false, false);
|
||||
Map<String, ModuleConfig> moduleConfigMap = applicationContext == null ? null : applicationContext.getBeansOfType(ModuleConfig.class, false, false);
|
||||
if (moduleConfigMap != null && moduleConfigMap.size() > 0) {
|
||||
ModuleConfig moduleConfig = null;
|
||||
for (ModuleConfig config : moduleConfigMap.values()) {
|
||||
|
|
@ -131,7 +130,7 @@ public class ReferenceBean<T> extends ReferenceConfig<T> implements FactoryBean,
|
|||
if ((getRegistries() == null || getRegistries().size() == 0)
|
||||
&& (getConsumer() == null || getConsumer().getRegistries() == null || getConsumer().getRegistries().size() == 0)
|
||||
&& (getApplication() == null || getApplication().getRegistries() == null || getApplication().getRegistries().size() == 0)) {
|
||||
Map<String, RegistryConfig> registryConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, RegistryConfig.class, false, false);
|
||||
Map<String, RegistryConfig> registryConfigMap = applicationContext == null ? null : applicationContext.getBeansOfType(RegistryConfig.class, false, false);
|
||||
if (registryConfigMap != null && registryConfigMap.size() > 0) {
|
||||
List<RegistryConfig> registryConfigs = new ArrayList<RegistryConfig>();
|
||||
for (RegistryConfig config : registryConfigMap.values()) {
|
||||
|
|
@ -147,7 +146,7 @@ public class ReferenceBean<T> extends ReferenceConfig<T> implements FactoryBean,
|
|||
if (getMonitor() == null
|
||||
&& (getConsumer() == null || getConsumer().getMonitor() == null)
|
||||
&& (getApplication() == null || getApplication().getMonitor() == null)) {
|
||||
Map<String, MonitorConfig> monitorConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, MonitorConfig.class, false, false);
|
||||
Map<String, MonitorConfig> monitorConfigMap = applicationContext == null ? null : applicationContext.getBeansOfType(MonitorConfig.class, false, false);
|
||||
if (monitorConfigMap != null && monitorConfigMap.size() > 0) {
|
||||
MonitorConfig monitorConfig = null;
|
||||
for (MonitorConfig config : monitorConfigMap.values()) {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
|
@ -122,9 +121,9 @@ public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean
|
|||
@SuppressWarnings({ "unchecked", "deprecation" })
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if (getProvider() == null) {
|
||||
Map<String, ProviderConfig> providerConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProviderConfig.class, false, false);
|
||||
Map<String, ProviderConfig> providerConfigMap = applicationContext == null ? null : applicationContext.getBeansOfType(ProviderConfig.class, false, false);
|
||||
if (providerConfigMap != null && providerConfigMap.size() > 0) {
|
||||
Map<String, ProtocolConfig> protocolConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProtocolConfig.class, false, false);
|
||||
Map<String, ProtocolConfig> protocolConfigMap = applicationContext == null ? null : applicationContext.getBeansOfType(ProtocolConfig.class, false, false);
|
||||
if ((protocolConfigMap == null || protocolConfigMap.size() == 0)
|
||||
&& providerConfigMap.size() > 1) { // 兼容旧版本
|
||||
List<ProviderConfig> providerConfigs = new ArrayList<ProviderConfig>();
|
||||
|
|
@ -154,7 +153,7 @@ public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean
|
|||
}
|
||||
if (getApplication() == null
|
||||
&& (getProvider() == null || getProvider().getApplication() == null)) {
|
||||
Map<String, ApplicationConfig> applicationConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ApplicationConfig.class, false, false);
|
||||
Map<String, ApplicationConfig> applicationConfigMap = applicationContext == null ? null : applicationContext.getBeansOfType(ApplicationConfig.class, false, false);
|
||||
if (applicationConfigMap != null && applicationConfigMap.size() > 0) {
|
||||
ApplicationConfig applicationConfig = null;
|
||||
for (ApplicationConfig config : applicationConfigMap.values()) {
|
||||
|
|
@ -172,7 +171,7 @@ public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean
|
|||
}
|
||||
if (getModule() == null
|
||||
&& (getProvider() == null || getProvider().getModule() == null)) {
|
||||
Map<String, ModuleConfig> moduleConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ModuleConfig.class, false, false);
|
||||
Map<String, ModuleConfig> moduleConfigMap = applicationContext == null ? null : applicationContext.getBeansOfType(ModuleConfig.class, false, false);
|
||||
if (moduleConfigMap != null && moduleConfigMap.size() > 0) {
|
||||
ModuleConfig moduleConfig = null;
|
||||
for (ModuleConfig config : moduleConfigMap.values()) {
|
||||
|
|
@ -191,7 +190,7 @@ public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean
|
|||
if ((getRegistries() == null || getRegistries().size() == 0)
|
||||
&& (getProvider() == null || getProvider().getRegistries() == null || getProvider().getRegistries().size() == 0)
|
||||
&& (getApplication() == null || getApplication().getRegistries() == null || getApplication().getRegistries().size() == 0)) {
|
||||
Map<String, RegistryConfig> registryConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, RegistryConfig.class, false, false);
|
||||
Map<String, RegistryConfig> registryConfigMap = applicationContext == null ? null : applicationContext.getBeansOfType(RegistryConfig.class, false, false);
|
||||
if (registryConfigMap != null && registryConfigMap.size() > 0) {
|
||||
List<RegistryConfig> registryConfigs = new ArrayList<RegistryConfig>();
|
||||
for (RegistryConfig config : registryConfigMap.values()) {
|
||||
|
|
@ -207,7 +206,7 @@ public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean
|
|||
if (getMonitor() == null
|
||||
&& (getProvider() == null || getProvider().getMonitor() == null)
|
||||
&& (getApplication() == null || getApplication().getMonitor() == null)) {
|
||||
Map<String, MonitorConfig> monitorConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, MonitorConfig.class, false, false);
|
||||
Map<String, MonitorConfig> monitorConfigMap = applicationContext == null ? null : applicationContext.getBeansOfType(MonitorConfig.class, false, false);
|
||||
if (monitorConfigMap != null && monitorConfigMap.size() > 0) {
|
||||
MonitorConfig monitorConfig = null;
|
||||
for (MonitorConfig config : monitorConfigMap.values()) {
|
||||
|
|
@ -225,7 +224,7 @@ public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean
|
|||
}
|
||||
if ((getProtocols() == null || getProtocols().size() == 0)
|
||||
&& (getProvider() == null || getProvider().getProtocols() == null || getProvider().getProtocols().size() == 0)) {
|
||||
Map<String, ProtocolConfig> protocolConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProtocolConfig.class, false, false);
|
||||
Map<String, ProtocolConfig> protocolConfigMap = applicationContext == null ? null : applicationContext.getBeansOfType(ProtocolConfig.class, false, false);
|
||||
if (protocolConfigMap != null && protocolConfigMap.size() > 0) {
|
||||
List<ProtocolConfig> protocolConfigs = new ArrayList<ProtocolConfig>();
|
||||
for (ProtocolConfig config : protocolConfigMap.values()) {
|
||||
|
|
|
|||
|
|
@ -47,8 +47,9 @@ import com.alibaba.dubbo.config.ArgumentConfig;
|
|||
import com.alibaba.dubbo.config.MethodConfig;
|
||||
import com.alibaba.dubbo.config.MonitorConfig;
|
||||
import com.alibaba.dubbo.config.ProtocolConfig;
|
||||
import com.alibaba.dubbo.config.ProviderConfig;
|
||||
import com.alibaba.dubbo.config.RegistryConfig;
|
||||
import com.alibaba.dubbo.config.spring.ConsumerBean;
|
||||
import com.alibaba.dubbo.config.spring.ProviderBean;
|
||||
import com.alibaba.dubbo.config.spring.ReferenceBean;
|
||||
import com.alibaba.dubbo.config.spring.ServiceBean;
|
||||
import com.alibaba.dubbo.rpc.Protocol;
|
||||
|
|
@ -126,9 +127,9 @@ public class DubboBeanDefinitionParser implements BeanDefinitionParser {
|
|||
parseProperties(element.getChildNodes(), classDefinition);
|
||||
beanDefinition.getPropertyValues().addPropertyValue("ref", new BeanDefinitionHolder(classDefinition, id + "Impl"));
|
||||
}
|
||||
} else if (ProviderConfig.class.equals(beanClass)) {
|
||||
} else if (ProviderBean.class.equals(beanClass)) {
|
||||
parseNested(element, parserContext, ServiceBean.class, true, "service", "provider", id, beanDefinition);
|
||||
} else if (ProviderConfig.class.equals(beanClass)) {
|
||||
} else if (ConsumerBean.class.equals(beanClass)) {
|
||||
parseNested(element, parserContext, ReferenceBean.class, false, "reference", "consumer", id, beanDefinition);
|
||||
}
|
||||
Set<String> props = new HashSet<String>();
|
||||
|
|
|
|||
|
|
@ -19,13 +19,12 @@ import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
|
|||
|
||||
import com.alibaba.dubbo.common.Version;
|
||||
import com.alibaba.dubbo.config.ApplicationConfig;
|
||||
import com.alibaba.dubbo.config.ConsumerConfig;
|
||||
import com.alibaba.dubbo.config.ModuleConfig;
|
||||
import com.alibaba.dubbo.config.MonitorConfig;
|
||||
import com.alibaba.dubbo.config.ProtocolConfig;
|
||||
import com.alibaba.dubbo.config.ProviderConfig;
|
||||
import com.alibaba.dubbo.config.RegistryConfig;
|
||||
import com.alibaba.dubbo.config.spring.AnnotationBean;
|
||||
import com.alibaba.dubbo.config.spring.ConsumerBean;
|
||||
import com.alibaba.dubbo.config.spring.ProviderBean;
|
||||
import com.alibaba.dubbo.config.spring.ReferenceBean;
|
||||
import com.alibaba.dubbo.config.spring.ServiceBean;
|
||||
|
||||
|
|
@ -40,17 +39,16 @@ public class DubboNamespaceHandler extends NamespaceHandlerSupport {
|
|||
Version.checkDuplicate(DubboNamespaceHandler.class);
|
||||
}
|
||||
|
||||
public void init() {
|
||||
registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));
|
||||
public void init() {
|
||||
registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));
|
||||
registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true));
|
||||
registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true));
|
||||
registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));
|
||||
registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class, true));
|
||||
registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class, true));
|
||||
registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true));
|
||||
registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true));
|
||||
registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false));
|
||||
registerBeanDefinitionParser("annotation", new DubboBeanDefinitionParser(AnnotationBean.class, true));
|
||||
}
|
||||
registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true));
|
||||
registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));
|
||||
registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderBean.class, true));
|
||||
registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerBean.class, true));
|
||||
registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true));
|
||||
registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true));
|
||||
registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -657,6 +657,11 @@
|
|||
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element ref="parameter" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="package" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[ Scan the consumer @Reference annotation package. ]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="default" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[ Is default. ]]></xsd:documentation>
|
||||
|
|
@ -988,6 +993,11 @@
|
|||
<xsd:documentation><![CDATA[ The provider shutdown wait time. ]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="package" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[ Scan the provider @Service annotation package. ]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="default" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[ Is default. ]]></xsd:documentation>
|
||||
|
|
@ -1041,25 +1051,6 @@
|
|||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="annotationType">
|
||||
<xsd:attribute name="id" type="xsd:ID">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[ The unique identifier for a bean. ]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="package" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[ The scan package. ]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:element name="annotation" type="annotationType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[ The annotation config ]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="application" type="applicationType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[ The application config ]]></xsd:documentation>
|
||||
|
|
|
|||
|
|
@ -22,8 +22,10 @@
|
|||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
|
||||
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
|
||||
|
||||
<context:component-scan base-package="com.alibaba.dubbo.config.spring.annotation.consumer" />
|
||||
|
||||
<dubbo:application name="annotation-consumer" />
|
||||
<dubbo:registry address="127.0.0.1:4548" />
|
||||
<dubbo:annotation package="com.alibaba.dubbo.config.spring.annotation.consumer" />
|
||||
<dubbo:consumer package="com.alibaba.dubbo.config.spring.annotation.consumer" />
|
||||
|
||||
</beans>
|
||||
|
|
@ -22,6 +22,6 @@
|
|||
|
||||
<dubbo:application name="annotation-provider" />
|
||||
<dubbo:registry address="127.0.0.1:4548" />
|
||||
<dubbo:annotation package="com.alibaba.dubbo.config.spring.annotation.provider" />
|
||||
<dubbo:provider package="com.alibaba.dubbo.config.spring.annotation.provider" />
|
||||
|
||||
</beans>
|
||||
|
|
@ -26,9 +26,6 @@
|
|||
<packaging>pom</packaging>
|
||||
<name>${project.artifactId}</name>
|
||||
<description>The config module of dubbo project</description>
|
||||
<properties>
|
||||
<skip_maven_deploy>true</skip_maven_deploy>
|
||||
</properties>
|
||||
<modules>
|
||||
<module>dubbo-config-api</module>
|
||||
<module>dubbo-config-spring</module>
|
||||
|
|
|
|||
|
|
@ -26,9 +26,6 @@
|
|||
<packaging>pom</packaging>
|
||||
<name>${project.artifactId}</name>
|
||||
<description>The container module of dubbo project</description>
|
||||
<properties>
|
||||
<skip_maven_deploy>true</skip_maven_deploy>
|
||||
</properties>
|
||||
<modules>
|
||||
<module>dubbo-container-api</module>
|
||||
<module>dubbo-container-spring</module>
|
||||
|
|
|
|||
|
|
@ -84,31 +84,6 @@
|
|||
<artifactId>dubbo-rpc-hessian</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>dubbo-rpc-http</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>dubbo-rpc-webservice</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>dubbo-rpc-thrift</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>dubbo-rpc-memcached</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>dubbo-rpc-redis</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>dubbo-registry-default</artifactId>
|
||||
|
|
|
|||
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* Copyright 1999-2012 Alibaba Group.
|
||||
*
|
||||
* Licensed 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.alibaba.dubbo.examples.annotation;
|
||||
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
import com.alibaba.dubbo.examples.annotation.action.AnnotationAction;
|
||||
|
||||
/**
|
||||
* CallbackConsumer
|
||||
*
|
||||
* @author william.liangf
|
||||
*/
|
||||
public class AnnotationConsumer {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String config = AnnotationConsumer.class.getPackage().getName().replace('.', '/') + "/annotation-consumer.xml";
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(config);
|
||||
context.start();
|
||||
final AnnotationAction annotationAction = (AnnotationAction)context.getBean("annotationAction");
|
||||
String hello = annotationAction.doSayHello("world");
|
||||
System.out.println("result :" + hello);
|
||||
System.in.read();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* Copyright 1999-2012 Alibaba Group.
|
||||
*
|
||||
* Licensed 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.alibaba.dubbo.examples.annotation;
|
||||
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
/**
|
||||
* MergeProvider
|
||||
*
|
||||
* @author william.liangf
|
||||
*/
|
||||
public class AnnotationProvider {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String config = AnnotationProvider.class.getPackage().getName().replace('.', '/') + "/annotation-provider.xml";
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(config);
|
||||
context.start();
|
||||
System.in.read();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
* Copyright 1999-2012 Alibaba Group.
|
||||
*
|
||||
* Licensed 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.alibaba.dubbo.examples.annotation.action;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.alibaba.dubbo.config.annotation.Reference;
|
||||
import com.alibaba.dubbo.examples.annotation.api.AnnotationService;
|
||||
|
||||
/**
|
||||
* AnnotationAction
|
||||
*
|
||||
* @author william.liangf
|
||||
*/
|
||||
@Component("annotationAction")
|
||||
public class AnnotationAction {
|
||||
|
||||
@Reference
|
||||
private AnnotationService annotationService;
|
||||
|
||||
public String doSayHello(String name) {
|
||||
return annotationService.sayHello(name);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
- Copyright 1999-2011 Alibaba Group.
|
||||
-
|
||||
- Licensed 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.
|
||||
-->
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
|
||||
|
||||
<dubbo:application name="annotation-consumer" />
|
||||
|
||||
<dubbo:registry address="multicast://224.5.6.7:1234" />
|
||||
|
||||
<dubbo:annotation package="com.alibaba.dubbo.examples.annotation.action" />
|
||||
|
||||
</beans>
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
- Copyright 1999-2011 Alibaba Group.
|
||||
-
|
||||
- Licensed 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.
|
||||
-->
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
|
||||
|
||||
<dubbo:application name="annotation-provider" />
|
||||
|
||||
<dubbo:registry address="multicast://224.5.6.7:1234" />
|
||||
|
||||
<dubbo:protocol name="dubbo" port="20880" />
|
||||
|
||||
<dubbo:annotation package="com.alibaba.dubbo.examples.annotation.impl" />
|
||||
|
||||
</beans>
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* Copyright 1999-2012 Alibaba Group.
|
||||
*
|
||||
* Licensed 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.alibaba.dubbo.examples.annotation.impl;
|
||||
|
||||
import com.alibaba.dubbo.config.annotation.Service;
|
||||
import com.alibaba.dubbo.examples.annotation.api.AnnotationService;
|
||||
|
||||
/**
|
||||
* AsyncServiceImpl
|
||||
*
|
||||
* @author william.liangf
|
||||
*/
|
||||
@Service
|
||||
public class AnnotationServiceImpl implements AnnotationService {
|
||||
|
||||
public String sayHello(String name) {
|
||||
System.out.println("async provider received: " + name);
|
||||
return "annotation: hello, " + name;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* Copyright 1999-2012 Alibaba Group.
|
||||
*
|
||||
* Licensed 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.alibaba.dubbo.examples.memcached;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
/**
|
||||
* GenericConsumer
|
||||
*
|
||||
* @author chao.liuc
|
||||
*/
|
||||
public class MemcachedConsumer {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void main(String[] args) throws Exception {
|
||||
String config = MemcachedConsumer.class.getPackage().getName().replace('.', '/') + "/memcached-consumer.xml";
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(config);
|
||||
context.start();
|
||||
Map<String, Object> cache = (Map<String, Object>) context.getBean("cache");
|
||||
cache.remove("hello");
|
||||
Object value = cache.get("hello");
|
||||
System.out.println(value);
|
||||
if (value != null) {
|
||||
throw new IllegalStateException(value + " != null");
|
||||
}
|
||||
cache.put("hello", "world");
|
||||
value = cache.get("hello");
|
||||
System.out.println(value);
|
||||
if (! "world".equals(value)) {
|
||||
throw new IllegalStateException(value + " != world");
|
||||
}
|
||||
System.in.read();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
- Copyright 1999-2011 Alibaba Group.
|
||||
-
|
||||
- Licensed 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.
|
||||
-->
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
|
||||
|
||||
<dubbo:application name="memcached-consumer" />
|
||||
|
||||
<dubbo:reference id="cache" interface="java.util.Map" url="memcached://10.20.153.10:11211" />
|
||||
|
||||
</beans>
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
* Copyright 1999-2012 Alibaba Group.
|
||||
*
|
||||
* Licensed 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.alibaba.dubbo.examples.redis;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
/**
|
||||
* GenericConsumer
|
||||
*
|
||||
* @author chao.liuc
|
||||
*/
|
||||
public class RedisConsumer {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void main(String[] args) throws Exception {
|
||||
String config = RedisConsumer.class.getPackage().getName().replace('.', '/') + "/redis-consumer.xml";
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(config);
|
||||
context.start();
|
||||
Map<String, Object> cache = (Map<String, Object>) context.getBean("cache");
|
||||
cache.remove("hello");
|
||||
Object value = cache.get("hello");
|
||||
System.out.println(value);
|
||||
if (value != null) {
|
||||
throw new IllegalStateException(value + " != null");
|
||||
}
|
||||
cache.put("hello", "world");
|
||||
value = cache.get("hello");
|
||||
System.out.println(value);
|
||||
if (! "world".equals(value)) {
|
||||
throw new IllegalStateException(value + " != world");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
- Copyright 1999-2011 Alibaba Group.
|
||||
-
|
||||
- Licensed 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.
|
||||
-->
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
|
||||
|
||||
<dubbo:application name="memcached-consumer" />
|
||||
|
||||
<dubbo:reference id="cache" interface="java.util.Map" url="redis://10.20.153.10:6379" />
|
||||
|
||||
</beans>
|
||||
|
|
@ -63,12 +63,12 @@ public class ValidationConsumer {
|
|||
}
|
||||
|
||||
// Delete OK
|
||||
validationService.delete(2, "abc");
|
||||
validationService.delete(2);
|
||||
System.out.println("Validation Delete OK");
|
||||
|
||||
// Delete Error
|
||||
try {
|
||||
validationService.delete(0, "abc");
|
||||
validationService.delete(0);
|
||||
System.err.println("Validation Delete ERROR");
|
||||
} catch (RpcException e) {
|
||||
ConstraintViolationException ve = (ConstraintViolationException)e.getCause();
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ public class ValidationParameter implements Serializable {
|
|||
private static final long serialVersionUID = 7158911668568000392L;
|
||||
|
||||
@NotNull // 不允许为空
|
||||
@Size(min = 2, max = 20) // 长度或大小范围
|
||||
@Size(min = 1, max = 20) // 长度或大小范围
|
||||
private String name;
|
||||
|
||||
@NotNull(groups = ValidationService.Save.class) // 保存时不允许为空,更新时允许为空 ,表示不更新该字段
|
||||
|
|
|
|||
|
|
@ -16,9 +16,6 @@
|
|||
package com.alibaba.dubbo.examples.validation.api;
|
||||
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Pattern;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -33,7 +30,7 @@ public interface ValidationService { // 缺省可按服务接口区分验证场
|
|||
|
||||
@interface Update{} // 与方法同名接口,首字母大写,用于区分验证场景,如:@NotNull(groups = ValidationService.Update.class),可选
|
||||
void update(ValidationParameter parameter);
|
||||
|
||||
void delete(@Min(1) long id, @NotNull @Size(min = 2, max = 16) @Pattern(regexp = "^[a-zA-Z]+$") String operator);
|
||||
|
||||
void delete(@Min(1) long id);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ public class ValidationServiceImpl implements ValidationService {
|
|||
public void update(ValidationParameter parameter) {
|
||||
}
|
||||
|
||||
public void delete(long id, String operator) {
|
||||
public void delete(long id) {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
* Copyright 1999-2012 Alibaba Group.
|
||||
*
|
||||
* Licensed 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.alibaba.dubbo.examples.annotation;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
import com.alibaba.dubbo.examples.annotation.action.AnnotationAction;
|
||||
|
||||
/**
|
||||
* AnnotationTest
|
||||
*
|
||||
* @author william.liangf
|
||||
*/
|
||||
public class AnnotationTest {
|
||||
|
||||
@Test
|
||||
public void testAnnotation() {
|
||||
ClassPathXmlApplicationContext providerContext = new ClassPathXmlApplicationContext(AnnotationTest.class.getPackage().getName().replace('.', '/') + "/annotation-provider.xml");
|
||||
providerContext.start();
|
||||
try {
|
||||
ClassPathXmlApplicationContext consumerContext = new ClassPathXmlApplicationContext(AnnotationTest.class.getPackage().getName().replace('.', '/') + "/annotation-consumer.xml");
|
||||
consumerContext.start();
|
||||
try {
|
||||
AnnotationAction annotationAction = (AnnotationAction) consumerContext.getBean("annotationAction");
|
||||
String hello = annotationAction.doSayHello("world");
|
||||
assertEquals("annotation: hello, world", hello);
|
||||
} finally {
|
||||
consumerContext.stop();
|
||||
consumerContext.close();
|
||||
}
|
||||
} finally {
|
||||
providerContext.stop();
|
||||
providerContext.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,137 +0,0 @@
|
|||
/*
|
||||
* Copyright 1999-2012 Alibaba Group.
|
||||
*
|
||||
* Licensed 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.alibaba.dubbo.examples.validation;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.ConstraintViolationException;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
import com.alibaba.dubbo.examples.validation.api.ValidationParameter;
|
||||
import com.alibaba.dubbo.examples.validation.api.ValidationService;
|
||||
import com.alibaba.dubbo.rpc.RpcException;
|
||||
|
||||
/**
|
||||
* ValidationTest
|
||||
*
|
||||
* @author william.liangf
|
||||
*/
|
||||
public class ValidationTest {
|
||||
|
||||
@Test
|
||||
public void testValidation() {
|
||||
ClassPathXmlApplicationContext providerContext = new ClassPathXmlApplicationContext(ValidationTest.class.getPackage().getName().replace('.', '/') + "/validation-provider.xml");
|
||||
providerContext.start();
|
||||
try {
|
||||
ClassPathXmlApplicationContext consumerContext = new ClassPathXmlApplicationContext(ValidationTest.class.getPackage().getName().replace('.', '/') + "/validation-consumer.xml");
|
||||
consumerContext.start();
|
||||
try {
|
||||
ValidationService validationService = (ValidationService) consumerContext.getBean("validationService");
|
||||
|
||||
// Save OK
|
||||
ValidationParameter parameter = new ValidationParameter();
|
||||
parameter.setName("liangfei");
|
||||
parameter.setEmail("liangfei@liang.fei");
|
||||
parameter.setAge(50);
|
||||
parameter.setLoginDate(new Date(System.currentTimeMillis() - 1000000));
|
||||
parameter.setExpiryDate(new Date(System.currentTimeMillis() + 1000000));
|
||||
validationService.save(parameter);
|
||||
|
||||
try {
|
||||
parameter = new ValidationParameter();
|
||||
parameter.setName("l");
|
||||
parameter.setEmail("liangfei@liang.fei");
|
||||
parameter.setAge(50);
|
||||
parameter.setLoginDate(new Date(System.currentTimeMillis() - 1000000));
|
||||
parameter.setExpiryDate(new Date(System.currentTimeMillis() + 1000000));
|
||||
validationService.save(parameter);
|
||||
Assert.fail();
|
||||
} catch (RpcException e) {
|
||||
ConstraintViolationException ve = (ConstraintViolationException)e.getCause();
|
||||
Set<ConstraintViolation<?>> violations = ve.getConstraintViolations();
|
||||
Assert.assertNotNull(violations);
|
||||
}
|
||||
|
||||
// Save Error
|
||||
try {
|
||||
parameter = new ValidationParameter();
|
||||
validationService.save(parameter);
|
||||
Assert.fail();
|
||||
} catch (RpcException e) {
|
||||
ConstraintViolationException ve = (ConstraintViolationException)e.getCause();
|
||||
Set<ConstraintViolation<?>> violations = ve.getConstraintViolations();
|
||||
Assert.assertNotNull(violations);
|
||||
}
|
||||
|
||||
// Delete OK
|
||||
validationService.delete(2, "abc");
|
||||
|
||||
// Delete Error
|
||||
try {
|
||||
validationService.delete(2, "a");
|
||||
Assert.fail();
|
||||
} catch (RpcException e) {
|
||||
ConstraintViolationException ve = (ConstraintViolationException)e.getCause();
|
||||
Set<ConstraintViolation<?>> violations = ve.getConstraintViolations();
|
||||
Assert.assertNotNull(violations);
|
||||
Assert.assertEquals(1, violations.size());
|
||||
}
|
||||
|
||||
// Delete Error
|
||||
try {
|
||||
validationService.delete(0, "abc");
|
||||
Assert.fail();
|
||||
} catch (RpcException e) {
|
||||
ConstraintViolationException ve = (ConstraintViolationException)e.getCause();
|
||||
Set<ConstraintViolation<?>> violations = ve.getConstraintViolations();
|
||||
Assert.assertNotNull(violations);
|
||||
Assert.assertEquals(1, violations.size());
|
||||
}
|
||||
try {
|
||||
validationService.delete(2, null);
|
||||
Assert.fail();
|
||||
} catch (RpcException e) {
|
||||
ConstraintViolationException ve = (ConstraintViolationException)e.getCause();
|
||||
Set<ConstraintViolation<?>> violations = ve.getConstraintViolations();
|
||||
Assert.assertNotNull(violations);
|
||||
Assert.assertEquals(1, violations.size());
|
||||
}
|
||||
try {
|
||||
validationService.delete(0, null);
|
||||
Assert.fail();
|
||||
} catch (RpcException e) {
|
||||
ConstraintViolationException ve = (ConstraintViolationException)e.getCause();
|
||||
Set<ConstraintViolation<?>> violations = ve.getConstraintViolations();
|
||||
Assert.assertNotNull(violations);
|
||||
Assert.assertEquals(2, violations.size());
|
||||
}
|
||||
} finally {
|
||||
consumerContext.stop();
|
||||
consumerContext.close();
|
||||
}
|
||||
} finally {
|
||||
providerContext.stop();
|
||||
providerContext.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -26,9 +26,6 @@
|
|||
<packaging>pom</packaging>
|
||||
<name>${project.artifactId}</name>
|
||||
<description>The demo module of dubbo project</description>
|
||||
<properties>
|
||||
<skip_maven_deploy>true</skip_maven_deploy>
|
||||
</properties>
|
||||
<modules>
|
||||
<module>dubbo-demo-api</module>
|
||||
<module>dubbo-demo-provider</module>
|
||||
|
|
|
|||
|
|
@ -26,9 +26,6 @@
|
|||
<packaging>pom</packaging>
|
||||
<name>${project.artifactId}</name>
|
||||
<description>The filter module of dubbo project</description>
|
||||
<properties>
|
||||
<skip_maven_deploy>true</skip_maven_deploy>
|
||||
</properties>
|
||||
<modules>
|
||||
<module>dubbo-filter-cache</module>
|
||||
<module>dubbo-filter-validation</module>
|
||||
|
|
|
|||
|
|
@ -26,9 +26,6 @@
|
|||
<packaging>pom</packaging>
|
||||
<name>${project.artifactId}</name>
|
||||
<description>The monitor module of dubbo project</description>
|
||||
<properties>
|
||||
<skip_maven_deploy>true</skip_maven_deploy>
|
||||
</properties>
|
||||
<modules>
|
||||
<module>dubbo-monitor-api</module>
|
||||
<module>dubbo-monitor-default</module>
|
||||
|
|
|
|||
|
|
@ -389,9 +389,7 @@ public class RegistryDirectory<T> extends AbstractDirectory<T> implements Notify
|
|||
Invoker<T> invoker = localUrlInvokerMap == null ? null : localUrlInvokerMap.get(key);
|
||||
if (invoker == null) { // 缓存中没有,重新refer
|
||||
try {
|
||||
if (url.getParameter(Constants.ENABLED_KEY, true)) {
|
||||
invoker = new InvokerDelegete<T>(protocol.refer(serviceType, url), url, providerUrl);
|
||||
}
|
||||
invoker = new InvokerDelegete<T>(protocol.refer(serviceType, url), url, providerUrl);
|
||||
} catch (Throwable t) {
|
||||
logger.error("Failed to refer invoker for interface:"+serviceType+",url:("+url+")" + t.getMessage(), t);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -373,7 +373,7 @@ public abstract class AbstractRegistry implements Registry {
|
|||
}
|
||||
}
|
||||
|
||||
protected static List<URL> filterEmpty(URL url, List<URL> urls) {
|
||||
private List<URL> filterEmpty(URL url, List<URL> urls) {
|
||||
if (urls == null || urls.size() == 0) {
|
||||
List<URL> result = new ArrayList<URL>(1);
|
||||
result.add(url.setProtocol(Constants.EMPTY_PROTOCOL));
|
||||
|
|
@ -414,7 +414,6 @@ public abstract class AbstractRegistry implements Registry {
|
|||
}
|
||||
if ((urls == null || urls.size() == 0)
|
||||
&& ! Constants.ANY_VALUE.equals(url.getServiceInterface())) {
|
||||
logger.warn("Ignore empty notify urls for subscribe url " + url);
|
||||
return;
|
||||
}
|
||||
List<URL> result = new ArrayList<URL>();
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@ public abstract class FailbackRegistry extends AbstractRegistry {
|
|||
listeners = failedNotified.get(url);
|
||||
}
|
||||
listeners.put(listener, urls);
|
||||
logger.error("Failed to notify for subscribe " + url + ", waiting for retry, cause: " + t.getMessage(), t);
|
||||
logger.error("Failed to unsubscribe " + url + ", waiting for retry, cause: " + t.getMessage(), t);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -801,52 +801,6 @@ public class RegistryDirectoryTest {
|
|||
Invoker<?> aInvoker = invokers.get(0);
|
||||
Assert.assertEquals("4",aInvoker.getUrl().getParameter("timeout"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试override通过enable=false,禁用所有服务提供者
|
||||
* 预期:不能通过override禁用所有服务提供者.
|
||||
*/
|
||||
@Test
|
||||
public void testNofityOverrideUrls_disabled_allProvider(){
|
||||
RegistryDirectory registryDirectory = getRegistryDirectory();
|
||||
invocation = new RpcInvocation();
|
||||
|
||||
List<URL> durls = new ArrayList<URL>();
|
||||
durls.add(SERVICEURL.setHost("10.20.30.140"));
|
||||
durls.add(SERVICEURL.setHost("10.20.30.141"));
|
||||
registryDirectory.notify(durls);
|
||||
|
||||
durls = new ArrayList<URL>();
|
||||
durls.add(URL.valueOf("override://0.0.0.0?"+Constants.ENABLED_KEY+"=false"));
|
||||
registryDirectory.notify(durls);
|
||||
|
||||
List<Invoker<?>> invokers = registryDirectory.list(invocation);
|
||||
//不能通过override禁用所有服务提供者.
|
||||
Assert.assertEquals(2,invokers.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试override通过enable=false,禁用指定服务提供者
|
||||
* 预期:可以禁用指定的服务提供者。
|
||||
*/
|
||||
@Test
|
||||
public void testNofityOverrideUrls_disabled_specifiedProvider(){
|
||||
RegistryDirectory registryDirectory = getRegistryDirectory();
|
||||
invocation = new RpcInvocation();
|
||||
|
||||
List<URL> durls = new ArrayList<URL>();
|
||||
durls.add(SERVICEURL.setHost("10.20.30.140"));
|
||||
durls.add(SERVICEURL.setHost("10.20.30.141"));
|
||||
registryDirectory.notify(durls);
|
||||
|
||||
durls = new ArrayList<URL>();
|
||||
durls.add(URL.valueOf("override://10.20.30.140?"+Constants.ENABLED_KEY+"=false"));
|
||||
registryDirectory.notify(durls);
|
||||
|
||||
List<Invoker<?>> invokers = registryDirectory.list(invocation);
|
||||
Assert.assertEquals(1,invokers.size());
|
||||
Assert.assertEquals("10.20.30.141", invokers.get(0).getUrl().getHost());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotifyRouterUrls_Clean() {
|
||||
|
|
|
|||
|
|
@ -381,7 +381,7 @@ public class RedisRegistry extends FailbackRegistry {
|
|||
}
|
||||
}
|
||||
String category = toCategoryName(key);
|
||||
if (! categories.contains(Constants.ANY_VALUE) && ! categories.contains(category)) {
|
||||
if (! categories.contains(category)) {
|
||||
continue;
|
||||
}
|
||||
List<URL> urls = new ArrayList<URL>();
|
||||
|
|
|
|||
|
|
@ -59,11 +59,11 @@ public class ZookeeperRegistry extends FailbackRegistry {
|
|||
|
||||
private final Set<String> anyServices = new ConcurrentHashSet<String>();
|
||||
|
||||
private final ConcurrentMap<URL, ConcurrentMap<NotifyListener, IZkChildListener>> zkListeners = new ConcurrentHashMap<URL, ConcurrentMap<NotifyListener, IZkChildListener>>();
|
||||
private final ConcurrentMap<NotifyListener, IZkChildListener> zkListeners = new ConcurrentHashMap<NotifyListener, IZkChildListener>();
|
||||
|
||||
private final ZkClient zkClient;
|
||||
|
||||
private volatile KeeperState zkState = KeeperState.SyncConnected;
|
||||
private volatile KeeperState zkState;
|
||||
|
||||
public ZookeeperRegistry(URL url) {
|
||||
super(url);
|
||||
|
|
@ -131,50 +131,40 @@ public class ZookeeperRegistry extends FailbackRegistry {
|
|||
try {
|
||||
if (Constants.ANY_VALUE.equals(url.getServiceInterface())) {
|
||||
String root = toRootPath();
|
||||
ConcurrentMap<NotifyListener, IZkChildListener> listeners = zkListeners.get(url);
|
||||
if (listeners == null) {
|
||||
zkListeners.putIfAbsent(url, new ConcurrentHashMap<NotifyListener, IZkChildListener>());
|
||||
listeners = zkListeners.get(url);
|
||||
}
|
||||
IZkChildListener zkListener = listeners.get(listener);
|
||||
IZkChildListener zkListener = zkListeners.get(listener);
|
||||
if (zkListener == null) {
|
||||
listeners.putIfAbsent(listener, new IZkChildListener() {
|
||||
zkListeners.putIfAbsent(listener, new IZkChildListener() {
|
||||
public void handleChildChange(String parentPath, List<String> currentChilds) throws Exception {
|
||||
for (String child : currentChilds) {
|
||||
if (! anyServices.contains(child)) {
|
||||
anyServices.add(child);
|
||||
subscribe(url.setPath(child).addParameters(Constants.INTERFACE_KEY, child,
|
||||
Constants.CHECK_KEY, String.valueOf(false)), listener);
|
||||
Constants.CHECK_KEY, String.valueOf(false), Constants.REGISTER_KEY, String.valueOf(false)), listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
zkListener = listeners.get(listener);
|
||||
zkListener = zkListeners.get(listener);
|
||||
}
|
||||
List<String> services = zkClient.subscribeChildChanges(root, zkListener);
|
||||
if (services != null && services.size() > 0) {
|
||||
anyServices.addAll(services);
|
||||
for (String service : services) {
|
||||
subscribe(url.setPath(service).addParameters(Constants.INTERFACE_KEY, service,
|
||||
Constants.CHECK_KEY, String.valueOf(false)), listener);
|
||||
Constants.CHECK_KEY, String.valueOf(false), Constants.REGISTER_KEY, String.valueOf(false)), listener);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
List<String> providers = new ArrayList<String>();
|
||||
for (String path : toCategoriesPath(url)) {
|
||||
ConcurrentMap<NotifyListener, IZkChildListener> listeners = zkListeners.get(url);
|
||||
if (listeners == null) {
|
||||
zkListeners.putIfAbsent(url, new ConcurrentHashMap<NotifyListener, IZkChildListener>());
|
||||
listeners = zkListeners.get(url);
|
||||
}
|
||||
IZkChildListener zkListener = listeners.get(listener);
|
||||
IZkChildListener zkListener = zkListeners.get(listener);
|
||||
if (zkListener == null) {
|
||||
listeners.putIfAbsent(listener, new IZkChildListener() {
|
||||
zkListeners.putIfAbsent(listener, new IZkChildListener() {
|
||||
public void handleChildChange(String parentPath, List<String> currentChilds) throws Exception {
|
||||
ZookeeperRegistry.this.notify(url, listener, toUrls(url, currentChilds));
|
||||
}
|
||||
});
|
||||
zkListener = listeners.get(listener);
|
||||
zkListener = zkListeners.get(listener);
|
||||
}
|
||||
List<String> children = zkClient.subscribeChildChanges(path, zkListener);
|
||||
if (children != null) {
|
||||
|
|
@ -190,13 +180,7 @@ public class ZookeeperRegistry extends FailbackRegistry {
|
|||
}
|
||||
|
||||
protected void doUnsubscribe(URL url, NotifyListener listener) {
|
||||
ConcurrentMap<NotifyListener, IZkChildListener> listeners = zkListeners.get(url);
|
||||
if (listeners != null) {
|
||||
IZkChildListener zkListener = listeners.get(listener);
|
||||
if (zkListener != null) {
|
||||
zkClient.unsubscribeChildChanges(toUrlPath(url), zkListener);
|
||||
}
|
||||
}
|
||||
zkClient.unsubscribeChildChanges(toUrlPath(url), zkListeners.get(listener));
|
||||
}
|
||||
|
||||
public List<URL> lookup(URL url) {
|
||||
|
|
@ -241,13 +225,7 @@ public class ZookeeperRegistry extends FailbackRegistry {
|
|||
}
|
||||
|
||||
private String[] toCategoriesPath(URL url) {
|
||||
String[] categroies;
|
||||
if (Constants.ANY_VALUE.equals(url.getParameter(Constants.CATEGORY_KEY))) {
|
||||
categroies = new String[] {Constants.PROVIDERS_CATEGORY, Constants.CONSUMERS_CATEGORY,
|
||||
Constants.ROUTERS_CATEGORY, Constants.CONFIGURATORS_CATEGORY};
|
||||
} else {
|
||||
categroies = url.getParameter(Constants.CATEGORY_KEY, new String[] {Constants.DEFAULT_CATEGORY});
|
||||
}
|
||||
String[] categroies = url.getParameter(Constants.CATEGORY_KEY, new String[] {Constants.DEFAULT_CATEGORY});
|
||||
String[] paths = new String[categroies.length];
|
||||
for (int i = 0; i < categroies.length; i ++) {
|
||||
paths[i] = toServicePath(url) + Constants.PATH_SEPARATOR + categroies[i];
|
||||
|
|
|
|||
|
|
@ -26,9 +26,6 @@
|
|||
<packaging>pom</packaging>
|
||||
<name>${project.artifactId}</name>
|
||||
<description>The registry module of dubbo project</description>
|
||||
<properties>
|
||||
<skip_maven_deploy>true</skip_maven_deploy>
|
||||
</properties>
|
||||
<modules>
|
||||
<module>dubbo-registry-api</module>
|
||||
<module>dubbo-registry-default</module>
|
||||
|
|
|
|||
|
|
@ -26,9 +26,6 @@
|
|||
<packaging>pom</packaging>
|
||||
<name>${project.artifactId}</name>
|
||||
<description>The remoting module of dubbo project</description>
|
||||
<properties>
|
||||
<skip_maven_deploy>true</skip_maven_deploy>
|
||||
</properties>
|
||||
<modules>
|
||||
<module>dubbo-remoting-api</module>
|
||||
<module>dubbo-remoting-netty</module>
|
||||
|
|
|
|||
|
|
@ -1,127 +0,0 @@
|
|||
/*
|
||||
* Copyright 1999-2012 Alibaba Group.
|
||||
*
|
||||
* Licensed 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.alibaba.dubbo.rpc.protocol;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.rpc.Exporter;
|
||||
import com.alibaba.dubbo.rpc.Invocation;
|
||||
import com.alibaba.dubbo.rpc.Invoker;
|
||||
import com.alibaba.dubbo.rpc.ProxyFactory;
|
||||
import com.alibaba.dubbo.rpc.Result;
|
||||
import com.alibaba.dubbo.rpc.RpcException;
|
||||
|
||||
/**
|
||||
* AbstractProxyProtocol
|
||||
*
|
||||
* @author william.liangf
|
||||
*/
|
||||
public abstract class AbstractProxyProtocol extends AbstractProtocol {
|
||||
|
||||
private final List<Class<?>> rpcExceptions = new CopyOnWriteArrayList<Class<?>>();;
|
||||
|
||||
private ProxyFactory proxyFactory;
|
||||
|
||||
public AbstractProxyProtocol() {
|
||||
}
|
||||
|
||||
public AbstractProxyProtocol(Class<?>... exceptions) {
|
||||
for (Class<?> exception : exceptions) {
|
||||
addRpcException(exception);
|
||||
}
|
||||
}
|
||||
|
||||
public void addRpcException(Class<?> exception) {
|
||||
this.rpcExceptions.add(exception);
|
||||
}
|
||||
|
||||
public void setProxyFactory(ProxyFactory proxyFactory) {
|
||||
this.proxyFactory = proxyFactory;
|
||||
}
|
||||
|
||||
public ProxyFactory getProxyFactory() {
|
||||
return proxyFactory;
|
||||
}
|
||||
|
||||
public <T> Exporter<T> export(final Invoker<T> invoker) throws RpcException {
|
||||
final String uri = invoker.getUrl().getAbsolutePath();
|
||||
final Runnable runnable = doExport(proxyFactory.getProxy(invoker), invoker.getInterface(), invoker.getUrl());
|
||||
Exporter<T> exporter = new AbstractExporter<T>(invoker) {
|
||||
public void unexport() {
|
||||
super.unexport();
|
||||
exporterMap.remove(uri);
|
||||
if (runnable != null) {
|
||||
try {
|
||||
runnable.run();
|
||||
} catch (Throwable t) {
|
||||
logger.warn(t.getMessage(), t);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
exporterMap.put(uri, exporter);
|
||||
return exporter;
|
||||
}
|
||||
|
||||
public <T> Invoker<T> refer(final Class<T> type, final URL url) throws RpcException {
|
||||
final Invoker<T> tagert = proxyFactory.getInvoker(doRefer(type, url), type, url);
|
||||
Invoker<T> invoker = new AbstractInvoker<T>(type, url) {
|
||||
@Override
|
||||
protected Result doInvoke(Invocation invocation) throws Throwable {
|
||||
try {
|
||||
Result result = tagert.invoke(invocation);
|
||||
Throwable e = result.getException();
|
||||
if (e != null) {
|
||||
for (Class<?> rpcException : rpcExceptions) {
|
||||
if (rpcException.isAssignableFrom(e.getClass())) {
|
||||
throw getRpcException(type, url, invocation, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} catch (RpcException e) {
|
||||
if (e.getCode() == RpcException.UNKNOWN_EXCEPTION) {
|
||||
e.setCode(getErrorCode(e.getCause()));
|
||||
}
|
||||
throw e;
|
||||
} catch (Throwable e) {
|
||||
throw getRpcException(type, url, invocation, e);
|
||||
}
|
||||
}
|
||||
};
|
||||
invokers.add(invoker);
|
||||
return invoker;
|
||||
}
|
||||
|
||||
protected RpcException getRpcException(Class<?> type, URL url, Invocation invocation, Throwable e) {
|
||||
RpcException re = new RpcException("Failed to invoke remote service: " + type + ", method: "
|
||||
+ invocation.getMethodName() + ", cause: " + e.getMessage(), e);
|
||||
re.setCode(getErrorCode(e));
|
||||
return re;
|
||||
}
|
||||
|
||||
protected int getErrorCode(Throwable e) {
|
||||
return RpcException.UNKNOWN_EXCEPTION;
|
||||
}
|
||||
|
||||
protected abstract <T> Runnable doExport(T impl, Class<T> type, URL url) throws RpcException;
|
||||
|
||||
protected abstract <T> T doRefer(Class<T> type, URL url) throws RpcException;
|
||||
|
||||
}
|
||||
|
|
@ -94,8 +94,7 @@ class CallbackServiceCodec {
|
|||
|
||||
Map<String, String> tmpmap = new HashMap<String, String>(url.getParameters());
|
||||
tmpmap.putAll(params);
|
||||
tmpmap.remove(Constants.VERSION_KEY);//callback不需要区分version
|
||||
tmpmap.put(Constants.INTERFACE_KEY, clazz.getName());
|
||||
tmpmap.remove(Constants.VERSION_KEY);//callback不需要区分version
|
||||
URL exporturl = new URL(DubboProtocol.NAME, channel.getLocalAddress().getAddress().getHostAddress(), channel.getLocalAddress().getPort(), clazz.getName()+"."+instid, tmpmap);
|
||||
|
||||
//同一个jvm不需要对不同的channel产生多个exporter cache key不会碰撞
|
||||
|
|
@ -138,11 +137,10 @@ class CallbackServiceCodec {
|
|||
String countkey = getServerSideCountKey(channel, clazz.getName());
|
||||
if (isRefer){
|
||||
if( proxy == null ){
|
||||
URL referurl = URL.valueOf("callback://" + url.getAddress() + "/" + clazz.getName() + "?" + Constants.INTERFACE_KEY + "=" + clazz.getName());
|
||||
referurl = referurl.addParametersIfAbsent(url.getParameters()).removeParameter(Constants.METHODS_KEY);
|
||||
if (!isInstancesOverLimit(channel, referurl, clazz.getName(), instid, true)){
|
||||
if (!isInstancesOverLimit(channel, url, clazz.getName(), instid, true)){
|
||||
url = url.setPath(clazz.getName());
|
||||
@SuppressWarnings("rawtypes")
|
||||
Invoker<?> invoker = new ChannelWrappedInvoker(clazz, channel, referurl, String.valueOf(instid));
|
||||
Invoker<?> invoker = new ChannelWrappedInvoker(clazz, channel, url, String.valueOf(instid));
|
||||
proxy = proxyFactory.getProxy(invoker);
|
||||
channel.setAttribute(proxyCacheKey, proxy);
|
||||
channel.setAttribute(invokerCacheKey, invoker);
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
package com.alibaba.dubbo.rpc.protocol.hessian;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
|
@ -25,111 +24,78 @@ import javax.servlet.ServletException;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.alibaba.dubbo.common.Constants;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.remoting.http.HttpBinder;
|
||||
import com.alibaba.dubbo.remoting.http.HttpHandler;
|
||||
import com.alibaba.dubbo.remoting.http.HttpServer;
|
||||
import com.alibaba.dubbo.rpc.RpcContext;
|
||||
import com.alibaba.dubbo.rpc.Exporter;
|
||||
import com.alibaba.dubbo.rpc.Invoker;
|
||||
import com.alibaba.dubbo.rpc.ProxyFactory;
|
||||
import com.alibaba.dubbo.rpc.RpcException;
|
||||
import com.alibaba.dubbo.rpc.protocol.AbstractProxyProtocol;
|
||||
import com.caucho.hessian.HessianException;
|
||||
import com.caucho.hessian.client.HessianConnectionException;
|
||||
import com.caucho.hessian.client.HessianProxyFactory;
|
||||
import com.caucho.hessian.io.HessianMethodSerializationException;
|
||||
import com.caucho.hessian.server.HessianSkeleton;
|
||||
import com.alibaba.dubbo.rpc.protocol.AbstractProtocol;
|
||||
|
||||
/**
|
||||
* http rpc support.
|
||||
*
|
||||
* @author qianlei
|
||||
*/
|
||||
public class HessianProtocol extends AbstractProxyProtocol {
|
||||
public class HessianProtocol extends AbstractProtocol {
|
||||
|
||||
private final Map<String, HttpServer> serverMap = new ConcurrentHashMap<String, HttpServer>();
|
||||
|
||||
private final Map<String, HessianSkeleton> skeletonMap = new ConcurrentHashMap<String, HessianSkeleton>();
|
||||
|
||||
private HttpBinder httpBinder;
|
||||
|
||||
public HessianProtocol() {
|
||||
super(HessianException.class);
|
||||
}
|
||||
private HttpBinder httpTransporter;
|
||||
|
||||
public void setHttpBinder(HttpBinder httpBinder) {
|
||||
this.httpBinder = httpBinder;
|
||||
private ProxyFactory proxyFactory;
|
||||
|
||||
public void setHttpTransporter(HttpBinder httpTransporter) {
|
||||
this.httpTransporter = httpTransporter;
|
||||
}
|
||||
|
||||
public void setProxyFactory(ProxyFactory proxyFactory) {
|
||||
this.proxyFactory = proxyFactory;
|
||||
}
|
||||
|
||||
public int getDefaultPort() {
|
||||
return 80;
|
||||
}
|
||||
|
||||
|
||||
private class HessianHandler implements HttpHandler {
|
||||
|
||||
public void handle(HttpServletRequest request, HttpServletResponse response)
|
||||
throws IOException, ServletException {
|
||||
String uri = request.getRequestURI();
|
||||
HessianSkeleton skeleton = skeletonMap.get(uri);
|
||||
if (! request.getMethod().equalsIgnoreCase("POST")) {
|
||||
response.setStatus(500);
|
||||
} else {
|
||||
RpcContext.getContext().setRemoteAddress(request.getRemoteAddr(), request.getRemotePort());
|
||||
try {
|
||||
skeleton.invoke(request.getInputStream(), response.getOutputStream());
|
||||
} catch (Throwable e) {
|
||||
throw new ServletException(e);
|
||||
}
|
||||
}
|
||||
HessianRpcExporter<?> exporter = (HessianRpcExporter<?>) exporterMap.get(uri);
|
||||
exporter.handle(request, response);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected <T> Runnable doExport(T impl, Class<T> type, URL url) throws RpcException {
|
||||
public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
|
||||
final URL url = invoker.getUrl();
|
||||
final String uri = url.getAbsolutePath(); // service uri also exporter cache key.
|
||||
|
||||
String addr = url.getIp() + ":" + url.getPort();
|
||||
HttpServer server = serverMap.get(addr);
|
||||
if (server == null) {
|
||||
server = httpBinder.bind(url, new HessianHandler());
|
||||
server = httpTransporter.bind(url, new HessianHandler());
|
||||
serverMap.put(addr, server);
|
||||
}
|
||||
final String path = url.getAbsolutePath();
|
||||
HessianSkeleton skeleton = new HessianSkeleton(impl, type);
|
||||
skeletonMap.put(path, skeleton);
|
||||
return new Runnable() {
|
||||
public void run() {
|
||||
skeletonMap.remove(path);
|
||||
}
|
||||
|
||||
HessianRpcExporter<T> exporter = new HessianRpcExporter<T>(invoker, proxyFactory) {
|
||||
public void unexport() {
|
||||
super.unexport();
|
||||
exporterMap.remove(uri);
|
||||
}
|
||||
};
|
||||
exporterMap.put(uri, exporter);
|
||||
return exporter;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T> T doRefer(Class<T> serviceType, URL url) throws RpcException {
|
||||
HessianProxyFactory hessianProxyFactory = new HessianProxyFactory();
|
||||
String client = url.getParameter(Constants.CLIENT_KEY, Constants.DEFAULT_HTTP_CLIENT);
|
||||
if ("httpclient".equals(client)) {
|
||||
hessianProxyFactory.setConnectionFactory(new HttpClientConnectionFactory());
|
||||
} else if (client != null && client.length() > 0 && ! Constants.DEFAULT_HTTP_CLIENT.equals(client)) {
|
||||
throw new IllegalStateException("Unsupported http protocol client=\"" + client + "\"!");
|
||||
}
|
||||
int timeout = url.getParameter(Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT);
|
||||
hessianProxyFactory.setConnectTimeout(timeout);
|
||||
hessianProxyFactory.setReadTimeout(timeout);
|
||||
return (T) hessianProxyFactory.create(serviceType, url.setProtocol("http").toJavaURL(), Thread.currentThread().getContextClassLoader());
|
||||
|
||||
public <T> Invoker<T> refer(Class<T> serviceType, URL url) throws RpcException {
|
||||
Invoker<T> invoker = new HessianRpcInvoker<T>(serviceType, url, proxyFactory);
|
||||
invokers.add(invoker);
|
||||
return invoker;
|
||||
}
|
||||
|
||||
protected int getErrorCode(Throwable e) {
|
||||
if (e instanceof HessianConnectionException) {
|
||||
if (e.getCause() != null) {
|
||||
Class<?> cls = e.getCause().getClass();
|
||||
if (SocketTimeoutException.class.equals(cls)) {
|
||||
return RpcException.TIMEOUT_EXCEPTION;
|
||||
}
|
||||
}
|
||||
return RpcException.NETWORK_EXCEPTION;
|
||||
} else if (e instanceof HessianMethodSerializationException) {
|
||||
return RpcException.SERIALIZATION_EXCEPTION;
|
||||
}
|
||||
return super.getErrorCode(e);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
super.destroy();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright 1999-2011 Alibaba Group.
|
||||
*
|
||||
* Licensed 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.alibaba.dubbo.rpc.protocol.hessian;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.alibaba.dubbo.remoting.http.HttpHandler;
|
||||
import com.alibaba.dubbo.rpc.Invoker;
|
||||
import com.alibaba.dubbo.rpc.ProxyFactory;
|
||||
import com.alibaba.dubbo.rpc.RpcContext;
|
||||
import com.alibaba.dubbo.rpc.protocol.AbstractExporter;
|
||||
import com.caucho.hessian.server.HessianSkeleton;
|
||||
|
||||
/**
|
||||
* hessian rpc exporter.
|
||||
*
|
||||
* @author qian.lei
|
||||
*/
|
||||
public class HessianRpcExporter<T> extends AbstractExporter<T> implements HttpHandler {
|
||||
|
||||
private HessianSkeleton skeleton;
|
||||
|
||||
public HessianRpcExporter(Invoker<T> invoker, ProxyFactory proxyFactory) {
|
||||
super(invoker);
|
||||
skeleton = new HessianSkeleton(proxyFactory.getProxy(invoker), invoker.getInterface());
|
||||
}
|
||||
|
||||
public void handle(HttpServletRequest request, HttpServletResponse response)
|
||||
throws IOException, ServletException {
|
||||
if (! request.getMethod().equalsIgnoreCase("POST")) {
|
||||
response.setStatus(500);
|
||||
} else {
|
||||
RpcContext.getContext().setRemoteAddress(request.getRemoteAddr(),
|
||||
request.getRemotePort());
|
||||
try {
|
||||
skeleton.invoke(request.getInputStream(), response.getOutputStream());
|
||||
} catch (Throwable e) {
|
||||
throw new ServletException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* Copyright 1999-2011 Alibaba Group.
|
||||
*
|
||||
* Licensed 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.alibaba.dubbo.rpc.protocol.hessian;
|
||||
|
||||
import java.net.SocketTimeoutException;
|
||||
|
||||
import com.alibaba.dubbo.common.Constants;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.rpc.Invocation;
|
||||
import com.alibaba.dubbo.rpc.Invoker;
|
||||
import com.alibaba.dubbo.rpc.ProxyFactory;
|
||||
import com.alibaba.dubbo.rpc.Result;
|
||||
import com.alibaba.dubbo.rpc.RpcException;
|
||||
import com.alibaba.dubbo.rpc.RpcResult;
|
||||
import com.alibaba.dubbo.rpc.protocol.AbstractInvoker;
|
||||
import com.caucho.hessian.HessianException;
|
||||
import com.caucho.hessian.client.HessianConnectionException;
|
||||
import com.caucho.hessian.client.HessianConnectionFactory;
|
||||
import com.caucho.hessian.client.HessianProxyFactory;
|
||||
import com.caucho.hessian.io.HessianMethodSerializationException;
|
||||
|
||||
/**
|
||||
* hessian rpc invoker.
|
||||
*
|
||||
* @author qianlei
|
||||
*/
|
||||
public class HessianRpcInvoker<T> extends AbstractInvoker<T> {
|
||||
|
||||
protected static final String HESSIAN_EXCEPTION_PREFIX = HessianException.class.getPackage().getName() + "."; //fix by tony.chenl
|
||||
|
||||
protected Invoker<T> invoker;
|
||||
|
||||
protected HessianConnectionFactory hessianConnectionFactory = new HttpClientConnectionFactory();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public HessianRpcInvoker(Class<T> serviceType, URL url, ProxyFactory proxyFactory){
|
||||
super(serviceType, url);
|
||||
HessianProxyFactory hessianProxyFactory = new HessianProxyFactory();
|
||||
String client = url.getParameter(Constants.CLIENT_KEY, Constants.DEFAULT_HTTP_CLIENT);
|
||||
if ("httpclient".equals(client)) {
|
||||
hessianProxyFactory.setConnectionFactory(hessianConnectionFactory);
|
||||
} else if (client != null && client.length() > 0 && ! Constants.DEFAULT_HTTP_CLIENT.equals(client)) {
|
||||
throw new IllegalStateException("Unsupported http protocol client=\"" + client + "\"!");
|
||||
}
|
||||
int timeout = url.getParameter(Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT);
|
||||
hessianProxyFactory.setConnectTimeout(timeout);
|
||||
hessianProxyFactory.setReadTimeout(timeout);
|
||||
invoker = proxyFactory.getInvoker((T)hessianProxyFactory.create(serviceType, url.setProtocol("http").toJavaURL(), Thread.currentThread().getContextClassLoader()), serviceType, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Result doInvoke(Invocation invocation) throws Throwable {
|
||||
try {
|
||||
Result result = invoker.invoke(invocation);
|
||||
Throwable e = result.getException();
|
||||
if (e != null) {
|
||||
String name = e.getClass().getName();
|
||||
if (name.startsWith(HESSIAN_EXCEPTION_PREFIX)) {
|
||||
RpcException re = new RpcException("Failed to invoke remote service: " + getInterface() + ", method: "
|
||||
+ invocation.getMethodName() + ", cause: " + e.getMessage(), e);
|
||||
throw setRpcExceptionCode(e, re);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} catch (RpcException e) {
|
||||
throw setRpcExceptionCode(e.getCause(), e);
|
||||
} catch (HessianException e) {
|
||||
throw setRpcExceptionCode(e, new RpcException("Failed to invoke remote service: " + getInterface() + ", method: "
|
||||
+ invocation.getMethodName() + ", cause: " + e.getMessage(), e));
|
||||
} catch (Throwable e) {
|
||||
return new RpcResult(e);
|
||||
}
|
||||
}
|
||||
|
||||
private RpcException setRpcExceptionCode(Throwable e, RpcException re) {
|
||||
if (e != null) {
|
||||
if (e instanceof HessianConnectionException) {
|
||||
re.setCode(RpcException.NETWORK_EXCEPTION);
|
||||
if (e.getCause() != null) {
|
||||
Class<?> cls = e.getCause().getClass();
|
||||
if (SocketTimeoutException.class.equals(cls)) {
|
||||
re.setCode(RpcException.TIMEOUT_EXCEPTION);
|
||||
}
|
||||
}
|
||||
} else if (e instanceof HessianMethodSerializationException) {
|
||||
re.setCode(RpcException.SERIALIZATION_EXCEPTION);
|
||||
}
|
||||
}
|
||||
return re;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
<!--
|
||||
- Copyright 1999-2011 Alibaba Group.
|
||||
-
|
||||
- Licensed 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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>dubbo-rpc</artifactId>
|
||||
<version>2.3.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>dubbo-rpc-http</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>${project.artifactId}</name>
|
||||
<description>The http rpc module of dubbo project</description>
|
||||
<properties>
|
||||
<skip_maven_deploy>true</skip_maven_deploy>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>dubbo-rpc-api</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>dubbo-remoting-http</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
@ -1,137 +0,0 @@
|
|||
/*
|
||||
* Copyright 1999-2012 Alibaba Group.
|
||||
*
|
||||
* Licensed 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 pehttpssions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.rpc.protocol.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.remoting.RemoteAccessException;
|
||||
import org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean;
|
||||
import org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter;
|
||||
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.remoting.http.HttpBinder;
|
||||
import com.alibaba.dubbo.remoting.http.HttpHandler;
|
||||
import com.alibaba.dubbo.remoting.http.HttpServer;
|
||||
import com.alibaba.dubbo.rpc.RpcContext;
|
||||
import com.alibaba.dubbo.rpc.RpcException;
|
||||
import com.alibaba.dubbo.rpc.protocol.AbstractProxyProtocol;
|
||||
|
||||
/**
|
||||
* HttpProtocol
|
||||
*
|
||||
* @author william.liangf
|
||||
*/
|
||||
public class HttpProtocol extends AbstractProxyProtocol {
|
||||
|
||||
public static final int DEFAULT_PORT = 80;
|
||||
|
||||
private final Map<String, HttpServer> serverMap = new ConcurrentHashMap<String, HttpServer>();
|
||||
|
||||
private final Map<String, HttpInvokerServiceExporter> skeletonMap = new ConcurrentHashMap<String, HttpInvokerServiceExporter>();
|
||||
|
||||
private HttpBinder httpBinder;
|
||||
|
||||
public HttpProtocol() {
|
||||
super(IOException.class);
|
||||
}
|
||||
|
||||
public void setHttpBinder(HttpBinder httpBinder) {
|
||||
this.httpBinder = httpBinder;
|
||||
}
|
||||
|
||||
public int getDefaultPort() {
|
||||
return DEFAULT_PORT;
|
||||
}
|
||||
|
||||
private class InternalHandler implements HttpHandler {
|
||||
|
||||
public void handle(HttpServletRequest request, HttpServletResponse response)
|
||||
throws IOException, ServletException {
|
||||
String uri = request.getRequestURI();
|
||||
HttpInvokerServiceExporter skeleton = skeletonMap.get(uri);
|
||||
if (! request.getMethod().equalsIgnoreCase("POST")) {
|
||||
response.setStatus(500);
|
||||
} else {
|
||||
RpcContext.getContext().setRemoteAddress(request.getRemoteAddr(), request.getRemotePort());
|
||||
try {
|
||||
skeleton.handleRequest(request, response);
|
||||
} catch (Throwable e) {
|
||||
throw new ServletException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected <T> Runnable doExport(final T impl, Class<T> type, URL url) throws RpcException {
|
||||
String addr = url.getIp() + ":" + url.getPort();
|
||||
HttpServer server = serverMap.get(addr);
|
||||
if (server == null) {
|
||||
server = httpBinder.bind(url, new InternalHandler());
|
||||
serverMap.put(addr, server);
|
||||
}
|
||||
final HttpInvokerServiceExporter httpServiceExporter = new HttpInvokerServiceExporter();
|
||||
httpServiceExporter.setServiceInterface(type);
|
||||
httpServiceExporter.setService(impl);
|
||||
try {
|
||||
httpServiceExporter.afterPropertiesSet();
|
||||
} catch (Exception e) {
|
||||
throw new RpcException(e.getMessage(), e);
|
||||
}
|
||||
final String path = url.getAbsolutePath();
|
||||
skeletonMap.put(path, httpServiceExporter);
|
||||
return new Runnable() {
|
||||
public void run() {
|
||||
skeletonMap.remove(path);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T> T doRefer(final Class<T> serviceType, final URL url) throws RpcException {
|
||||
final HttpInvokerProxyFactoryBean httpProxyFactoryBean = new HttpInvokerProxyFactoryBean();
|
||||
httpProxyFactoryBean.setServiceUrl(url.toIdentityString());
|
||||
httpProxyFactoryBean.setServiceInterface(serviceType);
|
||||
httpProxyFactoryBean.afterPropertiesSet();
|
||||
return (T) httpProxyFactoryBean.getObject();
|
||||
}
|
||||
|
||||
protected int getErrorCode(Throwable e) {
|
||||
if (e instanceof RemoteAccessException) {
|
||||
e = e.getCause();
|
||||
}
|
||||
if (e != null && e.getCause() != null) {
|
||||
Class<?> cls = e.getCause().getClass();
|
||||
// 是根据测试Case发现的问题,对RpcException.setCode进行设置
|
||||
if (SocketTimeoutException.class.equals(cls)) {
|
||||
return RpcException.TIMEOUT_EXCEPTION;
|
||||
} else if (IOException.class.isAssignableFrom(cls)) {
|
||||
return RpcException.NETWORK_EXCEPTION;
|
||||
} else if (ClassNotFoundException.class.isAssignableFrom(cls)) {
|
||||
return RpcException.SERIALIZATION_EXCEPTION;
|
||||
}
|
||||
}
|
||||
return super.getErrorCode(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
com.alibaba.dubbo.rpc.protocol.http.HttpProtocol
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
<!--
|
||||
- Copyright 1999-2011 Alibaba Group.
|
||||
-
|
||||
- Licensed 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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>dubbo-rpc</artifactId>
|
||||
<version>2.3.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>dubbo-rpc-memcached</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>${project.artifactId}</name>
|
||||
<description>The memcached rpc module of dubbo project</description>
|
||||
<properties>
|
||||
<skip_maven_deploy>true</skip_maven_deploy>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>dubbo-rpc-api</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.googlecode.xmemcached</groupId>
|
||||
<artifactId>xmemcached</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
@ -1,117 +0,0 @@
|
|||
/*
|
||||
* Copyright 1999-2012 Alibaba Group.
|
||||
*
|
||||
* Licensed 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.alibaba.dubbo.rpc.protocol.memcached;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import net.rubyeye.xmemcached.MemcachedClient;
|
||||
import net.rubyeye.xmemcached.MemcachedClientBuilder;
|
||||
import net.rubyeye.xmemcached.XMemcachedClientBuilder;
|
||||
import net.rubyeye.xmemcached.exception.MemcachedException;
|
||||
import net.rubyeye.xmemcached.utils.AddrUtil;
|
||||
|
||||
import com.alibaba.dubbo.common.Constants;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.rpc.Exporter;
|
||||
import com.alibaba.dubbo.rpc.Invocation;
|
||||
import com.alibaba.dubbo.rpc.Invoker;
|
||||
import com.alibaba.dubbo.rpc.Result;
|
||||
import com.alibaba.dubbo.rpc.RpcException;
|
||||
import com.alibaba.dubbo.rpc.RpcResult;
|
||||
import com.alibaba.dubbo.rpc.protocol.AbstractInvoker;
|
||||
import com.alibaba.dubbo.rpc.protocol.AbstractProtocol;
|
||||
|
||||
/**
|
||||
* MemcachedProtocol
|
||||
*
|
||||
* @author william.liangf
|
||||
*/
|
||||
public class MemcachedProtocol extends AbstractProtocol {
|
||||
|
||||
public static final int DEFAULT_PORT = 11211;
|
||||
|
||||
public int getDefaultPort() {
|
||||
return DEFAULT_PORT;
|
||||
}
|
||||
|
||||
public <T> Exporter<T> export(final Invoker<T> invoker) throws RpcException {
|
||||
throw new UnsupportedOperationException("Unsupported export memcached service. url: " + invoker.getUrl());
|
||||
}
|
||||
|
||||
public <T> Invoker<T> refer(final Class<T> type, final URL url) throws RpcException {
|
||||
try {
|
||||
String address = url.getAddress();
|
||||
String backup = url.getParameter(Constants.BACKUP_KEY);
|
||||
if (backup != null && backup.length() > 0) {
|
||||
address += "," + backup;
|
||||
}
|
||||
MemcachedClientBuilder builder = new XMemcachedClientBuilder(AddrUtil.getAddresses(address));
|
||||
final MemcachedClient memcachedClient = builder.build();
|
||||
final int expiry = url.getParameter("expiry", 0);
|
||||
final String get = url.getParameter("get", "get");
|
||||
final String set = url.getParameter("set", Map.class.equals(type) ? "put" : "set");
|
||||
final String delete = url.getParameter("delete", Map.class.equals(type) ? "remove" : "delete");
|
||||
return new AbstractInvoker<T>(type, url) {
|
||||
protected Result doInvoke(Invocation invocation) throws Throwable {
|
||||
try {
|
||||
if (get.equals(invocation.getMethodName())) {
|
||||
if (invocation.getArguments().length != 1) {
|
||||
throw new IllegalArgumentException("The memcached get method arguments mismatch, must only one arguments. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url);
|
||||
}
|
||||
return new RpcResult(memcachedClient.get(String.valueOf(invocation.getArguments()[0])));
|
||||
} else if (set.equals(invocation.getMethodName())) {
|
||||
if (invocation.getArguments().length != 2) {
|
||||
throw new IllegalArgumentException("The memcached set method arguments mismatch, must be two arguments. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url);
|
||||
}
|
||||
memcachedClient.set(String.valueOf(invocation.getArguments()[0]), expiry, invocation.getArguments()[1]);
|
||||
return new RpcResult();
|
||||
} else if (delete.equals(invocation.getMethodName())) {
|
||||
if (invocation.getArguments().length != 1) {
|
||||
throw new IllegalArgumentException("The memcached delete method arguments mismatch, must only one arguments. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url);
|
||||
}
|
||||
memcachedClient.delete(String.valueOf(invocation.getArguments()[0]));
|
||||
return new RpcResult();
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Unsupported method " + invocation.getMethodName() + " in memcached service.");
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
RpcException re = new RpcException("Failed to invoke memecached service method. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url + ", cause: " + t.getMessage(), t);
|
||||
if (t instanceof TimeoutException || t instanceof SocketTimeoutException) {
|
||||
re.setCode(RpcException.TIMEOUT_EXCEPTION);
|
||||
} else if (t instanceof MemcachedException || t instanceof IOException) {
|
||||
re.setCode(RpcException.NETWORK_EXCEPTION);
|
||||
}
|
||||
throw re;
|
||||
}
|
||||
}
|
||||
public void destroy() {
|
||||
super.destroy();
|
||||
try {
|
||||
memcachedClient.shutdown();
|
||||
} catch (Throwable e) {
|
||||
logger.warn(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
};
|
||||
} catch (Throwable t) {
|
||||
throw new RpcException("Failed to refer memecached service. interface: " + type.getName() + ", url: " + url + ", cause: " + t.getMessage(), t);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
com.alibaba.dubbo.rpc.protocol.memcached.MemcachedProtocol
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
<!--
|
||||
- Copyright 1999-2011 Alibaba Group.
|
||||
-
|
||||
- Licensed 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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>dubbo-rpc</artifactId>
|
||||
<version>2.3.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>dubbo-rpc-redis</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>${project.artifactId}</name>
|
||||
<description>The redis rpc module of dubbo project</description>
|
||||
<properties>
|
||||
<skip_maven_deploy>true</skip_maven_deploy>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>dubbo-rpc-api</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>redis.clients</groupId>
|
||||
<artifactId>jedis</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
@ -1,155 +0,0 @@
|
|||
/*
|
||||
* Copyright 1999-2012 Alibaba Group.
|
||||
*
|
||||
* Licensed 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.alibaba.dubbo.rpc.protocol.redis;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.apache.commons.pool.impl.GenericObjectPool;
|
||||
|
||||
import redis.clients.jedis.JedisPool;
|
||||
import redis.clients.jedis.exceptions.JedisConnectionException;
|
||||
import redis.clients.jedis.exceptions.JedisDataException;
|
||||
|
||||
import com.alibaba.dubbo.common.Constants;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.common.extension.ExtensionLoader;
|
||||
import com.alibaba.dubbo.common.serialize.ObjectInput;
|
||||
import com.alibaba.dubbo.common.serialize.ObjectOutput;
|
||||
import com.alibaba.dubbo.common.serialize.Serialization;
|
||||
import com.alibaba.dubbo.rpc.Exporter;
|
||||
import com.alibaba.dubbo.rpc.Invocation;
|
||||
import com.alibaba.dubbo.rpc.Invoker;
|
||||
import com.alibaba.dubbo.rpc.Result;
|
||||
import com.alibaba.dubbo.rpc.RpcException;
|
||||
import com.alibaba.dubbo.rpc.RpcResult;
|
||||
import com.alibaba.dubbo.rpc.protocol.AbstractInvoker;
|
||||
import com.alibaba.dubbo.rpc.protocol.AbstractProtocol;
|
||||
|
||||
|
||||
/**
|
||||
* RedisProtocol
|
||||
*
|
||||
* @author william.liangf
|
||||
*/
|
||||
public class RedisProtocol extends AbstractProtocol {
|
||||
|
||||
public static final int DEFAULT_PORT = 6379;
|
||||
|
||||
public int getDefaultPort() {
|
||||
return DEFAULT_PORT;
|
||||
}
|
||||
|
||||
public <T> Exporter<T> export(final Invoker<T> invoker) throws RpcException {
|
||||
throw new UnsupportedOperationException("Unsupported export redis service. url: " + invoker.getUrl());
|
||||
}
|
||||
|
||||
private Serialization getSerialization(URL url) {
|
||||
return ExtensionLoader.getExtensionLoader(Serialization.class).getExtension(url.getParameter(Constants.SERIALIZATION_KEY, "java"));
|
||||
}
|
||||
|
||||
public <T> Invoker<T> refer(final Class<T> type, final URL url) throws RpcException {
|
||||
try {
|
||||
GenericObjectPool.Config config = new GenericObjectPool.Config();
|
||||
config.testOnBorrow = url.getParameter("test.on.borrow", true);
|
||||
config.testOnReturn = url.getParameter("test.on.return", false);
|
||||
config.testWhileIdle = url.getParameter("test.while.idle", false);
|
||||
if (url.getParameter("max.idle", 0) > 0)
|
||||
config.maxIdle = url.getParameter("max.idle", 0);
|
||||
if (url.getParameter("min.idle", 0) > 0)
|
||||
config.minIdle = url.getParameter("min.idle", 0);
|
||||
if (url.getParameter("max.active", 0) > 0)
|
||||
config.maxActive = url.getParameter("max.active", 0);
|
||||
if (url.getParameter("max.wait", 0) > 0)
|
||||
config.maxWait = url.getParameter("max.wait", 0);
|
||||
if (url.getParameter("num.tests.per.eviction.run", 0) > 0)
|
||||
config.numTestsPerEvictionRun = url.getParameter("num.tests.per.eviction.run", 0);
|
||||
if (url.getParameter("time.between.eviction.runs.millis", 0) > 0)
|
||||
config.timeBetweenEvictionRunsMillis = url.getParameter("time.between.eviction.runs.millis", 0);
|
||||
if (url.getParameter("min.evictable.idle.time.millis", 0) > 0)
|
||||
config.minEvictableIdleTimeMillis = url.getParameter("min.evictable.idle.time.millis", 0);
|
||||
final JedisPool jedisPool = new JedisPool(config, url.getHost(), url.getPort(DEFAULT_PORT),
|
||||
url.getParameter(Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT));
|
||||
final int expiry = url.getParameter("expiry", 0);
|
||||
final String get = url.getParameter("get", "get");
|
||||
final String set = url.getParameter("set", Map.class.equals(type) ? "put" : "set");
|
||||
final String delete = url.getParameter("delete", Map.class.equals(type) ? "remove" : "delete");
|
||||
return new AbstractInvoker<T>(type, url) {
|
||||
protected Result doInvoke(Invocation invocation) throws Throwable {
|
||||
try {
|
||||
if (get.equals(invocation.getMethodName())) {
|
||||
if (invocation.getArguments().length != 1) {
|
||||
throw new IllegalArgumentException("The redis get method arguments mismatch, must only one arguments. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url);
|
||||
}
|
||||
byte[] value = jedisPool.getResource().get(String.valueOf(invocation.getArguments()[0]).getBytes());
|
||||
if (value == null) {
|
||||
return new RpcResult();
|
||||
}
|
||||
ObjectInput oin = getSerialization(url).deserialize(url, new ByteArrayInputStream(value));
|
||||
return new RpcResult(oin.readObject());
|
||||
} else if (set.equals(invocation.getMethodName())) {
|
||||
if (invocation.getArguments().length != 2) {
|
||||
throw new IllegalArgumentException("The redis set method arguments mismatch, must be two arguments. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url);
|
||||
}
|
||||
byte[] key = String.valueOf(invocation.getArguments()[0]).getBytes();
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
ObjectOutput value = getSerialization(url).serialize(url, output);
|
||||
value.writeObject(invocation.getArguments()[1]);
|
||||
jedisPool.getResource().set(key, output.toByteArray());
|
||||
if (expiry > 1000) {
|
||||
jedisPool.getResource().expire(key, expiry / 1000);
|
||||
}
|
||||
return new RpcResult();
|
||||
} else if (delete.equals(invocation.getMethodName())) {
|
||||
if (invocation.getArguments().length != 1) {
|
||||
throw new IllegalArgumentException("The redis delete method arguments mismatch, must only one arguments. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url);
|
||||
}
|
||||
jedisPool.getResource().del(String.valueOf(invocation.getArguments()[0]).getBytes());
|
||||
return new RpcResult();
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Unsupported method " + invocation.getMethodName() + " in redis service.");
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
RpcException re = new RpcException("Failed to invoke memecached service method. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url + ", cause: " + t.getMessage(), t);
|
||||
if (t instanceof TimeoutException || t instanceof SocketTimeoutException) {
|
||||
re.setCode(RpcException.TIMEOUT_EXCEPTION);
|
||||
} else if (t instanceof JedisConnectionException || t instanceof IOException) {
|
||||
re.setCode(RpcException.NETWORK_EXCEPTION);
|
||||
} else if (t instanceof JedisDataException) {
|
||||
re.setCode(RpcException.SERIALIZATION_EXCEPTION);
|
||||
}
|
||||
throw re;
|
||||
}
|
||||
}
|
||||
public void destroy() {
|
||||
super.destroy();
|
||||
try {
|
||||
jedisPool.destroy();
|
||||
} catch (Throwable e) {
|
||||
logger.warn(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
};
|
||||
} catch (Throwable t) {
|
||||
throw new RpcException("Failed to refer memecached service. interface: " + type.getName() + ", url: " + url + ", cause: " + t.getMessage(), t);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
com.alibaba.dubbo.rpc.protocol.redis.RedisProtocol
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright 1999-2011 Alibaba Group.
|
||||
*
|
||||
* Licensed 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.alibaba.dubbo.rpc.protocol.rmi;
|
||||
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.registry.Registry;
|
||||
import java.rmi.server.UnicastRemoteObject;
|
||||
|
||||
import com.alibaba.dubbo.common.logger.Logger;
|
||||
import com.alibaba.dubbo.common.logger.LoggerFactory;
|
||||
import com.alibaba.dubbo.rpc.Invoker;
|
||||
import com.alibaba.dubbo.rpc.protocol.AbstractExporter;
|
||||
|
||||
/**
|
||||
* Rmi exporter.
|
||||
*
|
||||
* @author qian.lei
|
||||
*/
|
||||
public class RmiExporter<T> extends AbstractExporter<T> {
|
||||
|
||||
private static final Logger Log = LoggerFactory.getLogger(RmiExporter.class);
|
||||
|
||||
private Remote remote;
|
||||
|
||||
private Registry registry;
|
||||
|
||||
public RmiExporter(Invoker<T> invoker, Remote remote, Registry registry) {
|
||||
super(invoker);
|
||||
this.remote = remote;
|
||||
this.registry = registry;
|
||||
}
|
||||
|
||||
public void unexport() {
|
||||
super.unexport();
|
||||
// unexport.
|
||||
if (remote != null) {
|
||||
try {
|
||||
UnicastRemoteObject.unexportObject(remote, true);
|
||||
} catch (Exception e) {
|
||||
Log.warn("Unexport rmi object error.", e); //ignore it.
|
||||
}
|
||||
remote = null;
|
||||
}
|
||||
if (registry != null) {
|
||||
try {
|
||||
// unbind.
|
||||
registry.unbind(getInvoker().getUrl().getPath());
|
||||
} catch (Exception e) {
|
||||
Log.warn("Unexport rmi object error.", e); //ignore it.
|
||||
}
|
||||
registry = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* Copyright 1999-2011 Alibaba Group.
|
||||
*
|
||||
* Licensed 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.alibaba.dubbo.rpc.protocol.rmi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.rmi.ConnectException;
|
||||
import java.rmi.ConnectIOException;
|
||||
import java.rmi.NoSuchObjectException;
|
||||
import java.rmi.RemoteException;
|
||||
import java.rmi.StubNotFoundException;
|
||||
import java.rmi.UnknownHostException;
|
||||
import java.rmi.registry.Registry;
|
||||
|
||||
import org.omg.CORBA.COMM_FAILURE;
|
||||
import org.omg.CORBA.CompletionStatus;
|
||||
import org.omg.CORBA.NO_RESPONSE;
|
||||
import org.omg.CORBA.SystemException;
|
||||
|
||||
import com.alibaba.dubbo.common.Constants;
|
||||
import com.alibaba.dubbo.rpc.Invocation;
|
||||
import com.alibaba.dubbo.rpc.Invoker;
|
||||
import com.alibaba.dubbo.rpc.Result;
|
||||
import com.alibaba.dubbo.rpc.RpcException;
|
||||
import com.alibaba.dubbo.rpc.protocol.AbstractInvoker;
|
||||
|
||||
/**
|
||||
* RmiInvoker.
|
||||
*
|
||||
* @author qian.lei
|
||||
*/
|
||||
public class RmiInvoker<T> extends AbstractInvoker<T> {
|
||||
|
||||
private Registry registry;
|
||||
|
||||
private RmiProxyFactory rmiProxyFactory;
|
||||
|
||||
private Invoker<T> invoker;
|
||||
|
||||
private boolean reconnect;
|
||||
|
||||
public RmiInvoker(Registry registry, RmiProxyFactory rmiProxyFactory, Invoker<T> invoker) {
|
||||
super(invoker.getInterface(), invoker.getUrl());
|
||||
this.registry = registry;
|
||||
this.rmiProxyFactory = rmiProxyFactory;
|
||||
this.invoker = invoker;
|
||||
this.reconnect = invoker.getUrl().getParameter(Constants.RECONNECT_KEY, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Result doInvoke(Invocation invocation) throws RpcException {
|
||||
Result result = null;
|
||||
try {
|
||||
result = invoker.invoke(invocation);
|
||||
|
||||
// 对Rmi的Connection问题进行重试
|
||||
Throwable e = result.getException();
|
||||
if (e != null && isConnectFailure(e) && reconnect) {
|
||||
invoker = rmiProxyFactory.getInvoker(registry.lookup(invoker.getUrl().getPath()), invoker.getInterface(), invoker.getUrl());
|
||||
result = invoker.invoke(invocation);
|
||||
}
|
||||
} catch (RpcException e) {
|
||||
throw setRpcExceptionCode(e.getCause(), e);
|
||||
} catch (Throwable e) {
|
||||
throw setRpcExceptionCode(e, new RpcException(e.getMessage(), e));
|
||||
}
|
||||
|
||||
Throwable e = result.getException();
|
||||
if (e != null && e instanceof RemoteException) {
|
||||
throw setRpcExceptionCode(e, new RpcException("Failed to invoke remote service: " + getInterface() + ", method: "
|
||||
+ invocation.getMethodName() + ", url: " + invoker.getUrl() + ", cause: " + e.getMessage(), e));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static RpcException setRpcExceptionCode(Throwable e, RpcException re) {
|
||||
if (e != null && e.getCause() != null) {
|
||||
Class<?> cls = e.getCause().getClass();
|
||||
// 是根据测试Case发现的问题,对RpcException.setCode进行设置
|
||||
if (SocketTimeoutException.class.equals(cls)) {
|
||||
re.setCode(RpcException.TIMEOUT_EXCEPTION);
|
||||
} else if (IOException.class.isAssignableFrom(cls)) {
|
||||
re.setCode(RpcException.NETWORK_EXCEPTION);
|
||||
} else if (ClassNotFoundException.class.isAssignableFrom(cls)) {
|
||||
re.setCode(RpcException.SERIALIZATION_EXCEPTION);
|
||||
}
|
||||
}
|
||||
return re;
|
||||
}
|
||||
|
||||
private static final String ORACLE_CONNECTION_EXCEPTION = "com.evermind.server.rmi.RMIConnectionException";
|
||||
|
||||
private static boolean isConnectFailure(Throwable ex) {
|
||||
return (ex instanceof ConnectException || ex instanceof ConnectIOException ||
|
||||
ex instanceof UnknownHostException || ex instanceof NoSuchObjectException ||
|
||||
ex instanceof StubNotFoundException || isCorbaConnectFailure(ex.getCause()) ||
|
||||
ORACLE_CONNECTION_EXCEPTION.equals(ex.getClass().getName()));
|
||||
}
|
||||
|
||||
private static boolean isCorbaConnectFailure(Throwable ex) {
|
||||
return ((ex instanceof COMM_FAILURE || ex instanceof NO_RESPONSE) &&
|
||||
((SystemException) ex).completed == CompletionStatus.COMPLETED_NO);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -15,85 +15,288 @@
|
|||
*/
|
||||
package com.alibaba.dubbo.rpc.protocol.rmi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.rmi.AlreadyBoundException;
|
||||
import java.rmi.NotBoundException;
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
import java.rmi.registry.LocateRegistry;
|
||||
import java.rmi.registry.Registry;
|
||||
import java.rmi.server.UnicastRemoteObject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javassist.CannotCompileException;
|
||||
import javassist.ClassPool;
|
||||
import javassist.CtClass;
|
||||
import javassist.CtNewMethod;
|
||||
import javassist.NotFoundException;
|
||||
import javassist.bytecode.Descriptor;
|
||||
|
||||
import org.springframework.remoting.RemoteAccessException;
|
||||
import org.springframework.remoting.rmi.RmiProxyFactoryBean;
|
||||
import org.springframework.remoting.rmi.RmiServiceExporter;
|
||||
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.common.bytecode.ClassGenerator;
|
||||
import com.alibaba.dubbo.rpc.Exporter;
|
||||
import com.alibaba.dubbo.rpc.Invocation;
|
||||
import com.alibaba.dubbo.rpc.Invoker;
|
||||
import com.alibaba.dubbo.rpc.ProxyFactory;
|
||||
import com.alibaba.dubbo.rpc.Result;
|
||||
import com.alibaba.dubbo.rpc.RpcException;
|
||||
import com.alibaba.dubbo.rpc.protocol.AbstractProxyProtocol;
|
||||
import com.alibaba.dubbo.rpc.RpcResult;
|
||||
import com.alibaba.dubbo.rpc.protocol.AbstractProtocol;
|
||||
|
||||
/**
|
||||
* RmiProtocol.
|
||||
*
|
||||
* @author qian.lei
|
||||
*/
|
||||
public class RmiProtocol extends AbstractProxyProtocol {
|
||||
public class RmiProtocol extends AbstractProtocol {
|
||||
|
||||
public static final int DEFAULT_PORT = 1099;
|
||||
|
||||
public RmiProtocol() {
|
||||
super(RemoteAccessException.class, RemoteException.class);
|
||||
private final Map<Integer, Registry> registryMap = new ConcurrentHashMap<Integer, Registry>();
|
||||
|
||||
private ProxyFactory proxyFactory;
|
||||
|
||||
private RmiProxyFactory rmiProxyFactory;
|
||||
|
||||
public void setProxyFactory(ProxyFactory proxyFactory) {
|
||||
this.proxyFactory = proxyFactory;
|
||||
}
|
||||
|
||||
public void setRmiProxyFactory(RmiProxyFactory rmiProxyFactory) {
|
||||
this.rmiProxyFactory = rmiProxyFactory;
|
||||
}
|
||||
|
||||
public int getDefaultPort() {
|
||||
return DEFAULT_PORT;
|
||||
}
|
||||
|
||||
protected <T> Runnable doExport(final T impl, Class<T> type, URL url) throws RpcException {
|
||||
final RmiServiceExporter rmiServiceExporter = new RmiServiceExporter();
|
||||
rmiServiceExporter.setRegistryPort(url.getPort());
|
||||
rmiServiceExporter.setServiceName(url.getPath());
|
||||
rmiServiceExporter.setServiceInterface(type);
|
||||
rmiServiceExporter.setService(impl);
|
||||
try {
|
||||
rmiServiceExporter.afterPropertiesSet();
|
||||
} catch (RemoteException e) {
|
||||
throw new RpcException(e.getMessage(), e);
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> Class<T> getRemoteClass(Class<T> type) {
|
||||
if (Remote.class.isAssignableFrom(type)) {
|
||||
return type;
|
||||
}
|
||||
return new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
rmiServiceExporter.destroy();
|
||||
} catch (Throwable e) {
|
||||
logger.warn(e.getMessage(), e);
|
||||
try {
|
||||
String remoteType = type.getName() + "$Remote";
|
||||
try {
|
||||
return (Class<T>) Class.forName(remoteType, true, type.getClassLoader());
|
||||
} catch (ClassNotFoundException e) {
|
||||
ClassPool pool = ClassGenerator.getClassPool(type.getClassLoader());
|
||||
CtClass ctClass = pool.makeInterface(remoteType);
|
||||
ctClass.addInterface(getCtClass(pool, Remote.class.getName()));
|
||||
Method[] methods = type.getMethods();
|
||||
for (Method method : methods) {
|
||||
CtClass[] parameters = new CtClass[method.getParameterTypes().length];
|
||||
int i = 0;
|
||||
for (Class<?> pt : method.getParameterTypes()) {
|
||||
parameters[i++] = getCtClass(pool, pt.getCanonicalName());
|
||||
}
|
||||
CtClass[] exceptions = new CtClass[method.getExceptionTypes().length + 1];
|
||||
exceptions[0] = getCtClass(pool, RemoteException.class.getName());
|
||||
i = 1;
|
||||
for (Class<?> et : method.getExceptionTypes()) {
|
||||
exceptions[i++] = getCtClass(pool, et.getCanonicalName());
|
||||
}
|
||||
ctClass.addMethod(CtNewMethod.abstractMethod(
|
||||
getCtClass(pool, method.getReturnType().getCanonicalName()),
|
||||
method.getName(), parameters, exceptions, ctClass));
|
||||
}
|
||||
return ctClass.toClass();
|
||||
}
|
||||
} catch (CannotCompileException e) {
|
||||
throw new IllegalStateException(e.getMessage(), e);
|
||||
} catch (NotFoundException e) {
|
||||
throw new IllegalStateException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
//fix javassist version problem (getCtClass is since 3.8.5 ,jboss )
|
||||
private static CtClass getCtClass(ClassPool pool, String classname) throws NotFoundException{
|
||||
if (classname.charAt(0) == '[')
|
||||
return Descriptor.toCtClass(classname, pool);
|
||||
else
|
||||
return pool.get(classname);
|
||||
}
|
||||
|
||||
public <T> Exporter<T> export(final Invoker<T> invoker) throws RpcException {
|
||||
if (! Remote.class.isAssignableFrom(invoker.getInterface())
|
||||
&& "spring".equals(invoker.getUrl().getParameter("codec", "spring"))) {
|
||||
final RmiServiceExporter rmiServiceExporter = new RmiServiceExporter();
|
||||
rmiServiceExporter.setRegistryPort(invoker.getUrl().getPort());
|
||||
rmiServiceExporter.setServiceName(invoker.getUrl().getPath());
|
||||
rmiServiceExporter.setServiceInterface(invoker.getInterface());
|
||||
rmiServiceExporter.setService(proxyFactory.getProxy(invoker));
|
||||
try {
|
||||
rmiServiceExporter.afterPropertiesSet();
|
||||
} catch (RemoteException e) {
|
||||
throw new RpcException(e.getMessage(), e);
|
||||
}
|
||||
Exporter<T> exporter = new Exporter<T>() {
|
||||
public Invoker<T> getInvoker() {
|
||||
return invoker;
|
||||
}
|
||||
public void unexport() {
|
||||
try {
|
||||
rmiServiceExporter.destroy();
|
||||
} catch (Throwable e) {
|
||||
logger.warn(e.getMessage(), e);
|
||||
}
|
||||
try {
|
||||
invoker.destroy();
|
||||
} catch (Throwable e) {
|
||||
logger.warn(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
};
|
||||
return exporter;
|
||||
} else {
|
||||
Remote remote = rmiProxyFactory.getProxy(invoker);
|
||||
// export.
|
||||
try {
|
||||
UnicastRemoteObject.exportObject(remote, 0);
|
||||
} catch (RemoteException e) {
|
||||
if ("object already exported".equalsIgnoreCase(e.getMessage())) {
|
||||
logger.warn("Ignore 'object already exported' exception.", e);
|
||||
} else {
|
||||
throw new RpcException("Export rmi service error.", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T> T doRefer(final Class<T> serviceType, final URL url) throws RpcException {
|
||||
final RmiProxyFactoryBean rmiProxyFactoryBean = new RmiProxyFactoryBean();
|
||||
rmiProxyFactoryBean.setServiceUrl(url.toIdentityString());
|
||||
rmiProxyFactoryBean.setServiceInterface(serviceType);
|
||||
rmiProxyFactoryBean.setCacheStub(true);
|
||||
rmiProxyFactoryBean.setLookupStubOnStartup(true);
|
||||
rmiProxyFactoryBean.setRefreshStubOnConnectFailure(true);
|
||||
rmiProxyFactoryBean.afterPropertiesSet();
|
||||
return (T) rmiProxyFactoryBean.getObject();
|
||||
}
|
||||
|
||||
protected int getErrorCode(Throwable e) {
|
||||
if (e instanceof RemoteAccessException) {
|
||||
e = e.getCause();
|
||||
// register.
|
||||
Registry registry = getOrCreateRegistry(invoker.getUrl().getPort());
|
||||
try {
|
||||
// bind service.
|
||||
registry.bind(invoker.getUrl().getPath(), remote);
|
||||
} catch (RemoteException e) {
|
||||
throw new RpcException("Bind rmi service [" + invoker.getUrl().getPath() + "] error.",
|
||||
e);
|
||||
} catch (AlreadyBoundException e) {
|
||||
throw new RpcException("Bind rmi service error. Service name ["
|
||||
+ invoker.getUrl().getPath() + "] already bound.", e);
|
||||
}
|
||||
RmiExporter<T> exporter = new RmiExporter<T>(invoker, remote, registry);
|
||||
exporterMap.put(serviceKey(invoker.getUrl()), exporter);
|
||||
return exporter;
|
||||
}
|
||||
if (e != null && e.getCause() != null) {
|
||||
Class<?> cls = e.getCause().getClass();
|
||||
// 是根据测试Case发现的问题,对RpcException.setCode进行设置
|
||||
if (SocketTimeoutException.class.equals(cls)) {
|
||||
return RpcException.TIMEOUT_EXCEPTION;
|
||||
} else if (IOException.class.isAssignableFrom(cls)) {
|
||||
return RpcException.NETWORK_EXCEPTION;
|
||||
} else if (ClassNotFoundException.class.isAssignableFrom(cls)) {
|
||||
return RpcException.SERIALIZATION_EXCEPTION;
|
||||
}
|
||||
|
||||
public <T> Invoker<T> refer(final Class<T> serviceType, final URL url) throws RpcException {
|
||||
if (! Remote.class.isAssignableFrom(serviceType)
|
||||
&& "spring".equals(url.getParameter("codec", "spring"))) {
|
||||
final RmiProxyFactoryBean rmiProxyFactoryBean = new RmiProxyFactoryBean();
|
||||
rmiProxyFactoryBean.setServiceUrl(url.toIdentityString());
|
||||
rmiProxyFactoryBean.setServiceInterface(serviceType);
|
||||
rmiProxyFactoryBean.setCacheStub(true);
|
||||
rmiProxyFactoryBean.setLookupStubOnStartup(true);
|
||||
rmiProxyFactoryBean.setRefreshStubOnConnectFailure(true);
|
||||
rmiProxyFactoryBean.afterPropertiesSet();
|
||||
final Object remoteObject = rmiProxyFactoryBean.getObject();
|
||||
return new Invoker<T>() {
|
||||
public Class<T> getInterface() {
|
||||
return serviceType;
|
||||
}
|
||||
public URL getUrl() {
|
||||
return url;
|
||||
}
|
||||
public boolean isAvailable() {
|
||||
return true;
|
||||
}
|
||||
public Result invoke(Invocation invocation) throws RpcException {
|
||||
try {
|
||||
return new RpcResult(remoteObject.getClass().getMethod(invocation.getMethodName(), invocation.getParameterTypes()).invoke(remoteObject, invocation.getArguments()));
|
||||
} catch (InvocationTargetException e) {
|
||||
Throwable t = e.getTargetException();
|
||||
if (t instanceof RemoteAccessException) {
|
||||
t = ((RemoteAccessException)t).getCause();
|
||||
}
|
||||
if (t instanceof RemoteException) {
|
||||
throw RmiInvoker.setRpcExceptionCode(t, new RpcException("Failed to invoke remote service: " + serviceType + ", method: "
|
||||
+ invocation.getMethodName() + ", url: " + url + ", cause: " + t.getMessage(), t));
|
||||
} else {
|
||||
return new RpcResult(t);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
if (e instanceof RemoteAccessException) {
|
||||
e = ((RemoteAccessException)e).getCause();
|
||||
}
|
||||
throw RmiInvoker.setRpcExceptionCode(e, new RpcException("Failed to invoke remote service: " + serviceType + ", method: "
|
||||
+ invocation.getMethodName() + ", url: " + url + ", cause: " + e.getMessage(), e));
|
||||
}
|
||||
}
|
||||
public void destroy() {
|
||||
}
|
||||
};
|
||||
} else {
|
||||
Invoker<T> invoker;
|
||||
try {
|
||||
if ("dubbo".equals(url.getParameter("codec"))) {
|
||||
RmiProtocol.getRemoteClass(serviceType);
|
||||
}
|
||||
Registry registry = LocateRegistry.getRegistry(url.getHost(), url.getPort());
|
||||
String path = url.getPath();
|
||||
if (path == null || path.length() == 0) {
|
||||
path = serviceType.getName();
|
||||
}
|
||||
invoker = new RmiInvoker<T>(registry, rmiProxyFactory, rmiProxyFactory.getInvoker(registry.lookup(path), serviceType, url));
|
||||
} catch (RemoteException e) {
|
||||
Throwable cause = e.getCause();
|
||||
boolean isExportedBySpringButNoSpringClass = ClassNotFoundException.class
|
||||
.isInstance(cause)
|
||||
&& cause.getMessage().contains(
|
||||
"org.springframework.remoting.rmi.RmiInvocationHandler");
|
||||
|
||||
String msg = String
|
||||
.format("Can not create remote object%s. url = %s",
|
||||
isExportedBySpringButNoSpringClass ? "(Rmi object is exported by spring rmi but NO spring class org.springframework.remoting.rmi.RmiInvocationHandler at consumer side)"
|
||||
: "", url);
|
||||
throw new RpcException(msg, e);
|
||||
} catch (NotBoundException e) {
|
||||
throw new RpcException("Rmi service not found. url = " + url, e);
|
||||
}
|
||||
invokers.add(invoker);
|
||||
return invoker;
|
||||
}
|
||||
}
|
||||
|
||||
protected Registry getOrCreateRegistry(int port) {
|
||||
Registry registry = registryMap.get(port);
|
||||
if (registry == null) {
|
||||
try {
|
||||
registry = LocateRegistry.createRegistry(port);
|
||||
} catch (RemoteException e) {
|
||||
throw new IllegalStateException("Failed to create rmi registry on port " + port
|
||||
+ ", cause: " + e.getMessage(), e);
|
||||
}
|
||||
registryMap.put(port, registry);
|
||||
}
|
||||
return registry;
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
super.destroy();
|
||||
for (Integer key : new ArrayList<Integer>(registryMap.keySet())) {
|
||||
Registry registry = registryMap.remove(key);
|
||||
if (registry != null) {
|
||||
try {
|
||||
String[] services = registry.list();
|
||||
if (services != null && services.length > 0) {
|
||||
for (String service : services) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Unbind rmi service: " + service);
|
||||
}
|
||||
registry.unbind(service);
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
logger.warn(t.getMessage(), t);
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.getErrorCode(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 1999-2012 Alibaba Group.
|
||||
* Copyright 1999-2011 Alibaba Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -13,15 +13,26 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.examples.annotation.api;
|
||||
package com.alibaba.dubbo.rpc.protocol.rmi;
|
||||
|
||||
import java.rmi.Remote;
|
||||
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.common.extension.SPI;
|
||||
import com.alibaba.dubbo.rpc.Invoker;
|
||||
|
||||
/**
|
||||
* AsyncService
|
||||
* RmiProxyFactory
|
||||
*
|
||||
* @author william.liangf
|
||||
*/
|
||||
public interface AnnotationService {
|
||||
|
||||
String sayHello(String name);
|
||||
@SPI
|
||||
public interface RmiProxyFactory {
|
||||
|
||||
}
|
||||
<T> Remote getProxy(Invoker<T> invoker);
|
||||
|
||||
<T> Invoker<T> getInvoker(Remote remote, Class<T> serviceType, URL url);
|
||||
|
||||
boolean isSupported(Remote remote, Class<?> serviceType, URL url);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* Copyright 1999-2011 Alibaba Group.
|
||||
*
|
||||
* Licensed 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.alibaba.dubbo.rpc.protocol.rmi.proxy;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
import java.rmi.server.RemoteServer;
|
||||
import java.rmi.server.ServerNotActiveException;
|
||||
|
||||
import javassist.CannotCompileException;
|
||||
import javassist.ClassPool;
|
||||
import javassist.CtClass;
|
||||
import javassist.CtNewMethod;
|
||||
import javassist.NotFoundException;
|
||||
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.common.bytecode.ClassGenerator;
|
||||
import com.alibaba.dubbo.rpc.Invocation;
|
||||
import com.alibaba.dubbo.rpc.Invoker;
|
||||
import com.alibaba.dubbo.rpc.ProxyFactory;
|
||||
import com.alibaba.dubbo.rpc.Result;
|
||||
import com.alibaba.dubbo.rpc.RpcContext;
|
||||
import com.alibaba.dubbo.rpc.RpcException;
|
||||
import com.alibaba.dubbo.rpc.protocol.rmi.RmiProxyFactory;
|
||||
|
||||
/**
|
||||
* DubboRmiProxyFactory
|
||||
*
|
||||
* @author william.liangf
|
||||
*/
|
||||
public class DubboRmiProxyFactory implements RmiProxyFactory {
|
||||
|
||||
private ProxyFactory proxyFactory;
|
||||
|
||||
public void setProxyFactory(ProxyFactory proxyFactory) {
|
||||
this.proxyFactory = proxyFactory;
|
||||
}
|
||||
|
||||
public boolean isSupported(Remote remote, Class<?> serviceType, URL url) {
|
||||
for (Class<?> i : remote.getClass().getInterfaces()) {
|
||||
if (i.getName().endsWith("$Remote")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public <T> Remote getProxy(final Invoker<T> invoker) {
|
||||
final Class<T> remoteClass = getRemoteClass(invoker.getInterface());
|
||||
return (Remote) proxyFactory.getProxy(new Invoker<T>() {
|
||||
public Class<T> getInterface() {
|
||||
return remoteClass;
|
||||
}
|
||||
|
||||
public URL getUrl() {
|
||||
return invoker.getUrl();
|
||||
}
|
||||
|
||||
public boolean isAvailable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Result invoke(Invocation invocation) throws RpcException {
|
||||
String client = null;
|
||||
try {
|
||||
client = RemoteServer.getClientHost();
|
||||
} catch (ServerNotActiveException e) {
|
||||
// Ignore it.
|
||||
}
|
||||
RpcContext.getContext().setRemoteAddress(client, 0);
|
||||
return invoker.invoke(invocation);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> Invoker<T> getInvoker(Remote remote, Class<T> serviceType, URL url) {
|
||||
return proxyFactory.getInvoker((T) remote, serviceType, url);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> Class<T> getRemoteClass(Class<T> type) {
|
||||
if (Remote.class.isAssignableFrom(type)) {
|
||||
return type;
|
||||
}
|
||||
try {
|
||||
String remoteType = type.getName() + "$Remote";
|
||||
try {
|
||||
return (Class<T>) Class.forName(remoteType, true, type.getClassLoader());
|
||||
} catch (ClassNotFoundException e) {
|
||||
ClassPool pool = ClassGenerator.getClassPool(type.getClassLoader());
|
||||
CtClass ctClass = pool.makeInterface(remoteType);
|
||||
// ctClass.addInterface(pool.getCtClass(type.getName()));
|
||||
ctClass.addInterface(pool.getCtClass(Remote.class.getName()));
|
||||
Method[] methods = type.getMethods();
|
||||
for (Method method : methods) {
|
||||
CtClass[] parameters = new CtClass[method.getParameterTypes().length];
|
||||
int i = 0;
|
||||
for (Class<?> pt : method.getParameterTypes()) {
|
||||
parameters[i++] = pool.getCtClass(pt.getCanonicalName());
|
||||
}
|
||||
CtClass[] exceptions = new CtClass[method.getExceptionTypes().length + 1];
|
||||
exceptions[0] = pool.getCtClass(RemoteException.class.getName());
|
||||
i = 1;
|
||||
for (Class<?> et : method.getExceptionTypes()) {
|
||||
exceptions[i++] = pool.getCtClass(et.getCanonicalName());
|
||||
}
|
||||
ctClass.addMethod(CtNewMethod.abstractMethod(
|
||||
pool.getCtClass(method.getReturnType().getCanonicalName()),
|
||||
method.getName(), parameters, exceptions, ctClass));
|
||||
}
|
||||
return ctClass.toClass();
|
||||
}
|
||||
} catch (CannotCompileException e) {
|
||||
throw new IllegalStateException(e.getMessage(), e);
|
||||
} catch (NotFoundException e) {
|
||||
throw new IllegalStateException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright 1999-2011 Alibaba Group.
|
||||
*
|
||||
* Licensed 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.alibaba.dubbo.rpc.protocol.rmi.proxy;
|
||||
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.server.RemoteServer;
|
||||
import java.rmi.server.ServerNotActiveException;
|
||||
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.rpc.Invocation;
|
||||
import com.alibaba.dubbo.rpc.Invoker;
|
||||
import com.alibaba.dubbo.rpc.ProxyFactory;
|
||||
import com.alibaba.dubbo.rpc.Result;
|
||||
import com.alibaba.dubbo.rpc.RpcContext;
|
||||
import com.alibaba.dubbo.rpc.RpcException;
|
||||
import com.alibaba.dubbo.rpc.protocol.rmi.RmiProxyFactory;
|
||||
|
||||
/**
|
||||
* DefaultProxyFactoryAdaptive
|
||||
*
|
||||
* @author william.liangf
|
||||
*/
|
||||
public class NativeProxyFactory implements RmiProxyFactory {
|
||||
|
||||
private ProxyFactory proxyFactory;
|
||||
|
||||
public void setProxyFactory(ProxyFactory proxyFactory) {
|
||||
this.proxyFactory = proxyFactory;
|
||||
}
|
||||
|
||||
public <T> Remote getProxy(final Invoker<T> invoker) {
|
||||
return (Remote) proxyFactory.getProxy(new Invoker<T>() {
|
||||
public Class<T> getInterface() {
|
||||
return invoker.getInterface();
|
||||
}
|
||||
|
||||
public URL getUrl() {
|
||||
return invoker.getUrl();
|
||||
}
|
||||
|
||||
public boolean isAvailable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Result invoke(Invocation invocation) throws RpcException {
|
||||
String client = null;
|
||||
try {
|
||||
client = RemoteServer.getClientHost();
|
||||
} catch (ServerNotActiveException e) {
|
||||
// Ignore it.
|
||||
}
|
||||
RpcContext.getContext().setRemoteAddress(client, 0);
|
||||
return invoker.invoke(invocation);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean isSupported(Remote remote, Class<?> serviceType, URL url) {
|
||||
return Remote.class.isAssignableFrom(serviceType) && serviceType.isInstance(remote);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> Invoker<T> getInvoker(Remote remote, Class<T> serviceType, URL url) {
|
||||
return proxyFactory.getInvoker((T) remote, serviceType, url);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright 1999-2011 Alibaba Group.
|
||||
*
|
||||
* Licensed 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.alibaba.dubbo.rpc.protocol.rmi.proxy;
|
||||
|
||||
import java.rmi.Remote;
|
||||
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.common.extension.Adaptive;
|
||||
import com.alibaba.dubbo.common.extension.ExtensionLoader;
|
||||
import com.alibaba.dubbo.rpc.Invoker;
|
||||
import com.alibaba.dubbo.rpc.protocol.rmi.RmiProxyFactory;
|
||||
|
||||
/**
|
||||
* RmiProxyFactoryAdaptive
|
||||
*
|
||||
* @author william.liangf
|
||||
*/
|
||||
@Adaptive
|
||||
public class RmiProxyFactoryAdaptive implements RmiProxyFactory {
|
||||
|
||||
public <T> Remote getProxy(Invoker<T> invoker) {
|
||||
ExtensionLoader<RmiProxyFactory> extensionLoader = ExtensionLoader.getExtensionLoader(RmiProxyFactory.class);
|
||||
String name = invoker.getUrl().getParameter("codec", "spring");
|
||||
if (name != null && name.length() > 0 && ! extensionLoader.hasExtension(name)) {
|
||||
throw new IllegalArgumentException("Unsupported protocol codec " + name
|
||||
+ " for protocol RMI, Only support: " + extensionLoader.getSupportedExtensions());
|
||||
}
|
||||
if (Remote.class.isAssignableFrom(invoker.getInterface())) {
|
||||
name = "native";
|
||||
}
|
||||
return extensionLoader.getExtension(name).getProxy(invoker);
|
||||
}
|
||||
|
||||
public <T> Invoker<T> getInvoker(Remote remote, Class<T> serviceType, URL url) {
|
||||
ExtensionLoader<RmiProxyFactory> extensionLoader = ExtensionLoader.getExtensionLoader(RmiProxyFactory.class);
|
||||
for (String name : extensionLoader.getSupportedExtensions()) {
|
||||
RmiProxyFactory rmiProxyFactory = extensionLoader.getExtension(name);
|
||||
if (rmiProxyFactory.isSupported(remote, serviceType, url)) {
|
||||
return rmiProxyFactory.getInvoker(remote, serviceType, url);
|
||||
}
|
||||
}
|
||||
throw new UnsupportedOperationException("Unsupported remote stub " + remote + " by type " + extensionLoader.getSupportedExtensions() + ", service: " + serviceType.getName() + ", url" + url);
|
||||
}
|
||||
|
||||
public boolean isSupported(Remote remote, Class<?> serviceType, URL url) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* Copyright 1999-2011 Alibaba Group.
|
||||
*
|
||||
* Licensed 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.alibaba.dubbo.rpc.protocol.rmi.proxy;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
import java.rmi.server.RemoteServer;
|
||||
import java.rmi.server.ServerNotActiveException;
|
||||
|
||||
import org.springframework.remoting.rmi.RmiInvocationHandler;
|
||||
import org.springframework.remoting.support.RemoteInvocation;
|
||||
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.common.utils.ReflectUtils;
|
||||
import com.alibaba.dubbo.common.utils.StringUtils;
|
||||
import com.alibaba.dubbo.rpc.Invocation;
|
||||
import com.alibaba.dubbo.rpc.Invoker;
|
||||
import com.alibaba.dubbo.rpc.Result;
|
||||
import com.alibaba.dubbo.rpc.RpcContext;
|
||||
import com.alibaba.dubbo.rpc.RpcException;
|
||||
import com.alibaba.dubbo.rpc.RpcInvocation;
|
||||
import com.alibaba.dubbo.rpc.RpcResult;
|
||||
import com.alibaba.dubbo.rpc.protocol.rmi.RmiProxyFactory;
|
||||
|
||||
/**
|
||||
* SpringRmiProxyFactory
|
||||
*
|
||||
* @author william.liangf
|
||||
*/
|
||||
public class SpringRmiProxyFactory implements RmiProxyFactory {
|
||||
|
||||
public boolean isSupported(Remote remote, Class<?> serviceType, URL url) {
|
||||
return ReflectUtils.isInstance(remote, "org.springframework.remoting.rmi.RmiInvocationHandler");
|
||||
}
|
||||
|
||||
private static void assertRmiInvocationHandler() {
|
||||
try {
|
||||
Class.forName("org.springframework.remoting.rmi.RmiInvocationHandler");
|
||||
} catch (ClassNotFoundException e1) {
|
||||
throw new RpcException(
|
||||
"set codec spring for protocol rmi,"
|
||||
+ " but NO spring class org.springframework.remoting.rmi.RmiInvocationHandler at provider side!");
|
||||
}
|
||||
}
|
||||
|
||||
public <T> Remote getProxy(final Invoker<T> invoker) {
|
||||
assertRmiInvocationHandler();
|
||||
return new org.springframework.remoting.rmi.RmiInvocationHandler() {
|
||||
public Object invoke(RemoteInvocation invocation) throws RemoteException,
|
||||
NoSuchMethodException, IllegalAccessException, InvocationTargetException {
|
||||
String client = null;
|
||||
try {
|
||||
client = RemoteServer.getClientHost();
|
||||
} catch (ServerNotActiveException e) {
|
||||
// Ignore it.
|
||||
}
|
||||
Invocation inv = new RpcInvocation(invocation.getMethodName(),
|
||||
invocation.getParameterTypes(), invocation.getArguments());
|
||||
try {
|
||||
RpcContext.getContext().setRemoteAddress(client, 0);
|
||||
return invoker.invoke(inv).recreate();
|
||||
} catch (RpcException e) {
|
||||
throw new RemoteException(StringUtils.toString(e));
|
||||
} catch (Throwable t) {
|
||||
throw new InvocationTargetException(t);
|
||||
}
|
||||
}
|
||||
public String getTargetInterfaceName() throws RemoteException {
|
||||
return invoker.getInterface().getName();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public <T> Invoker<T> getInvoker(final Remote remote, final Class<T> serviceType, final URL url) {
|
||||
assertRmiInvocationHandler();
|
||||
return new Invoker<T>() {
|
||||
public Class<T> getInterface() {
|
||||
return serviceType;
|
||||
}
|
||||
|
||||
public URL getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public boolean isAvailable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Result invoke(Invocation invocation) throws RpcException {
|
||||
RpcResult result = new RpcResult();
|
||||
try {
|
||||
RemoteInvocation i = new RemoteInvocation();
|
||||
i.setMethodName(invocation.getMethodName());
|
||||
i.setParameterTypes(invocation.getParameterTypes());
|
||||
i.setArguments(invocation.getArguments());
|
||||
result.setValue(((RmiInvocationHandler) remote).invoke(i));
|
||||
} catch (InvocationTargetException e) {
|
||||
result.setException(e.getTargetException());
|
||||
} catch (Exception e) {
|
||||
throw new RpcException(StringUtils.toString(e), e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
adaptive=com.alibaba.dubbo.rpc.protocol.rmi.proxy.RmiProxyFactoryAdaptive
|
||||
native=com.alibaba.dubbo.rpc.protocol.rmi.proxy.NativeProxyFactory
|
||||
dubbo=com.alibaba.dubbo.rpc.protocol.rmi.proxy.DubboRmiProxyFactory
|
||||
spring=com.alibaba.dubbo.rpc.protocol.rmi.proxy.SpringRmiProxyFactory
|
||||
|
|
@ -38,13 +38,13 @@ public class RmiProtocolTest
|
|||
public static interface NonStdRmiInterface {
|
||||
void bark();
|
||||
}
|
||||
/*
|
||||
|
||||
@Test
|
||||
public void test_getRemoteClass() throws Exception {
|
||||
Class<NonStdRmiInterface> clazz = RmiProtocol.getRemoteClass(NonStdRmiInterface.class);
|
||||
assertEquals(clazz, RmiProtocol.getRemoteClass(NonStdRmiInterface.class));
|
||||
}
|
||||
*/
|
||||
|
||||
@Test
|
||||
public void testRmiProtocolTimeout() throws Exception
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,63 +0,0 @@
|
|||
<!--
|
||||
- Copyright 1999-2011 Alibaba Group.
|
||||
-
|
||||
- Licensed 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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>dubbo-rpc</artifactId>
|
||||
<version>2.3.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>dubbo-rpc-thrift</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>${project.artifactId}</name>
|
||||
<description>The thrift rpc module of dubbo project</description>
|
||||
<properties>
|
||||
<skip_maven_deploy>true</skip_maven_deploy>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>dubbo-rpc-api</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>dubbo-rpc-default</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>dubbo-remoting-api</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>dubbo-remoting-netty</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.thrift</groupId>
|
||||
<artifactId>libthrift</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring</artifactId>
|
||||
<scope>provided</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
/**
|
||||
* File Created at 2012-02-02
|
||||
* $Id$
|
||||
*
|
||||
* Copyright 2008 Alibaba.com Croporation Limited.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is the confidential and proprietary information of
|
||||
* Alibaba Company. ("Confidential Information"). You shall not
|
||||
* disclose such Confidential Information and shall use it only in
|
||||
* accordance with the terms of the license agreement you entered into
|
||||
* with Alibaba.com.
|
||||
*/
|
||||
package com.alibaba.dubbo.rpc.protocol.thrift;
|
||||
|
||||
import com.alibaba.dubbo.common.extension.SPI;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:gang.lvg@alibaba-inc.com">kimi</a>
|
||||
*/
|
||||
@SPI( DubboClassNameGenerator.NAME )
|
||||
public interface ClassNameGenerator {
|
||||
|
||||
public String generateArgsClassName( String serviceName, String methodName );
|
||||
|
||||
public String generateResultClassName( String serviceName, String methodName );
|
||||
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
/**
|
||||
* File Created at 2012-02-02
|
||||
* $Id$
|
||||
*
|
||||
* Copyright 2008 Alibaba.com Croporation Limited.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is the confidential and proprietary information of
|
||||
* Alibaba Company. ("Confidential Information"). You shall not
|
||||
* disclose such Confidential Information and shall use it only in
|
||||
* accordance with the terms of the license agreement you entered into
|
||||
* with Alibaba.com.
|
||||
*/
|
||||
package com.alibaba.dubbo.rpc.protocol.thrift;
|
||||
|
||||
import com.alibaba.dubbo.common.Extension;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:gang.lvg@alibaba-inc.com">kimi</a>
|
||||
*/
|
||||
@Extension( DubboClassNameGenerator.NAME )
|
||||
public class DubboClassNameGenerator implements ClassNameGenerator {
|
||||
|
||||
public static final String NAME = "dubbo";
|
||||
|
||||
public String generateArgsClassName( String serviceName, String methodName ) {
|
||||
return ThriftUtils.generateMethodArgsClassName( serviceName, methodName );
|
||||
}
|
||||
|
||||
public String generateResultClassName( String serviceName, String methodName ) {
|
||||
return ThriftUtils.generateMethodResultClassName( serviceName, methodName );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
/**
|
||||
* File Created at 2012-02-02
|
||||
* $Id$
|
||||
*
|
||||
* Copyright 2008 Alibaba.com Croporation Limited.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is the confidential and proprietary information of
|
||||
* Alibaba Company. ("Confidential Information"). You shall not
|
||||
* disclose such Confidential Information and shall use it only in
|
||||
* accordance with the terms of the license agreement you entered into
|
||||
* with Alibaba.com.
|
||||
*/
|
||||
package com.alibaba.dubbo.rpc.protocol.thrift;
|
||||
|
||||
import com.alibaba.dubbo.common.Extension;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:gang.lvg@alibaba-inc.com">kimi</a>
|
||||
*/
|
||||
@Extension( ThriftClassNameGenerator.NAME)
|
||||
public class ThriftClassNameGenerator implements ClassNameGenerator {
|
||||
|
||||
public static final String NAME = "thrift";
|
||||
|
||||
public String generateArgsClassName( String serviceName, String methodName ) {
|
||||
return ThriftUtils.generateMethodArgsClassNameThrift( serviceName, methodName );
|
||||
}
|
||||
|
||||
public String generateResultClassName( String serviceName, String methodName ) {
|
||||
return ThriftUtils.generateMethodResultClassNameThrift( serviceName, methodName );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,717 +0,0 @@
|
|||
/**
|
||||
* File Created at 2011-12-05
|
||||
* $Id$
|
||||
*
|
||||
* Copyright 2008 Alibaba.com Croporation Limited.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is the confidential and proprietary information of
|
||||
* Alibaba Company. ("Confidential Information"). You shall not
|
||||
* disclose such Confidential Information and shall use it only in
|
||||
* accordance with the terms of the license agreement you entered into
|
||||
* with Alibaba.com.
|
||||
*/
|
||||
package com.alibaba.dubbo.rpc.protocol.thrift;
|
||||
|
||||
|
||||
import com.alibaba.dubbo.common.Constants;
|
||||
import com.alibaba.dubbo.common.extension.ExtensionLoader;
|
||||
import com.alibaba.dubbo.remoting.Channel;
|
||||
import com.alibaba.dubbo.remoting.Codec;
|
||||
import com.alibaba.dubbo.remoting.exchange.Request;
|
||||
import com.alibaba.dubbo.remoting.exchange.Response;
|
||||
import com.alibaba.dubbo.rpc.RpcException;
|
||||
import com.alibaba.dubbo.rpc.RpcInvocation;
|
||||
import com.alibaba.dubbo.rpc.RpcResult;
|
||||
import com.alibaba.dubbo.rpc.protocol.thrift.io.RandomAccessByteArrayOutputStream;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.thrift.TApplicationException;
|
||||
import org.apache.thrift.TBase;
|
||||
import org.apache.thrift.TException;
|
||||
import org.apache.thrift.TFieldIdEnum;
|
||||
import org.apache.thrift.protocol.TBinaryProtocol;
|
||||
import org.apache.thrift.protocol.TMessage;
|
||||
import org.apache.thrift.protocol.TMessageType;
|
||||
import org.apache.thrift.protocol.TProtocol;
|
||||
import org.apache.thrift.transport.TFramedTransport;
|
||||
import org.apache.thrift.transport.TIOStreamTransport;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* Thrift framed protocol codec.
|
||||
*
|
||||
* <pre>
|
||||
* |<- message header ->|<- message body ->|
|
||||
* +----------------+----------------------+------------------+---------------------------+------------------+
|
||||
* | magic (2 bytes)|message size (4 bytes)|head size(2 bytes)| version (1 byte) | header | message body |
|
||||
* +----------------+----------------------+------------------+---------------------------+------------------+
|
||||
* |<- message size ->|
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* <b>header fields in version 1</b>
|
||||
* <ol>
|
||||
* <li>string - service name</li>
|
||||
* <li>long - dubbo request id</li>
|
||||
* </ol>
|
||||
* </p>
|
||||
*
|
||||
* @author <a href="mailto:gang.lvg@alibaba-inc.com">gang.lvg</a>
|
||||
*/
|
||||
public class ThriftCodec implements Codec {
|
||||
|
||||
private static final AtomicInteger THRIFT_SEQ_ID = new AtomicInteger( 0 );
|
||||
|
||||
private static final ConcurrentMap<String, Class<?>> cachedClass =
|
||||
new ConcurrentHashMap<String, Class<?>>();
|
||||
|
||||
static final ConcurrentMap<Long, RequestData> cachedRequest =
|
||||
new ConcurrentHashMap<Long, RequestData>();
|
||||
|
||||
public static final int MESSAGE_LENGTH_INDEX = 2;
|
||||
|
||||
public static final int MESSAGE_HEADER_LENGTH_INDEX = 6;
|
||||
|
||||
public static final int MESSAGE_SHORTEST_LENGTH = 10;
|
||||
|
||||
public static final String NAME = "thrift";
|
||||
|
||||
public static final String PARAMETER_CLASS_NAME_GENERATOR = "class.name.generator";
|
||||
|
||||
public static final byte VERSION = (byte)1;
|
||||
|
||||
public static final short MAGIC = (short) 0xdabc;
|
||||
|
||||
public void encode( Channel channel, OutputStream output, Object message )
|
||||
throws IOException {
|
||||
|
||||
if ( message instanceof Request ) {
|
||||
encodeRequest( output, ( Request ) message );
|
||||
}
|
||||
else if ( message instanceof Response ) {
|
||||
encodeResponse( output, ( Response ) message );
|
||||
} else {
|
||||
throw new UnsupportedOperationException(
|
||||
new StringBuilder( 32 )
|
||||
.append( "Thrift codec only support encode " )
|
||||
.append( Request.class.getName() )
|
||||
.append( " and " )
|
||||
.append( Response.class.getName() )
|
||||
.toString() );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Object decode( Channel channel, InputStream input ) throws IOException {
|
||||
|
||||
int available = input.available();
|
||||
|
||||
if ( available < MESSAGE_SHORTEST_LENGTH ) {
|
||||
|
||||
return Codec.NEED_MORE_INPUT;
|
||||
|
||||
} else {
|
||||
|
||||
TIOStreamTransport transport = new TIOStreamTransport( input );
|
||||
|
||||
TBinaryProtocol protocol = new TBinaryProtocol( transport );
|
||||
|
||||
short magic;
|
||||
int messageLength;
|
||||
|
||||
try{
|
||||
// protocol.readI32(); // skip the first message length
|
||||
byte[] bytes = new byte[4];
|
||||
transport.read( bytes, 0, 4 );
|
||||
magic = protocol.readI16();
|
||||
messageLength = protocol.readI32();
|
||||
|
||||
} catch ( TException e ) {
|
||||
throw new IOException( e.getMessage(), e );
|
||||
}
|
||||
|
||||
if ( MAGIC != magic ) {
|
||||
throw new IOException(
|
||||
new StringBuilder( 32 )
|
||||
.append( "Unknown magic code " )
|
||||
.append( magic )
|
||||
.toString() );
|
||||
}
|
||||
|
||||
if ( available < messageLength ) { return NEED_MORE_INPUT; }
|
||||
|
||||
return decode( protocol );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Object decode( TProtocol protocol )
|
||||
throws IOException {
|
||||
|
||||
// version
|
||||
String serviceName;
|
||||
long id;
|
||||
|
||||
TMessage message;
|
||||
|
||||
try {
|
||||
protocol.readI16();
|
||||
protocol.readByte();
|
||||
serviceName = protocol.readString();
|
||||
id = protocol.readI64();
|
||||
message = protocol.readMessageBegin();
|
||||
} catch ( TException e ) {
|
||||
throw new IOException( e.getMessage(), e );
|
||||
}
|
||||
|
||||
if ( message.type == TMessageType.CALL ) {
|
||||
|
||||
RpcInvocation result = new RpcInvocation();
|
||||
result.setAttachment(Constants.INTERFACE_KEY, serviceName );
|
||||
result.setMethodName( message.name );
|
||||
|
||||
String argsClassName = ExtensionLoader.getExtensionLoader(ClassNameGenerator.class)
|
||||
.getDefaultExtension().generateArgsClassName( serviceName, message.name );
|
||||
|
||||
if ( StringUtils.isEmpty( argsClassName ) ) {
|
||||
throw new RpcException( RpcException.SERIALIZATION_EXCEPTION,
|
||||
"The specified interface name incorrect." );
|
||||
}
|
||||
|
||||
Class clazz = cachedClass.get( argsClassName );
|
||||
|
||||
if ( clazz == null ) {
|
||||
try {
|
||||
|
||||
clazz = Class.forName( argsClassName );
|
||||
|
||||
cachedClass.putIfAbsent( argsClassName, clazz );
|
||||
|
||||
} catch ( ClassNotFoundException e ) {
|
||||
throw new RpcException( RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e );
|
||||
}
|
||||
}
|
||||
|
||||
TBase args;
|
||||
|
||||
try {
|
||||
args = ( TBase ) clazz.newInstance();
|
||||
} catch ( InstantiationException e ) {
|
||||
throw new RpcException( RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e );
|
||||
} catch ( IllegalAccessException e ) {
|
||||
throw new RpcException( RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e );
|
||||
}
|
||||
|
||||
try{
|
||||
args.read( protocol );
|
||||
protocol.readMessageEnd();
|
||||
} catch ( TException e ) {
|
||||
throw new RpcException( RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e );
|
||||
}
|
||||
|
||||
List<Object> parameters = new ArrayList<Object>();
|
||||
List<Class<?>> parameterTypes =new ArrayList<Class<?>>();
|
||||
int index = 1;
|
||||
|
||||
while ( true ) {
|
||||
|
||||
TFieldIdEnum fieldIdEnum = args.fieldForId( index++ );
|
||||
|
||||
if ( fieldIdEnum == null ) { break; }
|
||||
|
||||
String fieldName = fieldIdEnum.getFieldName();
|
||||
|
||||
String getMethodName = ThriftUtils.generateGetMethodName( fieldName );
|
||||
|
||||
Method getMethod;
|
||||
|
||||
try {
|
||||
getMethod = clazz.getMethod( getMethodName );
|
||||
} catch ( NoSuchMethodException e ) {
|
||||
throw new RpcException(
|
||||
RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e );
|
||||
}
|
||||
|
||||
parameterTypes.add( getMethod.getReturnType() );
|
||||
try {
|
||||
parameters.add( getMethod.invoke( args ) );
|
||||
} catch ( IllegalAccessException e ) {
|
||||
throw new RpcException(
|
||||
RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e );
|
||||
} catch ( InvocationTargetException e ) {
|
||||
throw new RpcException(
|
||||
RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
result.setArguments( parameters.toArray() );
|
||||
result.setParameterTypes(parameterTypes.toArray(new Class[parameterTypes.size()]));
|
||||
|
||||
Request request = new Request( id );
|
||||
request.setData( result );
|
||||
|
||||
cachedRequest.putIfAbsent( id,
|
||||
RequestData.create( message.seqid, serviceName, message.name ) );
|
||||
|
||||
return request;
|
||||
|
||||
} else if ( message.type == TMessageType.EXCEPTION ) {
|
||||
|
||||
TApplicationException exception;
|
||||
|
||||
try {
|
||||
exception = TApplicationException.read( protocol );
|
||||
protocol.readMessageEnd();
|
||||
} catch ( TException e ) {
|
||||
throw new IOException( e.getMessage(), e );
|
||||
}
|
||||
|
||||
RpcResult result = new RpcResult();
|
||||
|
||||
result.setException( new RpcException( exception.getMessage() ) );
|
||||
|
||||
Response response = new Response();
|
||||
|
||||
response.setResult( result );
|
||||
|
||||
response.setId( id );
|
||||
|
||||
return response;
|
||||
|
||||
} else if ( message.type == TMessageType.REPLY ) {
|
||||
|
||||
String resultClassName = ExtensionLoader.getExtensionLoader( ClassNameGenerator.class )
|
||||
.getDefaultExtension().generateResultClassName( serviceName, message.name );
|
||||
|
||||
if ( StringUtils.isEmpty( resultClassName ) ) {
|
||||
throw new IllegalArgumentException(
|
||||
new StringBuilder( 32 )
|
||||
.append( "Could not infer service result class name from service name " )
|
||||
.append( serviceName )
|
||||
.append( ", the service name you specified may not generated by thrift idl compiler" )
|
||||
.toString() );
|
||||
}
|
||||
|
||||
Class<?> clazz = cachedClass.get( resultClassName );
|
||||
|
||||
if ( clazz == null ) {
|
||||
|
||||
try {
|
||||
|
||||
clazz = Class.forName( resultClassName );
|
||||
|
||||
cachedClass.putIfAbsent( resultClassName, clazz );
|
||||
|
||||
} catch ( ClassNotFoundException e ) {
|
||||
throw new RpcException( RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TBase<?,? extends TFieldIdEnum> result;
|
||||
try {
|
||||
result = ( TBase<?,?> ) clazz.newInstance();
|
||||
} catch ( InstantiationException e ) {
|
||||
throw new RpcException( RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e );
|
||||
} catch ( IllegalAccessException e ) {
|
||||
throw new RpcException( RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e );
|
||||
}
|
||||
|
||||
try {
|
||||
result.read( protocol );
|
||||
protocol.readMessageEnd();
|
||||
} catch ( TException e ) {
|
||||
throw new RpcException( RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e );
|
||||
}
|
||||
|
||||
Object realResult = null;
|
||||
|
||||
int index = 0;
|
||||
|
||||
while ( true ) {
|
||||
|
||||
TFieldIdEnum fieldIdEnum = result.fieldForId( index++ );
|
||||
|
||||
if ( fieldIdEnum == null ) { break ; }
|
||||
|
||||
Field field;
|
||||
|
||||
try {
|
||||
field = clazz.getDeclaredField( fieldIdEnum.getFieldName() );
|
||||
field.setAccessible( true );
|
||||
} catch ( NoSuchFieldException e ) {
|
||||
throw new RpcException( RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e );
|
||||
}
|
||||
|
||||
try {
|
||||
realResult = field.get( result );
|
||||
} catch ( IllegalAccessException e ) {
|
||||
throw new RpcException( RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e );
|
||||
}
|
||||
|
||||
if ( realResult != null ) { break ; }
|
||||
|
||||
}
|
||||
|
||||
Response response = new Response();
|
||||
|
||||
response.setId( id );
|
||||
|
||||
RpcResult rpcResult = new RpcResult();
|
||||
|
||||
if ( realResult instanceof Throwable ) {
|
||||
rpcResult.setException( ( Throwable ) realResult );
|
||||
} else {
|
||||
rpcResult.setValue(realResult);
|
||||
}
|
||||
|
||||
response.setResult( rpcResult );
|
||||
|
||||
return response;
|
||||
|
||||
} else {
|
||||
// Impossible
|
||||
throw new IOException( );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void encodeRequest( OutputStream output, Request request )
|
||||
throws IOException {
|
||||
|
||||
RpcInvocation inv = ( RpcInvocation ) request.getData();
|
||||
|
||||
int seqId = nextSeqId();
|
||||
|
||||
String serviceName = inv.getAttachment(Constants.INTERFACE_KEY);
|
||||
|
||||
if ( StringUtils.isEmpty( serviceName ) ) {
|
||||
throw new IllegalArgumentException(
|
||||
new StringBuilder( 32 )
|
||||
.append( "Could not find service name in attachment with key " )
|
||||
.append(Constants.INTERFACE_KEY)
|
||||
.toString() );
|
||||
}
|
||||
|
||||
TMessage message = new TMessage(
|
||||
inv.getMethodName(),
|
||||
TMessageType.CALL,
|
||||
seqId );
|
||||
|
||||
String methodArgs = ExtensionLoader.getExtensionLoader( ClassNameGenerator.class )
|
||||
.getDefaultExtension().generateArgsClassName( serviceName, inv.getMethodName() );
|
||||
|
||||
if ( StringUtils.isEmpty( methodArgs ) ) {
|
||||
throw new RpcException( RpcException.SERIALIZATION_EXCEPTION,
|
||||
new StringBuilder(32).append(
|
||||
"Could not encode request, the specified interface may be incorrect." ).toString() );
|
||||
}
|
||||
|
||||
Class<?> clazz = cachedClass.get( methodArgs );
|
||||
|
||||
if ( clazz == null ) {
|
||||
|
||||
try {
|
||||
|
||||
clazz = Class.forName( methodArgs );
|
||||
|
||||
cachedClass.putIfAbsent( methodArgs, clazz );
|
||||
|
||||
} catch ( ClassNotFoundException e ) {
|
||||
throw new RpcException( RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TBase args;
|
||||
|
||||
try {
|
||||
args = (TBase) clazz.newInstance();
|
||||
} catch ( InstantiationException e ) {
|
||||
throw new RpcException( RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e );
|
||||
} catch ( IllegalAccessException e ) {
|
||||
throw new RpcException( RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e );
|
||||
}
|
||||
|
||||
for( int i = 0; i < inv.getArguments().length; i++ ) {
|
||||
|
||||
Object obj = inv.getArguments()[i];
|
||||
|
||||
if ( obj == null ) { continue; }
|
||||
|
||||
TFieldIdEnum field = args.fieldForId( i + 1 );
|
||||
|
||||
String setMethodName = ThriftUtils.generateSetMethodName( field.getFieldName() );
|
||||
|
||||
Method method;
|
||||
|
||||
try {
|
||||
method = clazz.getMethod( setMethodName, inv.getParameterTypes()[i] );
|
||||
} catch ( NoSuchMethodException e ) {
|
||||
throw new RpcException( RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e );
|
||||
}
|
||||
|
||||
try {
|
||||
method.invoke( args, obj );
|
||||
} catch ( IllegalAccessException e ) {
|
||||
throw new RpcException( RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e );
|
||||
} catch ( InvocationTargetException e ) {
|
||||
throw new RpcException( RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
RandomAccessByteArrayOutputStream bos = new RandomAccessByteArrayOutputStream( 1024 );
|
||||
|
||||
TIOStreamTransport transport = new TIOStreamTransport( bos );
|
||||
|
||||
TBinaryProtocol protocol = new TBinaryProtocol( transport );
|
||||
|
||||
int headerLength, messageLength;
|
||||
|
||||
byte[] bytes = new byte[4];
|
||||
try {
|
||||
// magic
|
||||
protocol.writeI16( MAGIC );
|
||||
// message length placeholder
|
||||
protocol.writeI32( Integer.MAX_VALUE );
|
||||
// message header length placeholder
|
||||
protocol.writeI16( Short.MAX_VALUE );
|
||||
// version
|
||||
protocol.writeByte( VERSION );
|
||||
// service name
|
||||
protocol.writeString( serviceName );
|
||||
// dubbo request id
|
||||
protocol.writeI64( request.getId() );
|
||||
protocol.getTransport().flush();
|
||||
// header size
|
||||
headerLength = bos.size();
|
||||
|
||||
// message body
|
||||
protocol.writeMessageBegin( message );
|
||||
args.write( protocol );
|
||||
protocol.writeMessageEnd();
|
||||
protocol.getTransport().flush();
|
||||
int oldIndex = messageLength = bos.size();
|
||||
|
||||
// fill in message length and header length
|
||||
try {
|
||||
TFramedTransport.encodeFrameSize( messageLength, bytes );
|
||||
bos.setWriteIndex( MESSAGE_LENGTH_INDEX );
|
||||
protocol.writeI32( messageLength );
|
||||
bos.setWriteIndex( MESSAGE_HEADER_LENGTH_INDEX );
|
||||
protocol.writeI16( ( short )( 0xffff & headerLength ) );
|
||||
} finally {
|
||||
bos.setWriteIndex( oldIndex );
|
||||
}
|
||||
|
||||
} catch ( TException e ) {
|
||||
throw new RpcException( RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e );
|
||||
}
|
||||
|
||||
output.write( bytes );
|
||||
bos.writeTo( output );
|
||||
output.flush();
|
||||
|
||||
}
|
||||
|
||||
private void encodeResponse( OutputStream output, Response response )
|
||||
throws IOException {
|
||||
|
||||
RpcResult result = ( RpcResult ) response.getResult();
|
||||
|
||||
RequestData rd = cachedRequest.get( response.getId() );
|
||||
|
||||
String resultClassName = ExtensionLoader.getExtensionLoader( ClassNameGenerator.class )
|
||||
.getDefaultExtension().generateResultClassName( rd.serviceName, rd.methodName );
|
||||
|
||||
if ( StringUtils.isEmpty( resultClassName ) ) {
|
||||
throw new RpcException( RpcException.SERIALIZATION_EXCEPTION,
|
||||
new StringBuilder( 32 ).append(
|
||||
"Could not encode response, the specified interface may be incorrect." ).toString() );
|
||||
}
|
||||
|
||||
Class clazz = cachedClass.get( resultClassName );
|
||||
|
||||
if ( clazz == null ) {
|
||||
|
||||
try {
|
||||
clazz = Class.forName( resultClassName );
|
||||
cachedClass.putIfAbsent( resultClassName, clazz );
|
||||
} catch ( ClassNotFoundException e ) {
|
||||
throw new RpcException( RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TBase resultObj;
|
||||
|
||||
try {
|
||||
resultObj = ( TBase ) clazz.newInstance();
|
||||
} catch ( InstantiationException e ) {
|
||||
throw new RpcException( RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e );
|
||||
} catch ( IllegalAccessException e ) {
|
||||
throw new RpcException( RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e );
|
||||
}
|
||||
|
||||
TApplicationException applicationException = null;
|
||||
TMessage message;
|
||||
|
||||
if ( result.hasException() ) {
|
||||
Throwable throwable = result.getException();
|
||||
int index = 1;
|
||||
boolean found = false;
|
||||
while ( true ) {
|
||||
TFieldIdEnum fieldIdEnum = resultObj.fieldForId( index++ );
|
||||
if ( fieldIdEnum == null ) { break; }
|
||||
String fieldName = fieldIdEnum.getFieldName();
|
||||
String getMethodName = ThriftUtils.generateGetMethodName( fieldName );
|
||||
String setMethodName = ThriftUtils.generateSetMethodName( fieldName );
|
||||
Method getMethod;
|
||||
Method setMethod;
|
||||
try {
|
||||
getMethod = clazz.getMethod( getMethodName );
|
||||
if ( getMethod.getReturnType().equals( throwable.getClass() ) ) {
|
||||
found = true;
|
||||
setMethod = clazz.getMethod( setMethodName, throwable.getClass() );
|
||||
setMethod.invoke( resultObj, throwable );
|
||||
}
|
||||
} catch ( NoSuchMethodException e ) {
|
||||
throw new RpcException( RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e );
|
||||
} catch ( InvocationTargetException e ) {
|
||||
throw new RpcException( RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e );
|
||||
} catch ( IllegalAccessException e ) {
|
||||
throw new RpcException( RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e );
|
||||
}
|
||||
}
|
||||
|
||||
if ( !found ) {
|
||||
applicationException = new TApplicationException( throwable.getMessage() );
|
||||
}
|
||||
|
||||
} else {
|
||||
Object realResult = result.getResult();
|
||||
// result field id is 0
|
||||
String fieldName = resultObj.fieldForId( 0 ).getFieldName();
|
||||
String setMethodName = ThriftUtils.generateSetMethodName( fieldName );
|
||||
String getMethodName = ThriftUtils.generateGetMethodName( fieldName );
|
||||
Method getMethod;
|
||||
Method setMethod;
|
||||
try {
|
||||
getMethod = clazz.getMethod( getMethodName );
|
||||
setMethod = clazz.getMethod( setMethodName, getMethod.getReturnType() );
|
||||
setMethod.invoke( resultObj, realResult );
|
||||
} catch ( NoSuchMethodException e ) {
|
||||
throw new RpcException( RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e );
|
||||
} catch ( InvocationTargetException e ) {
|
||||
throw new RpcException( RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e );
|
||||
} catch ( IllegalAccessException e ) {
|
||||
throw new RpcException( RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( applicationException != null ) {
|
||||
message = new TMessage( rd.methodName, TMessageType.EXCEPTION, rd.id );
|
||||
} else {
|
||||
message = new TMessage( rd.methodName, TMessageType.REPLY, rd.id );
|
||||
}
|
||||
|
||||
RandomAccessByteArrayOutputStream bos = new RandomAccessByteArrayOutputStream( 1024 );
|
||||
|
||||
TIOStreamTransport transport = new TIOStreamTransport( bos );
|
||||
|
||||
TBinaryProtocol protocol = new TBinaryProtocol( transport );
|
||||
|
||||
int messageLength;
|
||||
int headerLength;
|
||||
|
||||
byte[] bytes = new byte[4];
|
||||
try {
|
||||
// magic
|
||||
protocol.writeI16( MAGIC );
|
||||
// message length
|
||||
protocol.writeI32( Integer.MAX_VALUE );
|
||||
// message header length
|
||||
protocol.writeI16( Short.MAX_VALUE );
|
||||
// version
|
||||
protocol.writeByte( VERSION );
|
||||
// service name
|
||||
protocol.writeString( rd.serviceName );
|
||||
// id
|
||||
protocol.writeI64( response.getId() );
|
||||
protocol.getTransport().flush();
|
||||
headerLength = bos.size();
|
||||
|
||||
// message
|
||||
protocol.writeMessageBegin( message );
|
||||
switch ( message.type ) {
|
||||
case TMessageType.EXCEPTION:
|
||||
applicationException.write( protocol );
|
||||
break;
|
||||
case TMessageType.REPLY:
|
||||
resultObj.write( protocol );
|
||||
break;
|
||||
}
|
||||
protocol.writeMessageEnd();
|
||||
protocol.getTransport().flush();
|
||||
int oldIndex = messageLength = bos.size();
|
||||
|
||||
try{
|
||||
TFramedTransport.encodeFrameSize( messageLength, bytes );
|
||||
bos.setWriteIndex( MESSAGE_LENGTH_INDEX );
|
||||
protocol.writeI32( messageLength );
|
||||
bos.setWriteIndex( MESSAGE_HEADER_LENGTH_INDEX );
|
||||
protocol.writeI16( ( short ) ( 0xffff & headerLength ) );
|
||||
} finally {
|
||||
bos.setWriteIndex( oldIndex );
|
||||
}
|
||||
|
||||
} catch ( TException e ) {
|
||||
throw new RpcException( RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e );
|
||||
}
|
||||
|
||||
output.write( bytes );
|
||||
bos.writeTo( output );
|
||||
output.flush();
|
||||
|
||||
}
|
||||
|
||||
private static int nextSeqId() {
|
||||
return THRIFT_SEQ_ID.incrementAndGet();
|
||||
}
|
||||
|
||||
// just for test
|
||||
static int getSeqId() {
|
||||
return THRIFT_SEQ_ID.get();
|
||||
}
|
||||
|
||||
static class RequestData {
|
||||
int id;
|
||||
String serviceName;
|
||||
String methodName;
|
||||
|
||||
static RequestData create( int id, String sn, String mn ) {
|
||||
RequestData result = new RequestData();
|
||||
result.id = id;
|
||||
result.serviceName = sn;
|
||||
result.methodName = mn;
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,156 +0,0 @@
|
|||
/**
|
||||
* File Created at 2011-12-06
|
||||
* $Id$
|
||||
*
|
||||
* Copyright 2008 Alibaba.com Croporation Limited.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is the confidential and proprietary information of
|
||||
* Alibaba Company. ("Confidential Information"). You shall not
|
||||
* disclose such Confidential Information and shall use it only in
|
||||
* accordance with the terms of the license agreement you entered into
|
||||
* with Alibaba.com.
|
||||
*/
|
||||
package com.alibaba.dubbo.rpc.protocol.thrift;
|
||||
|
||||
import com.alibaba.dubbo.common.Constants;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.common.utils.AtomicPositiveInteger;
|
||||
import com.alibaba.dubbo.remoting.RemotingException;
|
||||
import com.alibaba.dubbo.remoting.TimeoutException;
|
||||
import com.alibaba.dubbo.remoting.exchange.ExchangeClient;
|
||||
import com.alibaba.dubbo.rpc.Invocation;
|
||||
import com.alibaba.dubbo.rpc.Invoker;
|
||||
import com.alibaba.dubbo.rpc.Result;
|
||||
import com.alibaba.dubbo.rpc.RpcContext;
|
||||
import com.alibaba.dubbo.rpc.RpcException;
|
||||
import com.alibaba.dubbo.rpc.RpcInvocation;
|
||||
import com.alibaba.dubbo.rpc.protocol.AbstractInvoker;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:gang.lvg@alibaba-inc.com">gang.lvg</a>
|
||||
*/
|
||||
public class ThriftInvoker<T> extends AbstractInvoker<T> {
|
||||
|
||||
private final ExchangeClient[] clients;
|
||||
|
||||
private final AtomicPositiveInteger index = new AtomicPositiveInteger();
|
||||
|
||||
private final ReentrantLock destroyLock = new ReentrantLock();
|
||||
|
||||
private final Set<Invoker<?>> invokers;
|
||||
|
||||
public ThriftInvoker( Class<T> service, URL url, ExchangeClient[] clients ) {
|
||||
this(service, url, clients, null);
|
||||
}
|
||||
|
||||
public ThriftInvoker(Class<T> type, URL url, ExchangeClient[] clients, Set<Invoker<?>> invokers) {
|
||||
super(type, url,
|
||||
new String[]{Constants.INTERFACE_KEY, Constants.GROUP_KEY,
|
||||
Constants.TOKEN_KEY, Constants.TIMEOUT_KEY});
|
||||
this.clients = clients;
|
||||
this.invokers = invokers;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Result doInvoke( Invocation invocation ) throws Throwable {
|
||||
|
||||
RpcInvocation inv;
|
||||
|
||||
final String methodName;
|
||||
|
||||
inv = new RpcInvocation( invocation.getMethodName(), invocation.getParameterTypes(),
|
||||
invocation.getArguments(), invocation.getAttachments() );
|
||||
|
||||
methodName = invocation.getMethodName();
|
||||
|
||||
inv.setAttachment( Constants.PATH_KEY, getUrl().getPath() );
|
||||
|
||||
// for thrift codec
|
||||
inv.setAttachment( ThriftCodec.PARAMETER_CLASS_NAME_GENERATOR, getUrl().getParameter(
|
||||
ThriftCodec.PARAMETER_CLASS_NAME_GENERATOR, DubboClassNameGenerator.NAME ) );
|
||||
|
||||
ExchangeClient currentClient;
|
||||
|
||||
if (clients.length == 1) {
|
||||
currentClient = clients[0];
|
||||
} else {
|
||||
currentClient = clients[index.getAndIncrement() % clients.length];
|
||||
}
|
||||
|
||||
try {
|
||||
int timeout = getUrl().getMethodParameter(
|
||||
methodName, Constants.TIMEOUT_KEY,Constants.DEFAULT_TIMEOUT);
|
||||
|
||||
RpcContext.getContext().setFuture(null);
|
||||
|
||||
return (Result) currentClient.request(inv, timeout).get();
|
||||
|
||||
} catch (TimeoutException e) {
|
||||
throw new RpcException(RpcException.TIMEOUT_EXCEPTION, e.getMessage(), e);
|
||||
} catch (RemotingException e) {
|
||||
throw new RpcException(RpcException.NETWORK_EXCEPTION, e.getMessage(), e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
|
||||
if (!super.isAvailable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (ExchangeClient client : clients){
|
||||
if (client.isConnected()
|
||||
&& !client.hasAttribute(Constants.CHANNEL_ATTRIBUTE_READONLY_KEY)){
|
||||
//cannot write == not Available ?
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
//防止client被关闭多次.在connect per jvm的情况下,client.close方法会调用计数器-1,当计数器小于等于0的情况下,才真正关闭
|
||||
if (super.isDestroyed()){
|
||||
return ;
|
||||
} else {
|
||||
//dubbo check ,避免多次关闭
|
||||
destroyLock.lock();
|
||||
|
||||
try{
|
||||
|
||||
if (super.isDestroyed()){
|
||||
return ;
|
||||
}
|
||||
|
||||
super.destroy();
|
||||
|
||||
if(invokers != null) {
|
||||
invokers.remove(this);
|
||||
}
|
||||
|
||||
for (ExchangeClient client : clients) {
|
||||
|
||||
try {
|
||||
client.close();
|
||||
} catch (Throwable t) {
|
||||
logger.warn(t.getMessage(), t);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}finally {
|
||||
destroyLock.unlock();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,214 +0,0 @@
|
|||
/**
|
||||
* File Created at 2011-12-06
|
||||
* $Id$
|
||||
*
|
||||
* Copyright 2008 Alibaba.com Croporation Limited.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is the confidential and proprietary information of
|
||||
* Alibaba Company. ("Confidential Information"). You shall not
|
||||
* disclose such Confidential Information and shall use it only in
|
||||
* accordance with the terms of the license agreement you entered into
|
||||
* with Alibaba.com.
|
||||
*/
|
||||
package com.alibaba.dubbo.rpc.protocol.thrift;
|
||||
|
||||
import com.alibaba.dubbo.common.Constants;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.common.extension.ExtensionLoader;
|
||||
import com.alibaba.dubbo.remoting.Channel;
|
||||
import com.alibaba.dubbo.remoting.RemotingException;
|
||||
import com.alibaba.dubbo.remoting.Transporter;
|
||||
import com.alibaba.dubbo.remoting.exchange.ExchangeChannel;
|
||||
import com.alibaba.dubbo.remoting.exchange.ExchangeClient;
|
||||
import com.alibaba.dubbo.remoting.exchange.ExchangeHandler;
|
||||
import com.alibaba.dubbo.remoting.exchange.ExchangeServer;
|
||||
import com.alibaba.dubbo.remoting.exchange.Exchangers;
|
||||
import com.alibaba.dubbo.remoting.exchange.support.ExchangeHandlerAdapter;
|
||||
import com.alibaba.dubbo.rpc.Exporter;
|
||||
import com.alibaba.dubbo.rpc.Invocation;
|
||||
import com.alibaba.dubbo.rpc.Invoker;
|
||||
import com.alibaba.dubbo.rpc.RpcContext;
|
||||
import com.alibaba.dubbo.rpc.RpcException;
|
||||
import com.alibaba.dubbo.rpc.protocol.AbstractProtocol;
|
||||
import com.alibaba.dubbo.rpc.protocol.dubbo.DubboExporter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:gang.lvg@alibaba-inc.com">gang.lvg</a>
|
||||
*/
|
||||
public class ThriftProtocol extends AbstractProtocol {
|
||||
|
||||
public static final int DEFAULT_PORT = 40880;
|
||||
|
||||
public static final String NAME = "thrift";
|
||||
|
||||
// ip:port -> ExchangeServer
|
||||
private final ConcurrentMap<String, ExchangeServer> serverMap =
|
||||
new ConcurrentHashMap<String, ExchangeServer>();
|
||||
|
||||
private ExchangeHandler handler = new ExchangeHandlerAdapter() {
|
||||
|
||||
@Override
|
||||
public Object reply( ExchangeChannel channel, Object msg ) throws RemotingException {
|
||||
|
||||
if ( msg instanceof Invocation ) {
|
||||
Invocation inv = ( Invocation ) msg;
|
||||
String serviceName = inv.getAttachments().get(Constants.INTERFACE_KEY);
|
||||
String serviceKey = serviceKey( channel.getLocalAddress().getPort(),
|
||||
serviceName, null, null );
|
||||
DubboExporter<?> exporter = (DubboExporter<?>) exporterMap.get( serviceKey );
|
||||
if (exporter == null) {
|
||||
throw new RemotingException(channel,
|
||||
"Not found exported service: "
|
||||
+ serviceKey
|
||||
+ " in "
|
||||
+ exporterMap.keySet()
|
||||
+ ", may be version or group mismatch "
|
||||
+ ", channel: consumer: "
|
||||
+ channel.getRemoteAddress()
|
||||
+ " --> provider: "
|
||||
+ channel.getLocalAddress()
|
||||
+ ", message:"+ msg);
|
||||
}
|
||||
|
||||
RpcContext.getContext().setRemoteAddress(channel.getRemoteAddress());
|
||||
return exporter.getInvoker().invoke( inv );
|
||||
|
||||
}
|
||||
|
||||
throw new RemotingException(channel,
|
||||
"Unsupported request: "
|
||||
+ (msg.getClass().getName() + ": " + msg)
|
||||
+ ", channel: consumer: "
|
||||
+ channel.getRemoteAddress()
|
||||
+ " --> provider: "
|
||||
+ channel.getLocalAddress());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void received( Channel channel, Object message ) throws RemotingException {
|
||||
if ( message instanceof Invocation ) {
|
||||
reply( ( ExchangeChannel ) channel, message );
|
||||
} else {
|
||||
super.received( channel, message );
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
public int getDefaultPort() {
|
||||
return DEFAULT_PORT;
|
||||
}
|
||||
|
||||
public <T> Exporter<T> export( Invoker<T> invoker ) throws RpcException {
|
||||
|
||||
// 只能使用 thrift codec
|
||||
URL url = invoker.getUrl().addParameter(Constants.DOWNSTREAM_CODEC_KEY, ThriftCodec.NAME);
|
||||
url = url.addParameter(Constants.CODEC_KEY, ThriftCodec.NAME);
|
||||
// find server.
|
||||
String key = url.getAddress();
|
||||
//client 也可以暴露一个只有server可以调用的服务。
|
||||
boolean isServer = url.getParameter(Constants.IS_SERVER_KEY,true);
|
||||
if (isServer && ! serverMap.containsKey(key)) {
|
||||
serverMap.put(key, getServer(url));
|
||||
}
|
||||
// export service.
|
||||
key = serviceKey(url);
|
||||
DubboExporter<T> exporter = new DubboExporter<T>(invoker, key, exporterMap);
|
||||
exporterMap.put(key, exporter);
|
||||
|
||||
return exporter;
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
|
||||
super.destroy();
|
||||
|
||||
for (String key : new ArrayList<String>(serverMap.keySet())) {
|
||||
|
||||
ExchangeServer server = serverMap.remove(key);
|
||||
|
||||
if (server != null) {
|
||||
try {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Close dubbo server: " + server.getLocalAddress());
|
||||
}
|
||||
server.close(getServerShutdownTimeout());
|
||||
} catch (Throwable t) {
|
||||
logger.warn(t.getMessage(), t);
|
||||
}
|
||||
} // ~ end of if ( server != null )
|
||||
|
||||
} // ~ end of loop serverMap
|
||||
|
||||
} // ~ end of method destroy
|
||||
|
||||
public <T> Invoker<T> refer( Class<T> type, URL url ) throws RpcException {
|
||||
|
||||
ThriftInvoker<T> invoker = new ThriftInvoker<T>(type, url, getClients(url), invokers);
|
||||
|
||||
invokers.add(invoker);
|
||||
|
||||
return invoker;
|
||||
|
||||
}
|
||||
|
||||
private ExchangeClient[] getClients(URL url){
|
||||
|
||||
int connections = url.getParameter(Constants.CONNECTIONS_KEY, 1);
|
||||
|
||||
ExchangeClient[] clients = new ExchangeClient[connections];
|
||||
|
||||
for (int i = 0; i < clients.length; i++) {
|
||||
clients[i] = initClient(url);
|
||||
}
|
||||
return clients;
|
||||
}
|
||||
|
||||
private ExchangeClient initClient(URL url) {
|
||||
|
||||
ExchangeClient client ;
|
||||
|
||||
url = url.addParameter( Constants.CODEC_KEY, ThriftCodec.NAME );
|
||||
|
||||
try {
|
||||
client = Exchangers.connect( url );
|
||||
} catch ( RemotingException e ) {
|
||||
throw new RpcException( "Fail to create remoting client for service(" + url
|
||||
+ "): " + e.getMessage(), e );
|
||||
}
|
||||
|
||||
return client;
|
||||
|
||||
}
|
||||
|
||||
private ExchangeServer getServer(URL url) {
|
||||
//默认开启server关闭时发送readonly事件
|
||||
url = url.addParameterIfAbsent(Constants.CHANNEL_READONLYEVENT_SENT_KEY, Boolean.TRUE.toString());
|
||||
String str = url.getParameter(Constants.SERVER_KEY, Constants.DEFAULT_REMOTING_SERVER);
|
||||
|
||||
if (str != null && str.length() > 0 && ! ExtensionLoader.getExtensionLoader(Transporter.class).hasExtension(str))
|
||||
throw new RpcException("Unsupported server type: " + str + ", url: " + url);
|
||||
|
||||
ExchangeServer server;
|
||||
try {
|
||||
server = Exchangers.bind(url, handler);
|
||||
} catch (RemotingException e) {
|
||||
throw new RpcException("Fail to start server(url: " + url + ") " + e.getMessage(), e);
|
||||
}
|
||||
str = url.getParameter(Constants.CLIENT_KEY);
|
||||
if (str != null && str.length() > 0) {
|
||||
Set<String> supportedTypes = ExtensionLoader.getExtensionLoader(Transporter.class).getSupportedExtensions();
|
||||
if (!supportedTypes.contains(str)) {
|
||||
throw new RpcException("Unsupported client type: " + str);
|
||||
}
|
||||
}
|
||||
return server;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,132 +0,0 @@
|
|||
/**
|
||||
* File Created at 2011-12-05
|
||||
* $Id$
|
||||
*
|
||||
* Copyright 2008 Alibaba.com Croporation Limited.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is the confidential and proprietary information of
|
||||
* Alibaba Company. ("Confidential Information"). You shall not
|
||||
* disclose such Confidential Information and shall use it only in
|
||||
* accordance with the terms of the license agreement you entered into
|
||||
* with Alibaba.com.
|
||||
*/
|
||||
package com.alibaba.dubbo.rpc.protocol.thrift;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:gang.lvg@alibaba-inc.com">gang.lvg</a>
|
||||
*/
|
||||
public class ThriftUtils {
|
||||
|
||||
/**
|
||||
* Generate class name which represents service arguments.
|
||||
*
|
||||
* @param serviceName service name
|
||||
* @param methodName method name
|
||||
* @return method args class name or null
|
||||
*/
|
||||
public static String generateMethodArgsClassName( String serviceName, String methodName ) {
|
||||
|
||||
int index = serviceName.lastIndexOf( "." );
|
||||
|
||||
if ( index > 0 ) {
|
||||
|
||||
return new StringBuilder( 32 )
|
||||
.append( serviceName.substring( 0, index + 1 ) )
|
||||
.append( "$__" )
|
||||
.append( serviceName.substring( index + 1 ) )
|
||||
.append( "Stub$" )
|
||||
.append( methodName )
|
||||
.append( "_args" )
|
||||
.toString();
|
||||
|
||||
} else {
|
||||
return new StringBuffer( 32 )
|
||||
.append( "$__" )
|
||||
.append( serviceName )
|
||||
.append( "Stub$" )
|
||||
.append( methodName )
|
||||
.append( "_args" )
|
||||
.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static String generateMethodResultClassName( String serviceName, String method ) {
|
||||
|
||||
int index = serviceName.lastIndexOf( "." );
|
||||
|
||||
if ( index > 0 ) {
|
||||
|
||||
return new StringBuilder( 32 )
|
||||
.append( serviceName.substring( 0, index + 1 ) )
|
||||
.append( "$__" )
|
||||
.append( serviceName.substring( index + 1 ) )
|
||||
.append( "Stub$" )
|
||||
.append( method )
|
||||
.append( "_result" )
|
||||
.toString();
|
||||
|
||||
} else {
|
||||
return new StringBuilder( 32 )
|
||||
.append( "$__" )
|
||||
.append( serviceName )
|
||||
.append( "Stub$" )
|
||||
.append( method )
|
||||
.append( "_result" )
|
||||
.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static String generateSetMethodName( String fieldName ) {
|
||||
|
||||
return new StringBuilder( 16 )
|
||||
.append( "set" )
|
||||
.append( Character.toUpperCase( fieldName.charAt( 0 ) ) )
|
||||
.append( fieldName.substring( 1 ) )
|
||||
.toString();
|
||||
|
||||
}
|
||||
|
||||
public static String generateGetMethodName( String fieldName ) {
|
||||
return new StringBuffer( 16 )
|
||||
.append( "get" )
|
||||
.append( Character.toUpperCase( fieldName.charAt( 0 ) ) )
|
||||
.append( fieldName.substring( 1 ) )
|
||||
.toString();
|
||||
}
|
||||
|
||||
public static String generateMethodArgsClassNameThrift( String serviceName, String methodName ) {
|
||||
|
||||
int index = serviceName.indexOf( "$" );
|
||||
|
||||
if ( index > 0 ) {
|
||||
return new StringBuilder( 32 )
|
||||
.append( serviceName.substring( 0, index + 1 ) )
|
||||
.append( methodName )
|
||||
.append( "_args" )
|
||||
.toString();
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
public static String generateMethodResultClassNameThrift( String serviceName, String methodName ) {
|
||||
|
||||
int index = serviceName.indexOf( "$" );
|
||||
|
||||
if ( index > 0 ) {
|
||||
return new StringBuilder( 32 )
|
||||
.append( serviceName.substring( 0, index + 1 ) )
|
||||
.append( methodName )
|
||||
.append( "_result" )
|
||||
.toString();
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,122 +0,0 @@
|
|||
/**
|
||||
* File Created at 2011-12-26
|
||||
* $Id$
|
||||
*
|
||||
* Copyright 2008 Alibaba.com Croporation Limited.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is the confidential and proprietary information of
|
||||
* Alibaba Company. ("Confidential Information"). You shall not
|
||||
* disclose such Confidential Information and shall use it only in
|
||||
* accordance with the terms of the license agreement you entered into
|
||||
* with Alibaba.com.
|
||||
*/
|
||||
package com.alibaba.dubbo.rpc.protocol.thrift.ext;
|
||||
|
||||
import com.alibaba.dubbo.common.logger.Logger;
|
||||
import com.alibaba.dubbo.common.logger.LoggerFactory;
|
||||
import com.alibaba.dubbo.rpc.protocol.thrift.ThriftCodec;
|
||||
import org.apache.thrift.TException;
|
||||
import org.apache.thrift.TProcessor;
|
||||
import org.apache.thrift.protocol.TBinaryProtocol;
|
||||
import org.apache.thrift.protocol.TProtocol;
|
||||
import org.apache.thrift.protocol.TProtocolFactory;
|
||||
import org.apache.thrift.transport.TIOStreamTransport;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:gang.lvg@alibaba-inc.com">kimi</a>
|
||||
*/
|
||||
public class MultiServiceProcessor implements TProcessor {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger( MultiServiceProcessor.class );
|
||||
|
||||
private ConcurrentMap<String, TProcessor> processorMap = new ConcurrentHashMap<String, TProcessor>();
|
||||
|
||||
private TProtocolFactory protocolFactory = new TBinaryProtocol.Factory();
|
||||
|
||||
public MultiServiceProcessor() {}
|
||||
|
||||
public boolean process( TProtocol in, TProtocol out ) throws TException {
|
||||
|
||||
short magic = in.readI16();
|
||||
|
||||
if ( magic != ThriftCodec.MAGIC ) {
|
||||
logger.error(
|
||||
new StringBuilder( 24 )
|
||||
.append( "Unsupported magic " )
|
||||
.append( magic ).toString() );
|
||||
return false;
|
||||
}
|
||||
|
||||
in.readI32();
|
||||
in.readI16();
|
||||
byte version = in.readByte();
|
||||
String serviceName = in.readString();
|
||||
long id = in.readI64();
|
||||
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream( 1024 );
|
||||
|
||||
TIOStreamTransport transport = new TIOStreamTransport( bos );
|
||||
|
||||
TProtocol protocol = protocolFactory.getProtocol( transport );
|
||||
|
||||
TProcessor processor = processorMap.get( serviceName );
|
||||
|
||||
if ( processor == null ) {
|
||||
logger.error(
|
||||
new StringBuilder( 32 )
|
||||
.append( "Could not find processor for service " )
|
||||
.append( serviceName )
|
||||
.toString() );
|
||||
return false;
|
||||
}
|
||||
|
||||
// todo if exception
|
||||
boolean result = processor.process( in, protocol );
|
||||
|
||||
ByteArrayOutputStream header = new ByteArrayOutputStream( 512 );
|
||||
|
||||
TIOStreamTransport headerTransport = new TIOStreamTransport( header );
|
||||
|
||||
TProtocol headerProtocol = protocolFactory.getProtocol( headerTransport );
|
||||
|
||||
headerProtocol.writeI16( magic );
|
||||
headerProtocol.writeI32( Integer.MAX_VALUE );
|
||||
headerProtocol.writeI16( Short.MAX_VALUE );
|
||||
headerProtocol.writeByte( version );
|
||||
headerProtocol.writeString( serviceName );
|
||||
headerProtocol.writeI64( id );
|
||||
headerProtocol.getTransport().flush();
|
||||
|
||||
out.writeI16( magic );
|
||||
out.writeI32( bos.size() + header.size() );
|
||||
out.writeI16( ( short ) ( 0xffff & header.size() ) );
|
||||
out.writeByte( version );
|
||||
out.writeString( serviceName );
|
||||
out.writeI64( id );
|
||||
|
||||
out.getTransport().write( bos.toByteArray() );
|
||||
out.getTransport().flush();
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
public TProcessor addProcessor( Class service, TProcessor processor ) {
|
||||
if ( service != null && processor != null ) {
|
||||
return processorMap.putIfAbsent( service.getName(), processor );
|
||||
}
|
||||
return processor;
|
||||
}
|
||||
|
||||
public void setProtocolFactory( TProtocolFactory factory ) {
|
||||
if ( factory != null ) {
|
||||
this.protocolFactory = factory;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
/**
|
||||
* File Created at 2011-12-22
|
||||
* $Id$
|
||||
*
|
||||
* Copyright 2008 Alibaba.com Croporation Limited.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is the confidential and proprietary information of
|
||||
* Alibaba Company. ("Confidential Information"). You shall not
|
||||
* disclose such Confidential Information and shall use it only in
|
||||
* accordance with the terms of the license agreement you entered into
|
||||
* with Alibaba.com.
|
||||
*/
|
||||
package com.alibaba.dubbo.rpc.protocol.thrift.io;
|
||||
|
||||
import com.alibaba.dubbo.common.io.Bytes;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:gang.lvg@alibaba-inc.com">kimi</a>
|
||||
*/
|
||||
public class RandomAccessByteArrayOutputStream extends OutputStream {
|
||||
|
||||
protected byte buffer[];
|
||||
|
||||
protected int count;
|
||||
|
||||
public RandomAccessByteArrayOutputStream() {
|
||||
|
||||
this( 32 );
|
||||
}
|
||||
|
||||
public RandomAccessByteArrayOutputStream( int size ) {
|
||||
|
||||
if ( size < 0 )
|
||||
throw new IllegalArgumentException( "Negative initial size: " + size );
|
||||
buffer = new byte[size];
|
||||
}
|
||||
|
||||
public void write( int b ) {
|
||||
|
||||
int newcount = count + 1;
|
||||
if ( newcount > buffer.length )
|
||||
buffer = Bytes.copyOf( buffer, Math.max( buffer.length << 1, newcount ) );
|
||||
buffer[count] = ( byte ) b;
|
||||
count = newcount;
|
||||
}
|
||||
|
||||
public void write( byte b[], int off, int len ) {
|
||||
|
||||
if ( ( off < 0 ) || ( off > b.length ) || ( len < 0 ) || ( ( off + len ) > b.length ) || ( ( off + len ) < 0 ) )
|
||||
throw new IndexOutOfBoundsException();
|
||||
if ( len == 0 )
|
||||
return;
|
||||
int newcount = count + len;
|
||||
if ( newcount > buffer.length )
|
||||
buffer = Bytes.copyOf( buffer, Math.max( buffer.length << 1, newcount ) );
|
||||
System.arraycopy( b, off, buffer, count, len );
|
||||
count = newcount;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setWriteIndex( int index ) {
|
||||
count = index;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
|
||||
count = 0;
|
||||
}
|
||||
|
||||
public byte[] toByteArray() {
|
||||
|
||||
return Bytes.copyOf( buffer, count );
|
||||
}
|
||||
|
||||
public ByteBuffer toByteBuffer() {
|
||||
|
||||
return ByteBuffer.wrap( buffer, 0, count );
|
||||
}
|
||||
|
||||
public void writeTo( OutputStream out ) throws IOException {
|
||||
|
||||
out.write( buffer, 0, count );
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
|
||||
return new String( buffer, 0, count );
|
||||
}
|
||||
|
||||
public String toString( String charset ) throws UnsupportedEncodingException {
|
||||
|
||||
return new String( buffer, 0, count, charset );
|
||||
}
|
||||
|
||||
public void close() throws IOException {}
|
||||
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
thrift=com.alibaba.dubbo.rpc.protocol.thrift.ThriftCodec
|
||||
|
|
@ -1 +0,0 @@
|
|||
thrift=com.alibaba.dubbo.rpc.protocol.thrift.ThriftProtocol
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
dubbo=com.alibaba.dubbo.rpc.protocol.thrift.DubboClassNameGenerator
|
||||
thrift=com.alibaba.dubbo.rpc.protocol.thrift.ThriftClassNameGenerator
|
||||
|
|
@ -1,658 +0,0 @@
|
|||
/**
|
||||
* Autogenerated by Dubbo Compiler (0.1.0)
|
||||
*
|
||||
* Thrift (0.7.0)
|
||||
*
|
||||
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
|
||||
*/
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.EnumMap;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Collections;
|
||||
import java.util.BitSet;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class $__ClassNameTestDubboStub {
|
||||
|
||||
public interface Iface {
|
||||
|
||||
public String echo(String arg);
|
||||
|
||||
}
|
||||
|
||||
public static class Processor<I extends Iface> extends org.apache.thrift.TBaseProcessor implements org.apache.thrift.TProcessor {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(Processor.class.getName());
|
||||
public Processor(I iface) {
|
||||
super(iface, getProcessMap(new HashMap<String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>>()));
|
||||
}
|
||||
|
||||
protected Processor(I iface, Map<String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>> processMap) {
|
||||
super(iface, getProcessMap(processMap));
|
||||
}
|
||||
|
||||
private static <I extends Iface> Map<String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>> getProcessMap(Map<String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>> processMap) {
|
||||
processMap.put("echo", new echo());
|
||||
return processMap;
|
||||
}
|
||||
|
||||
private static class echo<I extends Iface> extends org.apache.thrift.ProcessFunction<I, echo_args> {
|
||||
public echo() {
|
||||
super("echo");
|
||||
}
|
||||
|
||||
protected echo_args getEmptyArgsInstance() {
|
||||
return new echo_args();
|
||||
}
|
||||
|
||||
protected echo_result getResult(I iface, echo_args args) throws org.apache.thrift.TException {
|
||||
echo_result result = new echo_result();
|
||||
result.success = iface.echo(args.arg);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class echo_args implements org.apache.thrift.TBase<echo_args, echo_args._Fields>, java.io.Serializable, Cloneable {
|
||||
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("echo_args");
|
||||
|
||||
private static final org.apache.thrift.protocol.TField ARG_FIELD_DESC = new org.apache.thrift.protocol.TField("arg", org.apache.thrift.protocol.TType.STRING, (short)1);
|
||||
|
||||
public String arg; // required
|
||||
|
||||
/** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
|
||||
public enum _Fields implements org.apache.thrift.TFieldIdEnum {
|
||||
ARG((short)1, "arg");
|
||||
|
||||
private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
|
||||
|
||||
static {
|
||||
for (_Fields field : EnumSet.allOf(_Fields.class)) {
|
||||
byName.put(field.getFieldName(), field);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the _Fields constant that matches fieldId, or null if its not found.
|
||||
*/
|
||||
public static _Fields findByThriftId(int fieldId) {
|
||||
switch(fieldId) {
|
||||
case 1: // ARG
|
||||
return ARG;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the _Fields constant that matches fieldId, throwing an exception
|
||||
* if it is not found.
|
||||
*/
|
||||
public static _Fields findByThriftIdOrThrow(int fieldId) {
|
||||
_Fields fields = findByThriftId(fieldId);
|
||||
if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
|
||||
return fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the _Fields constant that matches name, or null if its not found.
|
||||
*/
|
||||
public static _Fields findByName(String name) {
|
||||
return byName.get(name);
|
||||
}
|
||||
|
||||
private final short _thriftId;
|
||||
private final String _fieldName;
|
||||
|
||||
_Fields(short thriftId, String fieldName) {
|
||||
_thriftId = thriftId;
|
||||
_fieldName = fieldName;
|
||||
}
|
||||
|
||||
public short getThriftFieldId() {
|
||||
return _thriftId;
|
||||
}
|
||||
|
||||
public String getFieldName() {
|
||||
return _fieldName;
|
||||
}
|
||||
}
|
||||
|
||||
// isset id assignments
|
||||
|
||||
public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
|
||||
static {
|
||||
Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
|
||||
tmpMap.put(_Fields.ARG, new org.apache.thrift.meta_data.FieldMetaData("arg", org.apache.thrift.TFieldRequirementType.REQUIRED,
|
||||
new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
|
||||
metaDataMap = Collections.unmodifiableMap(tmpMap);
|
||||
org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(echo_args.class, metaDataMap);
|
||||
}
|
||||
|
||||
public echo_args() {
|
||||
}
|
||||
|
||||
public echo_args(
|
||||
String arg)
|
||||
{
|
||||
this();
|
||||
this.arg = arg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a deep copy on <i>other</i>.
|
||||
*/
|
||||
public echo_args(echo_args other) {
|
||||
if (other.isSetArg()) {
|
||||
this.arg = other.arg;
|
||||
}
|
||||
}
|
||||
|
||||
public echo_args deepCopy() {
|
||||
return new echo_args(this);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.arg = null;
|
||||
}
|
||||
|
||||
public String getArg() {
|
||||
return this.arg;
|
||||
}
|
||||
|
||||
public echo_args setArg(String arg) {
|
||||
this.arg = arg;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void unsetArg() {
|
||||
this.arg = null;
|
||||
}
|
||||
|
||||
/** Returns true if field arg is set (has been assigned a value) and false otherwise */
|
||||
public boolean isSetArg() {
|
||||
return this.arg != null;
|
||||
}
|
||||
|
||||
public void setArgIsSet(boolean value) {
|
||||
if (!value) {
|
||||
this.arg = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setFieldValue(_Fields field, Object value) {
|
||||
switch (field) {
|
||||
case ARG:
|
||||
if (value == null) {
|
||||
unsetArg();
|
||||
} else {
|
||||
setArg((String)value);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public Object getFieldValue(_Fields field) {
|
||||
switch (field) {
|
||||
case ARG:
|
||||
return getArg();
|
||||
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
/** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
|
||||
public boolean isSet(_Fields field) {
|
||||
if (field == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
switch (field) {
|
||||
case ARG:
|
||||
return isSetArg();
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object that) {
|
||||
if (that == null)
|
||||
return false;
|
||||
if (that instanceof echo_args)
|
||||
return this.equals((echo_args)that);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean equals(echo_args that) {
|
||||
if (that == null)
|
||||
return false;
|
||||
|
||||
boolean this_present_arg = true && this.isSetArg();
|
||||
boolean that_present_arg = true && that.isSetArg();
|
||||
if (this_present_arg || that_present_arg) {
|
||||
if (!(this_present_arg && that_present_arg))
|
||||
return false;
|
||||
if (!this.arg.equals(that.arg))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int compareTo(echo_args other) {
|
||||
if (!getClass().equals(other.getClass())) {
|
||||
return getClass().getName().compareTo(other.getClass().getName());
|
||||
}
|
||||
|
||||
int lastComparison = 0;
|
||||
echo_args typedOther = (echo_args)other;
|
||||
|
||||
lastComparison = Boolean.valueOf(isSetArg()).compareTo(typedOther.isSetArg());
|
||||
if (lastComparison != 0) {
|
||||
return lastComparison;
|
||||
}
|
||||
if (isSetArg()) {
|
||||
lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.arg, typedOther.arg);
|
||||
if (lastComparison != 0) {
|
||||
return lastComparison;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public _Fields fieldForId(int fieldId) {
|
||||
return _Fields.findByThriftId(fieldId);
|
||||
}
|
||||
|
||||
public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
|
||||
org.apache.thrift.protocol.TField field;
|
||||
iprot.readStructBegin();
|
||||
while (true)
|
||||
{
|
||||
field = iprot.readFieldBegin();
|
||||
if (field.type == org.apache.thrift.protocol.TType.STOP) {
|
||||
break;
|
||||
}
|
||||
switch (field.id) {
|
||||
case 1: // ARG
|
||||
if (field.type == org.apache.thrift.protocol.TType.STRING) {
|
||||
this.arg = iprot.readString();
|
||||
} else {
|
||||
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
|
||||
}
|
||||
iprot.readFieldEnd();
|
||||
}
|
||||
iprot.readStructEnd();
|
||||
|
||||
// check for required fields of primitive type, which can't be checked in the validate method
|
||||
validate();
|
||||
}
|
||||
|
||||
public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
|
||||
validate();
|
||||
|
||||
oprot.writeStructBegin(STRUCT_DESC);
|
||||
if (this.arg != null) {
|
||||
oprot.writeFieldBegin(ARG_FIELD_DESC);
|
||||
oprot.writeString(this.arg);
|
||||
oprot.writeFieldEnd();
|
||||
}
|
||||
oprot.writeFieldStop();
|
||||
oprot.writeStructEnd();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder("echo_args(");
|
||||
boolean first = true;
|
||||
|
||||
sb.append("arg:");
|
||||
if (this.arg == null) {
|
||||
sb.append("null");
|
||||
} else {
|
||||
sb.append(this.arg);
|
||||
}
|
||||
first = false;
|
||||
sb.append(")");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public void validate() throws org.apache.thrift.TException {
|
||||
// check for required fields
|
||||
if (arg == null) {
|
||||
throw new org.apache.thrift.protocol.TProtocolException("Required field 'arg' was not present! Struct: " + toString());
|
||||
}
|
||||
}
|
||||
|
||||
private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
|
||||
try {
|
||||
write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
|
||||
} catch (org.apache.thrift.TException te) {
|
||||
throw new java.io.IOException(te);
|
||||
}
|
||||
}
|
||||
|
||||
private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
|
||||
try {
|
||||
read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
|
||||
} catch (org.apache.thrift.TException te) {
|
||||
throw new java.io.IOException(te);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class echo_result implements org.apache.thrift.TBase<echo_result, echo_result._Fields>, java.io.Serializable, Cloneable {
|
||||
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("echo_result");
|
||||
|
||||
private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRING, (short)0);
|
||||
|
||||
public String success; // required
|
||||
|
||||
/** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
|
||||
public enum _Fields implements org.apache.thrift.TFieldIdEnum {
|
||||
SUCCESS((short)0, "success");
|
||||
|
||||
private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
|
||||
|
||||
static {
|
||||
for (_Fields field : EnumSet.allOf(_Fields.class)) {
|
||||
byName.put(field.getFieldName(), field);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the _Fields constant that matches fieldId, or null if its not found.
|
||||
*/
|
||||
public static _Fields findByThriftId(int fieldId) {
|
||||
switch(fieldId) {
|
||||
case 0: // SUCCESS
|
||||
return SUCCESS;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the _Fields constant that matches fieldId, throwing an exception
|
||||
* if it is not found.
|
||||
*/
|
||||
public static _Fields findByThriftIdOrThrow(int fieldId) {
|
||||
_Fields fields = findByThriftId(fieldId);
|
||||
if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
|
||||
return fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the _Fields constant that matches name, or null if its not found.
|
||||
*/
|
||||
public static _Fields findByName(String name) {
|
||||
return byName.get(name);
|
||||
}
|
||||
|
||||
private final short _thriftId;
|
||||
private final String _fieldName;
|
||||
|
||||
_Fields(short thriftId, String fieldName) {
|
||||
_thriftId = thriftId;
|
||||
_fieldName = fieldName;
|
||||
}
|
||||
|
||||
public short getThriftFieldId() {
|
||||
return _thriftId;
|
||||
}
|
||||
|
||||
public String getFieldName() {
|
||||
return _fieldName;
|
||||
}
|
||||
}
|
||||
|
||||
// isset id assignments
|
||||
|
||||
public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
|
||||
static {
|
||||
Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
|
||||
tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT,
|
||||
new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
|
||||
metaDataMap = Collections.unmodifiableMap(tmpMap);
|
||||
org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(echo_result.class, metaDataMap);
|
||||
}
|
||||
|
||||
public echo_result() {
|
||||
}
|
||||
|
||||
public echo_result(
|
||||
String success)
|
||||
{
|
||||
this();
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a deep copy on <i>other</i>.
|
||||
*/
|
||||
public echo_result(echo_result other) {
|
||||
if (other.isSetSuccess()) {
|
||||
this.success = other.success;
|
||||
}
|
||||
}
|
||||
|
||||
public echo_result deepCopy() {
|
||||
return new echo_result(this);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.success = null;
|
||||
}
|
||||
|
||||
public String getSuccess() {
|
||||
return this.success;
|
||||
}
|
||||
|
||||
public echo_result setSuccess(String success) {
|
||||
this.success = success;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void unsetSuccess() {
|
||||
this.success = null;
|
||||
}
|
||||
|
||||
/** Returns true if field success is set (has been assigned a value) and false otherwise */
|
||||
public boolean isSetSuccess() {
|
||||
return this.success != null;
|
||||
}
|
||||
|
||||
public void setSuccessIsSet(boolean value) {
|
||||
if (!value) {
|
||||
this.success = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setFieldValue(_Fields field, Object value) {
|
||||
switch (field) {
|
||||
case SUCCESS:
|
||||
if (value == null) {
|
||||
unsetSuccess();
|
||||
} else {
|
||||
setSuccess((String)value);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public Object getFieldValue(_Fields field) {
|
||||
switch (field) {
|
||||
case SUCCESS:
|
||||
return getSuccess();
|
||||
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
/** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
|
||||
public boolean isSet(_Fields field) {
|
||||
if (field == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
switch (field) {
|
||||
case SUCCESS:
|
||||
return isSetSuccess();
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object that) {
|
||||
if (that == null)
|
||||
return false;
|
||||
if (that instanceof echo_result)
|
||||
return this.equals((echo_result)that);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean equals(echo_result that) {
|
||||
if (that == null)
|
||||
return false;
|
||||
|
||||
boolean this_present_success = true && this.isSetSuccess();
|
||||
boolean that_present_success = true && that.isSetSuccess();
|
||||
if (this_present_success || that_present_success) {
|
||||
if (!(this_present_success && that_present_success))
|
||||
return false;
|
||||
if (!this.success.equals(that.success))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int compareTo(echo_result other) {
|
||||
if (!getClass().equals(other.getClass())) {
|
||||
return getClass().getName().compareTo(other.getClass().getName());
|
||||
}
|
||||
|
||||
int lastComparison = 0;
|
||||
echo_result typedOther = (echo_result)other;
|
||||
|
||||
lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(typedOther.isSetSuccess());
|
||||
if (lastComparison != 0) {
|
||||
return lastComparison;
|
||||
}
|
||||
if (isSetSuccess()) {
|
||||
lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, typedOther.success);
|
||||
if (lastComparison != 0) {
|
||||
return lastComparison;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public _Fields fieldForId(int fieldId) {
|
||||
return _Fields.findByThriftId(fieldId);
|
||||
}
|
||||
|
||||
public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
|
||||
org.apache.thrift.protocol.TField field;
|
||||
iprot.readStructBegin();
|
||||
while (true)
|
||||
{
|
||||
field = iprot.readFieldBegin();
|
||||
if (field.type == org.apache.thrift.protocol.TType.STOP) {
|
||||
break;
|
||||
}
|
||||
switch (field.id) {
|
||||
case 0: // SUCCESS
|
||||
if (field.type == org.apache.thrift.protocol.TType.STRING) {
|
||||
this.success = iprot.readString();
|
||||
} else {
|
||||
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
|
||||
}
|
||||
iprot.readFieldEnd();
|
||||
}
|
||||
iprot.readStructEnd();
|
||||
|
||||
// check for required fields of primitive type, which can't be checked in the validate method
|
||||
validate();
|
||||
}
|
||||
|
||||
public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
|
||||
oprot.writeStructBegin(STRUCT_DESC);
|
||||
|
||||
if (this.isSetSuccess()) {
|
||||
oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
|
||||
oprot.writeString(this.success);
|
||||
oprot.writeFieldEnd();
|
||||
}
|
||||
oprot.writeFieldStop();
|
||||
oprot.writeStructEnd();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder("echo_result(");
|
||||
boolean first = true;
|
||||
|
||||
sb.append("success:");
|
||||
if (this.success == null) {
|
||||
sb.append("null");
|
||||
} else {
|
||||
sb.append(this.success);
|
||||
}
|
||||
first = false;
|
||||
sb.append(")");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public void validate() throws org.apache.thrift.TException {
|
||||
// check for required fields
|
||||
}
|
||||
|
||||
private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
|
||||
try {
|
||||
write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
|
||||
} catch (org.apache.thrift.TException te) {
|
||||
throw new java.io.IOException(te);
|
||||
}
|
||||
}
|
||||
|
||||
private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
|
||||
try {
|
||||
read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
|
||||
} catch (org.apache.thrift.TException te) {
|
||||
throw new java.io.IOException(te);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
/**
|
||||
* File Created at 2012-01-09
|
||||
* $Id$
|
||||
*
|
||||
* Copyright 2008 Alibaba.com Croporation Limited.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is the confidential and proprietary information of
|
||||
* Alibaba Company. ("Confidential Information"). You shall not
|
||||
* disclose such Confidential Information and shall use it only in
|
||||
* accordance with the terms of the license agreement you entered into
|
||||
* with Alibaba.com.
|
||||
*/
|
||||
|
||||
import com.alibaba.dubbo.rpc.protocol.thrift.ThriftUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:gang.lvg@alibaba-inc.com">kimi</a>
|
||||
*/
|
||||
public class ClassNameTest {
|
||||
|
||||
@Test
|
||||
public void testThriftUtils() {
|
||||
|
||||
Assert.assertEquals( $__ClassNameTestDubboStub.echo_args.class.getName(),
|
||||
ThriftUtils.generateMethodArgsClassName(
|
||||
ClassNameTestDubbo.class.getName(), "echo" ) );
|
||||
|
||||
Assert.assertEquals( $__ClassNameTestDubboStub.echo_result.class.getName(),
|
||||
ThriftUtils.generateMethodResultClassName(
|
||||
ClassNameTestDubbo.class.getName(), "echo" ) );
|
||||
|
||||
Assert.assertEquals( ClassNameTestThrift.echo_args.class.getName(),
|
||||
ThriftUtils.generateMethodArgsClassNameThrift(
|
||||
ClassNameTestThrift.Iface.class.getName(), "echo" ) );
|
||||
|
||||
Assert.assertEquals( ClassNameTestThrift.echo_result.class.getName(),
|
||||
ThriftUtils.generateMethodResultClassNameThrift(
|
||||
ClassNameTestThrift.Iface.class.getName(), "echo" ));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
/**
|
||||
* Autogenerated by Dubbo Compiler (0.1.0)
|
||||
*
|
||||
* Thrift (0.7.0)
|
||||
*
|
||||
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
|
||||
*/
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.EnumMap;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Collections;
|
||||
import java.util.BitSet;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public interface ClassNameTestDubbo {
|
||||
|
||||
public String echo(String arg);
|
||||
|
||||
}
|
||||
|
|
@ -1,757 +0,0 @@
|
|||
/**
|
||||
* Autogenerated by Thrift Compiler (0.7.0)
|
||||
*
|
||||
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
|
||||
*/
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.EnumMap;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Collections;
|
||||
import java.util.BitSet;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class ClassNameTestThrift {
|
||||
|
||||
public interface Iface {
|
||||
|
||||
public String echo(String arg) throws org.apache.thrift.TException;
|
||||
|
||||
}
|
||||
|
||||
public interface AsyncIface {
|
||||
|
||||
public void echo(String arg, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.echo_call> resultHandler) throws org.apache.thrift.TException;
|
||||
|
||||
}
|
||||
|
||||
public static class Client extends org.apache.thrift.TServiceClient implements Iface {
|
||||
public static class Factory implements org.apache.thrift.TServiceClientFactory<Client> {
|
||||
public Factory() {}
|
||||
public Client getClient(org.apache.thrift.protocol.TProtocol prot) {
|
||||
return new Client(prot);
|
||||
}
|
||||
public Client getClient(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
|
||||
return new Client(iprot, oprot);
|
||||
}
|
||||
}
|
||||
|
||||
public Client(org.apache.thrift.protocol.TProtocol prot)
|
||||
{
|
||||
super(prot, prot);
|
||||
}
|
||||
|
||||
public Client(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
|
||||
super(iprot, oprot);
|
||||
}
|
||||
|
||||
public String echo(String arg) throws org.apache.thrift.TException
|
||||
{
|
||||
send_echo(arg);
|
||||
return recv_echo();
|
||||
}
|
||||
|
||||
public void send_echo(String arg) throws org.apache.thrift.TException
|
||||
{
|
||||
echo_args args = new echo_args();
|
||||
args.setArg(arg);
|
||||
sendBase("echo", args);
|
||||
}
|
||||
|
||||
public String recv_echo() throws org.apache.thrift.TException
|
||||
{
|
||||
echo_result result = new echo_result();
|
||||
receiveBase(result, "echo");
|
||||
if (result.isSetSuccess()) {
|
||||
return result.success;
|
||||
}
|
||||
throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "echo failed: unknown result");
|
||||
}
|
||||
|
||||
}
|
||||
public static class AsyncClient extends org.apache.thrift.async.TAsyncClient implements AsyncIface {
|
||||
public static class Factory implements org.apache.thrift.async.TAsyncClientFactory<AsyncClient> {
|
||||
private org.apache.thrift.async.TAsyncClientManager clientManager;
|
||||
private org.apache.thrift.protocol.TProtocolFactory protocolFactory;
|
||||
public Factory(org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.protocol.TProtocolFactory protocolFactory) {
|
||||
this.clientManager = clientManager;
|
||||
this.protocolFactory = protocolFactory;
|
||||
}
|
||||
public AsyncClient getAsyncClient(org.apache.thrift.transport.TNonblockingTransport transport) {
|
||||
return new AsyncClient(protocolFactory, clientManager, transport);
|
||||
}
|
||||
}
|
||||
|
||||
public AsyncClient(org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.transport.TNonblockingTransport transport) {
|
||||
super(protocolFactory, clientManager, transport);
|
||||
}
|
||||
|
||||
public void echo(String arg, org.apache.thrift.async.AsyncMethodCallback<echo_call> resultHandler) throws org.apache.thrift.TException {
|
||||
checkReady();
|
||||
echo_call method_call = new echo_call(arg, resultHandler, this, ___protocolFactory, ___transport);
|
||||
this.___currentMethod = method_call;
|
||||
___manager.call(method_call);
|
||||
}
|
||||
|
||||
public static class echo_call extends org.apache.thrift.async.TAsyncMethodCall {
|
||||
private String arg;
|
||||
public echo_call(String arg, org.apache.thrift.async.AsyncMethodCallback<echo_call> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
|
||||
super(client, protocolFactory, transport, resultHandler, false);
|
||||
this.arg = arg;
|
||||
}
|
||||
|
||||
public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
|
||||
prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("echo", org.apache.thrift.protocol.TMessageType.CALL, 0));
|
||||
echo_args args = new echo_args();
|
||||
args.setArg(arg);
|
||||
args.write(prot);
|
||||
prot.writeMessageEnd();
|
||||
}
|
||||
|
||||
public String getResult() throws org.apache.thrift.TException {
|
||||
if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
|
||||
throw new IllegalStateException("Method call not finished!");
|
||||
}
|
||||
org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
|
||||
org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
|
||||
return (new Client(prot)).recv_echo();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Processor<I extends Iface> extends org.apache.thrift.TBaseProcessor implements org.apache.thrift.TProcessor {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(Processor.class.getName());
|
||||
public Processor(I iface) {
|
||||
super(iface, getProcessMap(new HashMap<String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>>()));
|
||||
}
|
||||
|
||||
protected Processor(I iface, Map<String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>> processMap) {
|
||||
super(iface, getProcessMap(processMap));
|
||||
}
|
||||
|
||||
private static <I extends Iface> Map<String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>> getProcessMap(Map<String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>> processMap) {
|
||||
processMap.put("echo", new echo());
|
||||
return processMap;
|
||||
}
|
||||
|
||||
private static class echo<I extends Iface> extends org.apache.thrift.ProcessFunction<I, echo_args> {
|
||||
public echo() {
|
||||
super("echo");
|
||||
}
|
||||
|
||||
protected echo_args getEmptyArgsInstance() {
|
||||
return new echo_args();
|
||||
}
|
||||
|
||||
protected echo_result getResult(I iface, echo_args args) throws org.apache.thrift.TException {
|
||||
echo_result result = new echo_result();
|
||||
result.success = iface.echo(args.arg);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class echo_args implements org.apache.thrift.TBase<echo_args, echo_args._Fields>, java.io.Serializable, Cloneable {
|
||||
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("echo_args");
|
||||
|
||||
private static final org.apache.thrift.protocol.TField ARG_FIELD_DESC = new org.apache.thrift.protocol.TField("arg", org.apache.thrift.protocol.TType.STRING, (short)1);
|
||||
|
||||
public String arg; // required
|
||||
|
||||
/** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
|
||||
public enum _Fields implements org.apache.thrift.TFieldIdEnum {
|
||||
ARG((short)1, "arg");
|
||||
|
||||
private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
|
||||
|
||||
static {
|
||||
for (_Fields field : EnumSet.allOf(_Fields.class)) {
|
||||
byName.put(field.getFieldName(), field);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the _Fields constant that matches fieldId, or null if its not found.
|
||||
*/
|
||||
public static _Fields findByThriftId(int fieldId) {
|
||||
switch(fieldId) {
|
||||
case 1: // ARG
|
||||
return ARG;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the _Fields constant that matches fieldId, throwing an exception
|
||||
* if it is not found.
|
||||
*/
|
||||
public static _Fields findByThriftIdOrThrow(int fieldId) {
|
||||
_Fields fields = findByThriftId(fieldId);
|
||||
if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
|
||||
return fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the _Fields constant that matches name, or null if its not found.
|
||||
*/
|
||||
public static _Fields findByName(String name) {
|
||||
return byName.get(name);
|
||||
}
|
||||
|
||||
private final short _thriftId;
|
||||
private final String _fieldName;
|
||||
|
||||
_Fields(short thriftId, String fieldName) {
|
||||
_thriftId = thriftId;
|
||||
_fieldName = fieldName;
|
||||
}
|
||||
|
||||
public short getThriftFieldId() {
|
||||
return _thriftId;
|
||||
}
|
||||
|
||||
public String getFieldName() {
|
||||
return _fieldName;
|
||||
}
|
||||
}
|
||||
|
||||
// isset id assignments
|
||||
|
||||
public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
|
||||
static {
|
||||
Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
|
||||
tmpMap.put(_Fields.ARG, new org.apache.thrift.meta_data.FieldMetaData("arg", org.apache.thrift.TFieldRequirementType.REQUIRED,
|
||||
new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
|
||||
metaDataMap = Collections.unmodifiableMap(tmpMap);
|
||||
org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(echo_args.class, metaDataMap);
|
||||
}
|
||||
|
||||
public echo_args() {
|
||||
}
|
||||
|
||||
public echo_args(
|
||||
String arg)
|
||||
{
|
||||
this();
|
||||
this.arg = arg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a deep copy on <i>other</i>.
|
||||
*/
|
||||
public echo_args(echo_args other) {
|
||||
if (other.isSetArg()) {
|
||||
this.arg = other.arg;
|
||||
}
|
||||
}
|
||||
|
||||
public echo_args deepCopy() {
|
||||
return new echo_args(this);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.arg = null;
|
||||
}
|
||||
|
||||
public String getArg() {
|
||||
return this.arg;
|
||||
}
|
||||
|
||||
public echo_args setArg(String arg) {
|
||||
this.arg = arg;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void unsetArg() {
|
||||
this.arg = null;
|
||||
}
|
||||
|
||||
/** Returns true if field arg is set (has been assigned a value) and false otherwise */
|
||||
public boolean isSetArg() {
|
||||
return this.arg != null;
|
||||
}
|
||||
|
||||
public void setArgIsSet(boolean value) {
|
||||
if (!value) {
|
||||
this.arg = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setFieldValue(_Fields field, Object value) {
|
||||
switch (field) {
|
||||
case ARG:
|
||||
if (value == null) {
|
||||
unsetArg();
|
||||
} else {
|
||||
setArg((String)value);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public Object getFieldValue(_Fields field) {
|
||||
switch (field) {
|
||||
case ARG:
|
||||
return getArg();
|
||||
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
/** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
|
||||
public boolean isSet(_Fields field) {
|
||||
if (field == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
switch (field) {
|
||||
case ARG:
|
||||
return isSetArg();
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object that) {
|
||||
if (that == null)
|
||||
return false;
|
||||
if (that instanceof echo_args)
|
||||
return this.equals((echo_args)that);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean equals(echo_args that) {
|
||||
if (that == null)
|
||||
return false;
|
||||
|
||||
boolean this_present_arg = true && this.isSetArg();
|
||||
boolean that_present_arg = true && that.isSetArg();
|
||||
if (this_present_arg || that_present_arg) {
|
||||
if (!(this_present_arg && that_present_arg))
|
||||
return false;
|
||||
if (!this.arg.equals(that.arg))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int compareTo(echo_args other) {
|
||||
if (!getClass().equals(other.getClass())) {
|
||||
return getClass().getName().compareTo(other.getClass().getName());
|
||||
}
|
||||
|
||||
int lastComparison = 0;
|
||||
echo_args typedOther = (echo_args)other;
|
||||
|
||||
lastComparison = Boolean.valueOf(isSetArg()).compareTo(typedOther.isSetArg());
|
||||
if (lastComparison != 0) {
|
||||
return lastComparison;
|
||||
}
|
||||
if (isSetArg()) {
|
||||
lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.arg, typedOther.arg);
|
||||
if (lastComparison != 0) {
|
||||
return lastComparison;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public _Fields fieldForId(int fieldId) {
|
||||
return _Fields.findByThriftId(fieldId);
|
||||
}
|
||||
|
||||
public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
|
||||
org.apache.thrift.protocol.TField field;
|
||||
iprot.readStructBegin();
|
||||
while (true)
|
||||
{
|
||||
field = iprot.readFieldBegin();
|
||||
if (field.type == org.apache.thrift.protocol.TType.STOP) {
|
||||
break;
|
||||
}
|
||||
switch (field.id) {
|
||||
case 1: // ARG
|
||||
if (field.type == org.apache.thrift.protocol.TType.STRING) {
|
||||
this.arg = iprot.readString();
|
||||
} else {
|
||||
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
|
||||
}
|
||||
iprot.readFieldEnd();
|
||||
}
|
||||
iprot.readStructEnd();
|
||||
|
||||
// check for required fields of primitive type, which can't be checked in the validate method
|
||||
validate();
|
||||
}
|
||||
|
||||
public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
|
||||
validate();
|
||||
|
||||
oprot.writeStructBegin(STRUCT_DESC);
|
||||
if (this.arg != null) {
|
||||
oprot.writeFieldBegin(ARG_FIELD_DESC);
|
||||
oprot.writeString(this.arg);
|
||||
oprot.writeFieldEnd();
|
||||
}
|
||||
oprot.writeFieldStop();
|
||||
oprot.writeStructEnd();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder("echo_args(");
|
||||
boolean first = true;
|
||||
|
||||
sb.append("arg:");
|
||||
if (this.arg == null) {
|
||||
sb.append("null");
|
||||
} else {
|
||||
sb.append(this.arg);
|
||||
}
|
||||
first = false;
|
||||
sb.append(")");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public void validate() throws org.apache.thrift.TException {
|
||||
// check for required fields
|
||||
if (arg == null) {
|
||||
throw new org.apache.thrift.protocol.TProtocolException("Required field 'arg' was not present! Struct: " + toString());
|
||||
}
|
||||
}
|
||||
|
||||
private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
|
||||
try {
|
||||
write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
|
||||
} catch (org.apache.thrift.TException te) {
|
||||
throw new java.io.IOException(te);
|
||||
}
|
||||
}
|
||||
|
||||
private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
|
||||
try {
|
||||
read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
|
||||
} catch (org.apache.thrift.TException te) {
|
||||
throw new java.io.IOException(te);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class echo_result implements org.apache.thrift.TBase<echo_result, echo_result._Fields>, java.io.Serializable, Cloneable {
|
||||
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("echo_result");
|
||||
|
||||
private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRING, (short)0);
|
||||
|
||||
public String success; // required
|
||||
|
||||
/** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
|
||||
public enum _Fields implements org.apache.thrift.TFieldIdEnum {
|
||||
SUCCESS((short)0, "success");
|
||||
|
||||
private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
|
||||
|
||||
static {
|
||||
for (_Fields field : EnumSet.allOf(_Fields.class)) {
|
||||
byName.put(field.getFieldName(), field);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the _Fields constant that matches fieldId, or null if its not found.
|
||||
*/
|
||||
public static _Fields findByThriftId(int fieldId) {
|
||||
switch(fieldId) {
|
||||
case 0: // SUCCESS
|
||||
return SUCCESS;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the _Fields constant that matches fieldId, throwing an exception
|
||||
* if it is not found.
|
||||
*/
|
||||
public static _Fields findByThriftIdOrThrow(int fieldId) {
|
||||
_Fields fields = findByThriftId(fieldId);
|
||||
if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
|
||||
return fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the _Fields constant that matches name, or null if its not found.
|
||||
*/
|
||||
public static _Fields findByName(String name) {
|
||||
return byName.get(name);
|
||||
}
|
||||
|
||||
private final short _thriftId;
|
||||
private final String _fieldName;
|
||||
|
||||
_Fields(short thriftId, String fieldName) {
|
||||
_thriftId = thriftId;
|
||||
_fieldName = fieldName;
|
||||
}
|
||||
|
||||
public short getThriftFieldId() {
|
||||
return _thriftId;
|
||||
}
|
||||
|
||||
public String getFieldName() {
|
||||
return _fieldName;
|
||||
}
|
||||
}
|
||||
|
||||
// isset id assignments
|
||||
|
||||
public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
|
||||
static {
|
||||
Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
|
||||
tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT,
|
||||
new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
|
||||
metaDataMap = Collections.unmodifiableMap(tmpMap);
|
||||
org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(echo_result.class, metaDataMap);
|
||||
}
|
||||
|
||||
public echo_result() {
|
||||
}
|
||||
|
||||
public echo_result(
|
||||
String success)
|
||||
{
|
||||
this();
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a deep copy on <i>other</i>.
|
||||
*/
|
||||
public echo_result(echo_result other) {
|
||||
if (other.isSetSuccess()) {
|
||||
this.success = other.success;
|
||||
}
|
||||
}
|
||||
|
||||
public echo_result deepCopy() {
|
||||
return new echo_result(this);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.success = null;
|
||||
}
|
||||
|
||||
public String getSuccess() {
|
||||
return this.success;
|
||||
}
|
||||
|
||||
public echo_result setSuccess(String success) {
|
||||
this.success = success;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void unsetSuccess() {
|
||||
this.success = null;
|
||||
}
|
||||
|
||||
/** Returns true if field success is set (has been assigned a value) and false otherwise */
|
||||
public boolean isSetSuccess() {
|
||||
return this.success != null;
|
||||
}
|
||||
|
||||
public void setSuccessIsSet(boolean value) {
|
||||
if (!value) {
|
||||
this.success = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setFieldValue(_Fields field, Object value) {
|
||||
switch (field) {
|
||||
case SUCCESS:
|
||||
if (value == null) {
|
||||
unsetSuccess();
|
||||
} else {
|
||||
setSuccess((String)value);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public Object getFieldValue(_Fields field) {
|
||||
switch (field) {
|
||||
case SUCCESS:
|
||||
return getSuccess();
|
||||
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
/** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
|
||||
public boolean isSet(_Fields field) {
|
||||
if (field == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
switch (field) {
|
||||
case SUCCESS:
|
||||
return isSetSuccess();
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object that) {
|
||||
if (that == null)
|
||||
return false;
|
||||
if (that instanceof echo_result)
|
||||
return this.equals((echo_result)that);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean equals(echo_result that) {
|
||||
if (that == null)
|
||||
return false;
|
||||
|
||||
boolean this_present_success = true && this.isSetSuccess();
|
||||
boolean that_present_success = true && that.isSetSuccess();
|
||||
if (this_present_success || that_present_success) {
|
||||
if (!(this_present_success && that_present_success))
|
||||
return false;
|
||||
if (!this.success.equals(that.success))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int compareTo(echo_result other) {
|
||||
if (!getClass().equals(other.getClass())) {
|
||||
return getClass().getName().compareTo(other.getClass().getName());
|
||||
}
|
||||
|
||||
int lastComparison = 0;
|
||||
echo_result typedOther = (echo_result)other;
|
||||
|
||||
lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(typedOther.isSetSuccess());
|
||||
if (lastComparison != 0) {
|
||||
return lastComparison;
|
||||
}
|
||||
if (isSetSuccess()) {
|
||||
lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, typedOther.success);
|
||||
if (lastComparison != 0) {
|
||||
return lastComparison;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public _Fields fieldForId(int fieldId) {
|
||||
return _Fields.findByThriftId(fieldId);
|
||||
}
|
||||
|
||||
public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
|
||||
org.apache.thrift.protocol.TField field;
|
||||
iprot.readStructBegin();
|
||||
while (true)
|
||||
{
|
||||
field = iprot.readFieldBegin();
|
||||
if (field.type == org.apache.thrift.protocol.TType.STOP) {
|
||||
break;
|
||||
}
|
||||
switch (field.id) {
|
||||
case 0: // SUCCESS
|
||||
if (field.type == org.apache.thrift.protocol.TType.STRING) {
|
||||
this.success = iprot.readString();
|
||||
} else {
|
||||
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
|
||||
}
|
||||
iprot.readFieldEnd();
|
||||
}
|
||||
iprot.readStructEnd();
|
||||
|
||||
// check for required fields of primitive type, which can't be checked in the validate method
|
||||
validate();
|
||||
}
|
||||
|
||||
public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
|
||||
oprot.writeStructBegin(STRUCT_DESC);
|
||||
|
||||
if (this.isSetSuccess()) {
|
||||
oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
|
||||
oprot.writeString(this.success);
|
||||
oprot.writeFieldEnd();
|
||||
}
|
||||
oprot.writeFieldStop();
|
||||
oprot.writeStructEnd();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder("echo_result(");
|
||||
boolean first = true;
|
||||
|
||||
sb.append("success:");
|
||||
if (this.success == null) {
|
||||
sb.append("null");
|
||||
} else {
|
||||
sb.append(this.success);
|
||||
}
|
||||
first = false;
|
||||
sb.append(")");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public void validate() throws org.apache.thrift.TException {
|
||||
// check for required fields
|
||||
}
|
||||
|
||||
private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
|
||||
try {
|
||||
write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
|
||||
} catch (org.apache.thrift.TException te) {
|
||||
throw new java.io.IOException(te);
|
||||
}
|
||||
}
|
||||
|
||||
private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
|
||||
try {
|
||||
read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
|
||||
} catch (org.apache.thrift.TException te) {
|
||||
throw new java.io.IOException(te);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,41 +0,0 @@
|
|||
/**
|
||||
* Autogenerated by Dubbo Compiler (0.1.0)
|
||||
*
|
||||
* Thrift (0.7.0)
|
||||
*
|
||||
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
|
||||
*/
|
||||
package com.alibaba.dubbo.rpc.gen.dubbo;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.EnumMap;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Collections;
|
||||
import java.util.BitSet;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public interface Demo {
|
||||
|
||||
public boolean echoBool(boolean arg);
|
||||
|
||||
public byte echoByte(byte arg);
|
||||
|
||||
public short echoI16(short arg);
|
||||
|
||||
public int echoI32(int arg);
|
||||
|
||||
public long echoI64(long arg);
|
||||
|
||||
public double echoDouble(double arg);
|
||||
|
||||
public String echoString(String arg);
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,137 +0,0 @@
|
|||
/**
|
||||
* File Created at 2011-11-25
|
||||
* $Id$
|
||||
*
|
||||
* Copyright 2008 Alibaba.com Croporation Limited.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is the confidential and proprietary information of
|
||||
* Alibaba Company. ("Confidential Information"). You shall not
|
||||
* disclose such Confidential Information and shall use it only in
|
||||
* accordance with the terms of the license agreement you entered into
|
||||
* with Alibaba.com.
|
||||
*/
|
||||
package com.alibaba.dubbo.rpc.protocol.thrift;
|
||||
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.common.extension.ExtensionLoader;
|
||||
import com.alibaba.dubbo.rpc.Invoker;
|
||||
import com.alibaba.dubbo.rpc.Protocol;
|
||||
import com.alibaba.dubbo.rpc.gen.dubbo.$__DemoStub;
|
||||
import com.alibaba.dubbo.rpc.gen.dubbo.Demo;
|
||||
import com.alibaba.dubbo.rpc.protocol.thrift.ext.MultiServiceProcessor;
|
||||
import org.apache.thrift.TProcessor;
|
||||
import org.apache.thrift.protocol.TBinaryProtocol;
|
||||
import org.apache.thrift.server.TServer;
|
||||
import org.apache.thrift.server.TThreadPoolServer;
|
||||
import org.apache.thrift.transport.TServerSocket;
|
||||
import org.apache.thrift.transport.TServerTransport;
|
||||
import org.apache.thrift.transport.TTransportFactory;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
||||
/**
|
||||
* @author gang.lvg 2011-11-25 13:05
|
||||
*/
|
||||
public abstract class AbstractTest {
|
||||
|
||||
static final int PORT = 30660;
|
||||
|
||||
protected TServer server;
|
||||
|
||||
protected Protocol protocol;
|
||||
|
||||
protected Invoker<?> invoker;
|
||||
|
||||
protected void init() throws Exception {
|
||||
TServerTransport serverTransport = new TServerSocket( PORT );
|
||||
|
||||
TBinaryProtocol.Factory bFactory = new TBinaryProtocol.Factory();
|
||||
|
||||
server = new TThreadPoolServer(
|
||||
new TThreadPoolServer.Args( serverTransport )
|
||||
.inputProtocolFactory( bFactory )
|
||||
.outputProtocolFactory( bFactory )
|
||||
.inputTransportFactory( getTransportFactory() )
|
||||
.outputTransportFactory( getTransportFactory() )
|
||||
.processor( getProcessor() ) );
|
||||
|
||||
Thread startTread = new Thread() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
server.serve();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
startTread.setName( "thrift-server" );
|
||||
|
||||
startTread.start();
|
||||
|
||||
while( !server.isServing() ) {
|
||||
Thread.sleep( 100 );
|
||||
}
|
||||
|
||||
protocol = ExtensionLoader.getExtensionLoader(Protocol.class)
|
||||
.getExtension( ThriftProtocol.NAME );
|
||||
|
||||
invoker = protocol.refer( getInterface(), getUrl() );
|
||||
|
||||
}
|
||||
|
||||
protected void destroy() throws Exception {
|
||||
|
||||
if ( server != null ) {
|
||||
server.stop();
|
||||
server = null;
|
||||
}
|
||||
|
||||
if ( protocol != null ) {
|
||||
protocol.destroy();
|
||||
protocol = null;
|
||||
}
|
||||
|
||||
if ( invoker != null ) {
|
||||
invoker.destroy();
|
||||
invoker = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected TTransportFactory getTransportFactory() {
|
||||
return new FramedTransportFactory();
|
||||
}
|
||||
|
||||
protected $__DemoStub.Iface getServiceImpl() {
|
||||
return new DubboDemoImpl();
|
||||
}
|
||||
|
||||
protected TProcessor getProcessor() {
|
||||
MultiServiceProcessor result = new MultiServiceProcessor();
|
||||
result.addProcessor(
|
||||
com.alibaba.dubbo.rpc.gen.dubbo.Demo.class,
|
||||
new $__DemoStub.Processor( getServiceImpl() ) );
|
||||
return result;
|
||||
}
|
||||
|
||||
protected Class<?> getInterface() {
|
||||
return Demo.class;
|
||||
}
|
||||
|
||||
protected URL getUrl() {
|
||||
return URL.valueOf(
|
||||
"thrift://127.0.0.1:" + PORT + "/" + getInterface().getName() );
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception{
|
||||
destroy();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
init();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
/**
|
||||
* File Created at 2011-11-23
|
||||
* $Id$
|
||||
*
|
||||
* Copyright 2008 Alibaba.com Croporation Limited.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is the confidential and proprietary information of
|
||||
* Alibaba Company. ("Confidential Information"). You shall not
|
||||
* disclose such Confidential Information and shall use it only in
|
||||
* accordance with the terms of the license agreement you entered into
|
||||
* with Alibaba.com.
|
||||
*/
|
||||
package com.alibaba.dubbo.rpc.protocol.thrift;
|
||||
|
||||
/**
|
||||
* @author gang.lvg 2011-11-23 14:17
|
||||
*/
|
||||
public class DemoImpl {
|
||||
|
||||
public boolean echoBool( boolean arg ) {
|
||||
|
||||
return arg;
|
||||
}
|
||||
|
||||
public byte echoByte( byte arg ) {
|
||||
|
||||
return arg;
|
||||
}
|
||||
|
||||
public short echoI16( short arg ) {
|
||||
|
||||
return arg;
|
||||
}
|
||||
|
||||
public int echoI32( int arg ) {
|
||||
|
||||
return arg;
|
||||
}
|
||||
|
||||
public long echoI64( long arg ) {
|
||||
|
||||
return arg;
|
||||
}
|
||||
|
||||
public double echoDouble( double arg ) {
|
||||
|
||||
return arg;
|
||||
}
|
||||
|
||||
public String echoString( String arg ) {
|
||||
|
||||
return arg;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
/**
|
||||
* File Created at 2011-12-31
|
||||
* $Id$
|
||||
*
|
||||
* Copyright 2008 Alibaba.com Croporation Limited.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is the confidential and proprietary information of
|
||||
* Alibaba Company. ("Confidential Information"). You shall not
|
||||
* disclose such Confidential Information and shall use it only in
|
||||
* accordance with the terms of the license agreement you entered into
|
||||
* with Alibaba.com.
|
||||
*/
|
||||
package com.alibaba.dubbo.rpc.protocol.thrift;
|
||||
|
||||
import com.alibaba.dubbo.rpc.gen.dubbo.$__DemoStub;
|
||||
import com.alibaba.dubbo.rpc.gen.dubbo.Demo;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:gang.lvg@alibaba-inc.com">kimi</a>
|
||||
*/
|
||||
public class DubboDemoImpl extends DemoImpl implements Demo, $__DemoStub.Iface {}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
/**
|
||||
* File Created at 2011-12-09
|
||||
* $Id$
|
||||
*
|
||||
* Copyright 2008 Alibaba.com Croporation Limited.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is the confidential and proprietary information of
|
||||
* Alibaba Company. ("Confidential Information"). You shall not
|
||||
* disclose such Confidential Information and shall use it only in
|
||||
* accordance with the terms of the license agreement you entered into
|
||||
* with Alibaba.com.
|
||||
*/
|
||||
package com.alibaba.dubbo.rpc.protocol.thrift;
|
||||
|
||||
import org.apache.thrift.transport.TFramedTransport;
|
||||
import org.apache.thrift.transport.TTransport;
|
||||
import org.apache.thrift.transport.TTransportFactory;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:gang.lvg@alibaba-inc.com">kimi</a>
|
||||
*/
|
||||
public class FramedTransportFactory extends TTransportFactory {
|
||||
|
||||
@Override
|
||||
public TTransport getTransport( TTransport trans ) {
|
||||
|
||||
return new TFramedTransport( trans );
|
||||
}
|
||||
}
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
/**
|
||||
* File Created at 2011-12-06
|
||||
* $Id$
|
||||
*
|
||||
* Copyright 2008 Alibaba.com Croporation Limited.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is the confidential and proprietary information of
|
||||
* Alibaba Company. ("Confidential Information"). You shall not
|
||||
* disclose such Confidential Information and shall use it only in
|
||||
* accordance with the terms of the license agreement you entered into
|
||||
* with Alibaba.com.
|
||||
*/
|
||||
package com.alibaba.dubbo.rpc.protocol.thrift;
|
||||
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.remoting.Channel;
|
||||
import com.alibaba.dubbo.remoting.ChannelHandler;
|
||||
import com.alibaba.dubbo.remoting.RemotingException;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:gang.lvg@alibaba-inc.com">gang.lvg</a>
|
||||
*/
|
||||
public class MockedChannel implements Channel {
|
||||
|
||||
private URL url;
|
||||
|
||||
public MockedChannel( URL url ) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public InetSocketAddress getRemoteAddress() {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isConnected() {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasAttribute( String key ) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public Object getAttribute( String key ) {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setAttribute( String key, Object value ) {
|
||||
|
||||
}
|
||||
|
||||
public void removeAttribute( String key ) {
|
||||
|
||||
}
|
||||
|
||||
public URL getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public ChannelHandler getChannelHandler() {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public InetSocketAddress getLocalAddress() {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void send( Object message ) throws RemotingException {
|
||||
|
||||
}
|
||||
|
||||
public void send( Object message, boolean sent ) throws RemotingException {
|
||||
|
||||
}
|
||||
|
||||
public void close() {
|
||||
|
||||
}
|
||||
|
||||
public void close( int timeout ) {
|
||||
|
||||
}
|
||||
|
||||
public boolean isClosed() {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
/**
|
||||
* File Created at 2011-12-09
|
||||
* $Id$
|
||||
*
|
||||
* Copyright 2008 Alibaba.com Croporation Limited.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is the confidential and proprietary information of
|
||||
* Alibaba Company. ("Confidential Information"). You shall not
|
||||
* disclose such Confidential Information and shall use it only in
|
||||
* accordance with the terms of the license agreement you entered into
|
||||
* with Alibaba.com.
|
||||
*/
|
||||
package com.alibaba.dubbo.rpc.protocol.thrift;
|
||||
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.rpc.Result;
|
||||
import com.alibaba.dubbo.rpc.RpcException;
|
||||
import com.alibaba.dubbo.rpc.RpcInvocation;
|
||||
import com.alibaba.dubbo.rpc.gen.dubbo.$__DemoStub;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:gang.lvg@alibaba-inc.com">kimi</a>
|
||||
*/
|
||||
public class ServerExceptionTest extends AbstractTest {
|
||||
|
||||
@Override
|
||||
protected $__DemoStub.Iface getServiceImpl() {
|
||||
|
||||
return new $__DemoStub.Iface () {
|
||||
|
||||
public boolean echoBool( boolean arg ) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public byte echoByte( byte arg ) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public short echoI16( short arg ) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int echoI32( int arg ) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public long echoI64( long arg ) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public double echoDouble( double arg ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public String echoString( String arg ) {
|
||||
// 在 server 端,thrift 无法处理 idl 中没有声明的异常
|
||||
throw new RuntimeException( "just for test" );
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@Test( expected = RpcException.class )
|
||||
public void testServerException() throws Exception {
|
||||
|
||||
Assert.assertNotNull( invoker );
|
||||
|
||||
RpcInvocation invocation = new RpcInvocation();
|
||||
|
||||
invocation.setMethodName( "echoString" );
|
||||
|
||||
invocation.setParameterTypes( new Class<?>[]{ String.class } );
|
||||
|
||||
String arg = "Hello, World!";
|
||||
|
||||
invocation.setArguments( new Object[] { arg } );
|
||||
|
||||
Result result = invoker.invoke( invocation );
|
||||
|
||||
System.out.println( result );
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected URL getUrl() {
|
||||
URL url = super.getUrl();
|
||||
// url = url.addParameter( Constants.TIMEOUT_KEY, Integer.MAX_VALUE );
|
||||
return url;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,151 +0,0 @@
|
|||
/**
|
||||
* File Created at 2011-12-09
|
||||
* $Id$
|
||||
*
|
||||
* Copyright 2008 Alibaba.com Croporation Limited.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is the confidential and proprietary information of
|
||||
* Alibaba Company. ("Confidential Information"). You shall not
|
||||
* disclose such Confidential Information and shall use it only in
|
||||
* accordance with the terms of the license agreement you entered into
|
||||
* with Alibaba.com.
|
||||
*/
|
||||
package com.alibaba.dubbo.rpc.protocol.thrift;
|
||||
|
||||
import com.alibaba.dubbo.common.Constants;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.rpc.Result;
|
||||
import com.alibaba.dubbo.rpc.RpcException;
|
||||
import com.alibaba.dubbo.rpc.RpcInvocation;
|
||||
import com.alibaba.dubbo.rpc.gen.dubbo.$__DemoStub;
|
||||
import com.alibaba.dubbo.rpc.gen.dubbo.Demo;
|
||||
import com.alibaba.dubbo.rpc.protocol.thrift.ext.MultiServiceProcessor;
|
||||
import org.apache.thrift.protocol.TBinaryProtocol;
|
||||
import org.apache.thrift.server.TThreadPoolServer;
|
||||
import org.apache.thrift.transport.TServerSocket;
|
||||
import org.apache.thrift.transport.TServerTransport;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:gang.lvg@alibaba-inc.com">kimi</a>
|
||||
*/
|
||||
public class ServiceMethodNotFoundTest extends AbstractTest {
|
||||
|
||||
private URL url;
|
||||
|
||||
protected void init() throws Exception {
|
||||
|
||||
TServerTransport serverTransport = new TServerSocket( PORT );
|
||||
|
||||
DubboDemoImpl impl = new DubboDemoImpl();
|
||||
|
||||
$__DemoStub.Processor processor = new $__DemoStub.Processor( impl );
|
||||
|
||||
// for test
|
||||
Field field = processor.getClass().getSuperclass().getDeclaredField( "processMap" );
|
||||
|
||||
field.setAccessible( true );
|
||||
|
||||
Object obj = field.get( processor );
|
||||
|
||||
if ( obj instanceof Map ) {
|
||||
( ( Map ) obj ).remove( "echoString" );
|
||||
}
|
||||
// ~
|
||||
|
||||
TBinaryProtocol.Factory bFactory = new TBinaryProtocol.Factory();
|
||||
|
||||
MultiServiceProcessor wrapper = new MultiServiceProcessor();
|
||||
wrapper.addProcessor( Demo.class, processor );
|
||||
|
||||
server = new TThreadPoolServer(
|
||||
new TThreadPoolServer.Args( serverTransport )
|
||||
.inputProtocolFactory( bFactory )
|
||||
.outputProtocolFactory( bFactory )
|
||||
.inputTransportFactory( getTransportFactory() )
|
||||
.outputTransportFactory( getTransportFactory() )
|
||||
.processor( wrapper ) );
|
||||
|
||||
Thread startTread = new Thread() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
server.serve();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
startTread.start();
|
||||
|
||||
while ( !server.isServing() ) {
|
||||
Thread.sleep( 100 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
|
||||
init();
|
||||
|
||||
protocol = new ThriftProtocol();
|
||||
|
||||
url = URL.valueOf( ThriftProtocol.NAME + "://127.0.0.1:" + PORT + "/" + Demo.class.getName() );
|
||||
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
|
||||
destroy();
|
||||
|
||||
if ( protocol != null ) {
|
||||
protocol.destroy();
|
||||
protocol = null;
|
||||
}
|
||||
|
||||
if ( invoker != null ) {
|
||||
invoker.destroy();
|
||||
invoker = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServiceMethodNotFound() throws Exception {
|
||||
// FIXME
|
||||
/*url = url.addParameter( "echoString." + Constants.TIMEOUT_KEY, Integer.MAX_VALUE );
|
||||
|
||||
invoker = protocol.refer( Demo.class, url );
|
||||
|
||||
org.junit.Assert.assertNotNull( invoker );
|
||||
|
||||
RpcInvocation invocation = new RpcInvocation();
|
||||
|
||||
invocation.setMethodName( "echoString" );
|
||||
|
||||
invocation.setParameterTypes( new Class<?>[]{ String.class } );
|
||||
|
||||
String arg = "Hello, World!";
|
||||
|
||||
invocation.setArguments( new Object[] { arg } );
|
||||
|
||||
invocation.setAttachment(Constants.INTERFACE_KEY, DemoImpl.class.getName());
|
||||
|
||||
Result result = invoker.invoke( invocation );
|
||||
|
||||
Assert.assertNull( result.getResult() );
|
||||
|
||||
Assert.assertTrue( result.getException() instanceof RpcException );*/
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,457 +0,0 @@
|
|||
/**
|
||||
* File Created at 2011-12-05
|
||||
* $Id$
|
||||
*
|
||||
* Copyright 2008 Alibaba.com Croporation Limited.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is the confidential and proprietary information of
|
||||
* Alibaba Company. ("Confidential Information"). You shall not
|
||||
* disclose such Confidential Information and shall use it only in
|
||||
* accordance with the terms of the license agreement you entered into
|
||||
* with Alibaba.com.
|
||||
*/
|
||||
package com.alibaba.dubbo.rpc.protocol.thrift;
|
||||
|
||||
import com.alibaba.dubbo.common.Constants;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.remoting.Channel;
|
||||
import com.alibaba.dubbo.remoting.exchange.Request;
|
||||
import com.alibaba.dubbo.remoting.exchange.Response;
|
||||
import com.alibaba.dubbo.remoting.exchange.support.DefaultFuture;
|
||||
import com.alibaba.dubbo.rpc.RpcException;
|
||||
import com.alibaba.dubbo.rpc.RpcInvocation;
|
||||
import com.alibaba.dubbo.rpc.RpcResult;
|
||||
import com.alibaba.dubbo.rpc.gen.dubbo.$__DemoStub;
|
||||
import com.alibaba.dubbo.rpc.gen.dubbo.Demo;
|
||||
import com.alibaba.dubbo.rpc.protocol.thrift.io.RandomAccessByteArrayOutputStream;
|
||||
import org.apache.thrift.TApplicationException;
|
||||
import org.apache.thrift.protocol.TBinaryProtocol;
|
||||
import org.apache.thrift.protocol.TMessage;
|
||||
import org.apache.thrift.protocol.TMessageType;
|
||||
import org.apache.thrift.transport.TFramedTransport;
|
||||
import org.apache.thrift.transport.TIOStreamTransport;
|
||||
import org.apache.thrift.transport.TTransport;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:gang.lvg@alibaba-inc.com">gang.lvg</a>
|
||||
*/
|
||||
public class ThriftCodecTest {
|
||||
|
||||
private ThriftCodec codec = new ThriftCodec();
|
||||
|
||||
@Test
|
||||
public void testEncodeRequest() throws Exception {
|
||||
|
||||
Request request = createRequest();
|
||||
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream( 1024 );
|
||||
|
||||
codec.encode( ( Channel ) null, output, request );
|
||||
|
||||
byte[] bytes = output.toByteArray();
|
||||
|
||||
ByteArrayInputStream bis = new ByteArrayInputStream( bytes );
|
||||
|
||||
TTransport transport = new TIOStreamTransport( bis );
|
||||
|
||||
TBinaryProtocol protocol = new TBinaryProtocol( transport );
|
||||
|
||||
// frame
|
||||
byte[] length = new byte[4];
|
||||
transport.read( length, 0, 4 );
|
||||
|
||||
if ( bis.markSupported() ) {
|
||||
bis.mark( 0 );
|
||||
}
|
||||
|
||||
// magic
|
||||
Assert.assertEquals( ThriftCodec.MAGIC, protocol.readI16() );
|
||||
|
||||
// message length
|
||||
int messageLength = protocol.readI32();
|
||||
Assert.assertEquals( messageLength + 4, bytes.length );
|
||||
|
||||
// header length
|
||||
short headerLength = protocol.readI16();
|
||||
// version
|
||||
Assert.assertEquals( ThriftCodec.VERSION, protocol.readByte() );
|
||||
// service name
|
||||
Assert.assertEquals( Demo.class.getName(), protocol.readString() );
|
||||
// dubbo request id
|
||||
Assert.assertEquals( request.getId(), protocol.readI64() );
|
||||
|
||||
// test message header length
|
||||
if ( bis.markSupported() ) {
|
||||
bis.reset();
|
||||
bis.skip( headerLength );
|
||||
}
|
||||
|
||||
TMessage message = protocol.readMessageBegin();
|
||||
|
||||
$__DemoStub.echoString_args args = new $__DemoStub.echoString_args();
|
||||
|
||||
args.read( protocol );
|
||||
|
||||
protocol.readMessageEnd();
|
||||
|
||||
Assert.assertEquals( "echoString", message.name );
|
||||
|
||||
Assert.assertEquals( TMessageType.CALL, message.type );
|
||||
|
||||
Assert.assertEquals( "Hello, World!", args.getArg() );
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDecodeReplyResponse() throws Exception {
|
||||
|
||||
URL url = URL.valueOf( ThriftProtocol.NAME + "://127.0.0.1:40880/" + Demo.class.getName() );
|
||||
|
||||
Channel channel = new MockedChannel( url );
|
||||
|
||||
RandomAccessByteArrayOutputStream bos = new RandomAccessByteArrayOutputStream( 128 );
|
||||
|
||||
Request request = createRequest();
|
||||
|
||||
DefaultFuture future = new DefaultFuture( channel, request, 10 );
|
||||
|
||||
TMessage message = new TMessage( "echoString", TMessageType.REPLY, ThriftCodec.getSeqId() );
|
||||
|
||||
$__DemoStub.echoString_result methodResult = new $__DemoStub.echoString_result();
|
||||
|
||||
methodResult.success = "Hello, World!";
|
||||
|
||||
TTransport transport = new TIOStreamTransport( bos );
|
||||
|
||||
TBinaryProtocol protocol = new TBinaryProtocol( transport );
|
||||
|
||||
int messageLength, headerLength;
|
||||
// prepare
|
||||
protocol.writeI16( ThriftCodec.MAGIC );
|
||||
protocol.writeI32( Integer.MAX_VALUE );
|
||||
protocol.writeI16( Short.MAX_VALUE );
|
||||
protocol.writeByte( ThriftCodec.VERSION );
|
||||
protocol.writeString( Demo.class.getName() );
|
||||
protocol.writeI64( request.getId() );
|
||||
protocol.getTransport().flush();
|
||||
headerLength = bos.size();
|
||||
|
||||
protocol.writeMessageBegin( message );
|
||||
methodResult.write( protocol );
|
||||
protocol.writeMessageEnd();
|
||||
protocol.getTransport().flush();
|
||||
int oldIndex = messageLength = bos.size();
|
||||
|
||||
try {
|
||||
bos.setWriteIndex( ThriftCodec.MESSAGE_LENGTH_INDEX );
|
||||
protocol.writeI32( messageLength );
|
||||
bos.setWriteIndex( ThriftCodec.MESSAGE_HEADER_LENGTH_INDEX );
|
||||
protocol.writeI16( ( short ) ( 0xffff & headerLength ) );
|
||||
} finally {
|
||||
bos.setWriteIndex( oldIndex );
|
||||
}
|
||||
// prepare
|
||||
|
||||
byte[] buf = new byte[ 4 + bos.size()];
|
||||
System.arraycopy( bos.toByteArray(), 0, buf, 4, bos.size() );
|
||||
|
||||
ByteArrayInputStream bis = new ByteArrayInputStream( buf );
|
||||
|
||||
Object obj = codec.decode( ( Channel ) null, bis );
|
||||
|
||||
Assert.assertNotNull( obj );
|
||||
|
||||
Assert.assertEquals( true, obj instanceof Response );
|
||||
|
||||
Response response = ( Response ) obj;
|
||||
|
||||
Assert.assertEquals( request.getId(), response.getId() );
|
||||
|
||||
Assert.assertTrue( response.getResult() instanceof RpcResult );
|
||||
|
||||
RpcResult result = ( RpcResult ) response.getResult();
|
||||
|
||||
Assert.assertTrue( result.getResult() instanceof String );
|
||||
|
||||
Assert.assertEquals( methodResult.success, result.getResult() );
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDecodeExceptionResponse() throws Exception {
|
||||
|
||||
URL url = URL.valueOf( ThriftProtocol.NAME + "://127.0.0.1:40880/" + Demo.class.getName() );
|
||||
|
||||
Channel channel = new MockedChannel( url );
|
||||
|
||||
RandomAccessByteArrayOutputStream bos = new RandomAccessByteArrayOutputStream( 128 );
|
||||
|
||||
Request request = createRequest();
|
||||
|
||||
DefaultFuture future = new DefaultFuture( channel, request, 10 );
|
||||
|
||||
TMessage message = new TMessage( "echoString", TMessageType.EXCEPTION, ThriftCodec.getSeqId() );
|
||||
|
||||
TTransport transport = new TIOStreamTransport( bos );
|
||||
|
||||
TBinaryProtocol protocol = new TBinaryProtocol( transport );
|
||||
|
||||
TApplicationException exception = new TApplicationException();
|
||||
|
||||
int messageLength, headerLength;
|
||||
// prepare
|
||||
protocol.writeI16( ThriftCodec.MAGIC );
|
||||
protocol.writeI32( Integer.MAX_VALUE );
|
||||
protocol.writeI16( Short.MAX_VALUE );
|
||||
protocol.writeByte( ThriftCodec.VERSION );
|
||||
protocol.writeString( Demo.class.getName() );
|
||||
protocol.writeI64( request.getId() );
|
||||
protocol.getTransport().flush();
|
||||
headerLength = bos.size();
|
||||
|
||||
protocol.writeMessageBegin( message );
|
||||
exception.write( protocol );
|
||||
protocol.writeMessageEnd();
|
||||
protocol.getTransport().flush();
|
||||
int oldIndex = messageLength = bos.size();
|
||||
|
||||
try {
|
||||
bos.setWriteIndex( ThriftCodec.MESSAGE_LENGTH_INDEX );
|
||||
protocol.writeI32( messageLength );
|
||||
bos.setWriteIndex( ThriftCodec.MESSAGE_HEADER_LENGTH_INDEX );
|
||||
protocol.writeI16( ( short ) ( 0xffff & headerLength ) );
|
||||
} finally {
|
||||
bos.setWriteIndex( oldIndex );
|
||||
}
|
||||
// prepare
|
||||
|
||||
ByteArrayInputStream bis = new ByteArrayInputStream( encodeFrame( bos.toByteArray() ) );
|
||||
|
||||
Object obj = codec.decode( ( Channel ) null, bis );
|
||||
|
||||
Assert.assertNotNull( obj );
|
||||
|
||||
Assert.assertTrue( obj instanceof Response );
|
||||
|
||||
Response response = ( Response ) obj;
|
||||
|
||||
Assert.assertTrue( response.getResult() instanceof RpcResult );
|
||||
|
||||
RpcResult result = ( RpcResult ) response.getResult();
|
||||
|
||||
Assert.assertTrue( result.hasException() );
|
||||
|
||||
Assert.assertTrue( result.getException() instanceof RpcException );
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodeReplyResponse() throws Exception {
|
||||
|
||||
URL url = URL.valueOf( ThriftProtocol.NAME + "://127.0.0.1:40880/" + Demo.class.getName() );
|
||||
|
||||
Channel channel = new MockedChannel( url );
|
||||
|
||||
Request request = createRequest();
|
||||
|
||||
RpcResult rpcResult = new RpcResult();
|
||||
rpcResult.setResult( "Hello, World!" );
|
||||
|
||||
Response response = new Response();
|
||||
response.setResult( rpcResult );
|
||||
response.setId( request.getId() );
|
||||
RandomAccessByteArrayOutputStream bos = new RandomAccessByteArrayOutputStream( 1024 );
|
||||
|
||||
ThriftCodec.RequestData rd = ThriftCodec.RequestData.create(
|
||||
ThriftCodec.getSeqId(), Demo.class.getName(), "echoString" );
|
||||
ThriftCodec.cachedRequest.putIfAbsent( request.getId(), rd );
|
||||
codec.encode( channel, bos, response );
|
||||
|
||||
byte[] buf = new byte[bos.size() - 4];
|
||||
System.arraycopy( bos.toByteArray(), 4, buf, 0, bos.size() - 4 );
|
||||
|
||||
ByteArrayInputStream bis = new ByteArrayInputStream( buf );
|
||||
|
||||
if ( bis.markSupported() ) {
|
||||
bis.mark( 0 );
|
||||
}
|
||||
|
||||
TIOStreamTransport transport = new TIOStreamTransport( bis );
|
||||
TBinaryProtocol protocol = new TBinaryProtocol( transport );
|
||||
|
||||
Assert.assertEquals( ThriftCodec.MAGIC, protocol.readI16() );
|
||||
Assert.assertEquals( protocol.readI32() + 4, bos.toByteArray().length );
|
||||
int headerLength = protocol.readI16();
|
||||
|
||||
Assert.assertEquals( ThriftCodec.VERSION, protocol.readByte() );
|
||||
Assert.assertEquals( Demo.class.getName(), protocol.readString() );
|
||||
Assert.assertEquals( request.getId(), protocol.readI64() );
|
||||
|
||||
if ( bis.markSupported() ) {
|
||||
bis.reset();
|
||||
bis.skip( headerLength );
|
||||
}
|
||||
|
||||
TMessage message = protocol.readMessageBegin();
|
||||
Assert.assertEquals( "echoString", message.name );
|
||||
Assert.assertEquals( TMessageType.REPLY, message.type );
|
||||
Assert.assertEquals( ThriftCodec.getSeqId(), message.seqid );
|
||||
$__DemoStub.echoString_result result = new $__DemoStub.echoString_result();
|
||||
result.read( protocol );
|
||||
protocol.readMessageEnd();
|
||||
|
||||
Assert.assertEquals( rpcResult.getResult(), result.getSuccess() );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodeExceptionResponse() throws Exception {
|
||||
|
||||
URL url = URL.valueOf( ThriftProtocol.NAME + "://127.0.0.1:40880/" + Demo.class.getName() );
|
||||
|
||||
Channel channel = new MockedChannel( url );
|
||||
|
||||
Request request = createRequest();
|
||||
|
||||
RpcResult rpcResult = new RpcResult();
|
||||
String exceptionMessage = "failed";
|
||||
rpcResult.setException( new RuntimeException( exceptionMessage ) );
|
||||
|
||||
Response response = new Response();
|
||||
response.setResult( rpcResult );
|
||||
response.setId( request.getId() );
|
||||
RandomAccessByteArrayOutputStream bos = new RandomAccessByteArrayOutputStream( 1024 );
|
||||
|
||||
ThriftCodec.RequestData rd = ThriftCodec.RequestData.create(
|
||||
ThriftCodec.getSeqId(), Demo.class.getName(), "echoString" );
|
||||
ThriftCodec.cachedRequest.put( request.getId(), rd );
|
||||
codec.encode( channel, bos, response );
|
||||
|
||||
byte[] buf = new byte[bos.size() - 4];
|
||||
System.arraycopy( bos.toByteArray(), 4, buf, 0, bos.size() - 4 );
|
||||
ByteArrayInputStream bis = new ByteArrayInputStream( buf);
|
||||
|
||||
if ( bis.markSupported() ) {
|
||||
bis.mark( 0 );
|
||||
}
|
||||
|
||||
TIOStreamTransport transport = new TIOStreamTransport( bis );
|
||||
TBinaryProtocol protocol = new TBinaryProtocol( transport );
|
||||
|
||||
Assert.assertEquals( ThriftCodec.MAGIC, protocol.readI16() );
|
||||
Assert.assertEquals( protocol.readI32() + 4, bos.toByteArray().length );
|
||||
int headerLength = protocol.readI16();
|
||||
|
||||
Assert.assertEquals( ThriftCodec.VERSION, protocol.readByte() );
|
||||
Assert.assertEquals( Demo.class.getName(), protocol.readString() );
|
||||
Assert.assertEquals( request.getId(), protocol.readI64() );
|
||||
|
||||
if ( bis.markSupported() ) {
|
||||
bis.reset();
|
||||
bis.skip( headerLength );
|
||||
}
|
||||
|
||||
TMessage message = protocol.readMessageBegin();
|
||||
Assert.assertEquals( "echoString", message.name );
|
||||
Assert.assertEquals( TMessageType.EXCEPTION, message.type );
|
||||
Assert.assertEquals( ThriftCodec.getSeqId(), message.seqid );
|
||||
TApplicationException exception = TApplicationException.read( protocol );
|
||||
protocol.readMessageEnd();
|
||||
|
||||
Assert.assertEquals( exceptionMessage, exception.getMessage() );
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDecodeRequest() throws Exception {
|
||||
Request request = createRequest();
|
||||
// encode
|
||||
RandomAccessByteArrayOutputStream bos = new RandomAccessByteArrayOutputStream( 1024 );
|
||||
|
||||
TIOStreamTransport transport = new TIOStreamTransport( bos );
|
||||
|
||||
TBinaryProtocol protocol = new TBinaryProtocol( transport );
|
||||
|
||||
int messageLength, headerLength;
|
||||
|
||||
protocol.writeI16( ThriftCodec.MAGIC );
|
||||
protocol.writeI32( Integer.MAX_VALUE );
|
||||
protocol.writeI16( Short.MAX_VALUE );
|
||||
protocol.writeByte( ThriftCodec.VERSION );
|
||||
protocol.writeString(
|
||||
( ( RpcInvocation ) request.getData() )
|
||||
.getAttachment( Constants.INTERFACE_KEY) );
|
||||
protocol.writeI64( request.getId() );
|
||||
protocol.getTransport().flush();
|
||||
headerLength = bos.size();
|
||||
|
||||
$__DemoStub.echoString_args args = new $__DemoStub.echoString_args( );
|
||||
args.setArg( "Hell, World!" );
|
||||
|
||||
TMessage message = new TMessage( "echoString", TMessageType.CALL, ThriftCodec.getSeqId() );
|
||||
|
||||
protocol.writeMessageBegin( message );
|
||||
args.write( protocol );
|
||||
protocol.writeMessageEnd();
|
||||
protocol.getTransport().flush();
|
||||
int oldIndex = messageLength = bos.size();
|
||||
|
||||
try{
|
||||
bos.setWriteIndex( ThriftCodec.MESSAGE_HEADER_LENGTH_INDEX );
|
||||
protocol.writeI16( ( short ) ( 0xffff & headerLength ) );
|
||||
bos.setWriteIndex( ThriftCodec.MESSAGE_LENGTH_INDEX );
|
||||
protocol.writeI32( messageLength );
|
||||
} finally {
|
||||
bos.setWriteIndex( oldIndex );
|
||||
}
|
||||
|
||||
Object obj = codec.decode( ( Channel ) null, new ByteArrayInputStream(
|
||||
encodeFrame( bos.toByteArray() ) ) );
|
||||
|
||||
Assert.assertTrue( obj instanceof Request );
|
||||
|
||||
obj = ( ( Request ) obj ).getData();
|
||||
|
||||
Assert.assertTrue( obj instanceof RpcInvocation );
|
||||
|
||||
RpcInvocation invocation = ( RpcInvocation ) obj;
|
||||
|
||||
Assert.assertEquals( "echoString", invocation.getMethodName() );
|
||||
Assert.assertArrayEquals( new Class[] {String .class}, invocation.getParameterTypes() );
|
||||
Assert.assertArrayEquals( new Object[] { args.getArg() }, invocation.getArguments() );
|
||||
|
||||
}
|
||||
|
||||
private Request createRequest() {
|
||||
|
||||
RpcInvocation invocation = new RpcInvocation();
|
||||
|
||||
invocation.setMethodName( "echoString" );
|
||||
|
||||
invocation.setArguments( new Object[]{ "Hello, World!" } );
|
||||
|
||||
invocation.setParameterTypes( new Class<?>[]{ String.class } );
|
||||
|
||||
invocation.setAttachment( Constants.INTERFACE_KEY, Demo.class.getName() );
|
||||
|
||||
Request request = new Request( 1L );
|
||||
|
||||
request.setData( invocation );
|
||||
|
||||
return request;
|
||||
|
||||
}
|
||||
|
||||
static byte[] encodeFrame( byte[] content ) {
|
||||
byte[] result = new byte[4+content.length];
|
||||
TFramedTransport.encodeFrameSize( content.length, result );
|
||||
System.arraycopy( content, 0, result, 4, content.length );
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
/**
|
||||
* File Created at 2011-12-31
|
||||
* $Id$
|
||||
*
|
||||
* Copyright 2008 Alibaba.com Croporation Limited.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is the confidential and proprietary information of
|
||||
* Alibaba Company. ("Confidential Information"). You shall not
|
||||
* disclose such Confidential Information and shall use it only in
|
||||
* accordance with the terms of the license agreement you entered into
|
||||
* with Alibaba.com.
|
||||
*/
|
||||
package com.alibaba.dubbo.rpc.protocol.thrift;
|
||||
|
||||
import com.alibaba.dubbo.rpc.gen.thrift.Demo;
|
||||
import org.apache.thrift.TException;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:gang.lvg@alibaba-inc.com">kimi</a>
|
||||
*/
|
||||
public class ThriftDemoImpl extends DemoImpl implements Demo.Iface {}
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
/**
|
||||
* File Created at 2011-12-08
|
||||
* $Id$
|
||||
*
|
||||
* Copyright 2008 Alibaba.com Croporation Limited.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is the confidential and proprietary information of
|
||||
* Alibaba Company. ("Confidential Information"). You shall not
|
||||
* disclose such Confidential Information and shall use it only in
|
||||
* accordance with the terms of the license agreement you entered into
|
||||
* with Alibaba.com.
|
||||
*/
|
||||
package com.alibaba.dubbo.rpc.protocol.thrift;
|
||||
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.rpc.Invoker;
|
||||
import com.alibaba.dubbo.rpc.Result;
|
||||
import com.alibaba.dubbo.rpc.RpcInvocation;
|
||||
import com.alibaba.dubbo.rpc.gen.dubbo.Demo;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:gang.lvg@alibaba-inc.com">kimi</a>
|
||||
*/
|
||||
public class ThriftProtocolTest extends AbstractTest {
|
||||
|
||||
public static final int DEFAULT_PORT = 30660;
|
||||
|
||||
private ThriftProtocol protocol;
|
||||
|
||||
private Invoker<Demo> invoker;
|
||||
|
||||
private URL url;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
|
||||
init();
|
||||
|
||||
protocol = new ThriftProtocol();
|
||||
|
||||
url = URL.valueOf( ThriftProtocol.NAME + "://127.0.0.1:" + PORT + "/" + Demo.class.getName() );
|
||||
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
|
||||
destroy();
|
||||
|
||||
if ( protocol != null ) {
|
||||
protocol.destroy();
|
||||
protocol = null;
|
||||
}
|
||||
|
||||
if ( invoker != null ) {
|
||||
invoker.destroy();
|
||||
invoker = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRefer() throws Exception {
|
||||
// FIXME
|
||||
/*invoker = protocol.refer( Demo.class, url );
|
||||
|
||||
Assert.assertNotNull( invoker );
|
||||
|
||||
RpcInvocation invocation = new RpcInvocation();
|
||||
|
||||
invocation.setMethodName( "echoString" );
|
||||
|
||||
invocation.setParameterTypes( new Class<?>[]{ String.class } );
|
||||
|
||||
String arg = "Hello, World!";
|
||||
|
||||
invocation.setArguments( new Object[] { arg } );
|
||||
|
||||
Result result = invoker.invoke( invocation );
|
||||
|
||||
Assert.assertEquals( arg, result.getResult() );*/
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
/**
|
||||
* File Created at 2011-12-05
|
||||
* $Id$
|
||||
*
|
||||
* Copyright 2008 Alibaba.com Croporation Limited.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is the confidential and proprietary information of
|
||||
* Alibaba Company. ("Confidential Information"). You shall not
|
||||
* disclose such Confidential Information and shall use it only in
|
||||
* accordance with the terms of the license agreement you entered into
|
||||
* with Alibaba.com.
|
||||
*/
|
||||
package com.alibaba.dubbo.rpc.protocol.thrift;
|
||||
|
||||
import com.alibaba.dubbo.common.extension.ExtensionLoader;
|
||||
import com.alibaba.dubbo.rpc.gen.dubbo.$__DemoStub;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:gang.lvg@alibaba-inc.com">gang.lvg</a>
|
||||
*/
|
||||
public class ThriftUtilsTest {
|
||||
|
||||
@Test
|
||||
public void testGenerateMethodArgsClassName() {
|
||||
|
||||
Assert.assertEquals(
|
||||
$__DemoStub.echoString_args.class.getName(),
|
||||
ThriftUtils.generateMethodArgsClassName(
|
||||
com.alibaba.dubbo.rpc.gen.dubbo.Demo.class.getName(),
|
||||
"echoString" ) );
|
||||
|
||||
Assert.assertEquals(
|
||||
$__DemoStub.echoString_args.class.getName(),
|
||||
ExtensionLoader.getExtensionLoader(ClassNameGenerator.class)
|
||||
.getExtension( DubboClassNameGenerator.NAME ).generateArgsClassName(
|
||||
com.alibaba.dubbo.rpc.gen.dubbo.Demo.class.getName(), "echoString" ) );
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenerateMethodResultClassName() {
|
||||
|
||||
Assert.assertEquals( $__DemoStub.echoString_result.class.getName(),
|
||||
ThriftUtils.generateMethodResultClassName(
|
||||
com.alibaba.dubbo.rpc.gen.dubbo.Demo.class.getName(),
|
||||
"echoString" ));
|
||||
|
||||
Assert.assertEquals( $__DemoStub.echoString_result.class.getName(),
|
||||
ExtensionLoader.getExtensionLoader( ClassNameGenerator.class )
|
||||
.getExtension( DubboClassNameGenerator.NAME ).generateResultClassName (
|
||||
com.alibaba.dubbo.rpc.gen.dubbo.Demo.class.getName(), "echoString" ));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenerateMethodArgsClassNameThrift() {
|
||||
Assert.assertEquals( com.alibaba.dubbo.rpc.gen.thrift.Demo.echoString_args.class.getName(),
|
||||
ThriftUtils.generateMethodArgsClassNameThrift(
|
||||
com.alibaba.dubbo.rpc.gen.thrift.Demo.Iface.class.getName(),
|
||||
"echoString" ) );
|
||||
|
||||
Assert.assertEquals( com.alibaba.dubbo.rpc.gen.thrift.Demo.echoString_args.class.getName(),
|
||||
ExtensionLoader.getExtensionLoader( ClassNameGenerator.class )
|
||||
.getExtension( ThriftClassNameGenerator.NAME ).generateArgsClassName(
|
||||
com.alibaba.dubbo.rpc.gen.thrift.Demo.Iface.class.getName(),
|
||||
"echoString" ) );
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenerateMethodResultClassNameThrift() {
|
||||
Assert.assertEquals( com.alibaba.dubbo.rpc.gen.thrift.Demo.echoString_result.class.getName(),
|
||||
ThriftUtils.generateMethodResultClassNameThrift(
|
||||
com.alibaba.dubbo.rpc.gen.thrift.Demo.Iface.class.getName(),
|
||||
"echoString" ) );
|
||||
|
||||
Assert.assertEquals( com.alibaba.dubbo.rpc.gen.thrift.Demo.echoString_result.class.getName(),
|
||||
ExtensionLoader.getExtensionLoader( ClassNameGenerator.class )
|
||||
.getExtension( ThriftClassNameGenerator.NAME ).generateResultClassName(
|
||||
com.alibaba.dubbo.rpc.gen.thrift.Demo.Iface.class.getName(),
|
||||
"echoString" ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
package com.alibaba.dubbo.rpc.protocol.thrift.examples;
|
||||
|
||||
import com.alibaba.dubbo.rpc.gen.dubbo.Demo;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:gang.lvg@alibaba-inc.com">kimi</a>
|
||||
*/
|
||||
public class DubboDemoConsumer {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
ClassPathXmlApplicationContext context =
|
||||
new ClassPathXmlApplicationContext("dubbo-demo-consumer.xml");
|
||||
context.start();
|
||||
Demo demo = (Demo) context.getBean("demoService");
|
||||
System.out.println(demo.echoI32(32));
|
||||
for (int i = 0; i < 10; i++) {
|
||||
System.out.println(demo.echoI32(i + 1));
|
||||
}
|
||||
context.close();
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue