use of org.apache.dubbo.common.beanutil.JavaBeanDescriptor in project dubbo by alibaba.
the class HessianProtocolTest method testGenericInvokeWithBean.
@Test
public void testGenericInvokeWithBean() {
HessianServiceImpl server = new HessianServiceImpl();
Assertions.assertFalse(server.isCalled());
ProxyFactory proxyFactory = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
int port = NetUtils.getAvailablePort();
URL url = URL.valueOf("hessian://127.0.0.1:" + port + "/" + HessianService.class.getName() + "?version=1.0.0&generic=bean");
Exporter<HessianService> exporter = protocol.export(proxyFactory.getInvoker(server, HessianService.class, url));
Invoker<GenericService> invoker = protocol.refer(GenericService.class, url);
GenericService client = proxyFactory.getProxy(invoker);
JavaBeanDescriptor javaBeanDescriptor = JavaBeanSerializeUtil.serialize("haha");
Object result = client.$invoke("sayHello", new String[] { "java.lang.String" }, new Object[] { javaBeanDescriptor });
Assertions.assertTrue(server.isCalled());
Assertions.assertEquals("Hello, haha", JavaBeanSerializeUtil.deserialize((JavaBeanDescriptor) result));
invoker.destroy();
exporter.unexport();
}
use of org.apache.dubbo.common.beanutil.JavaBeanDescriptor in project dubbo by alibaba.
the class GenericServiceTest method testGenericInvokeWithBeanSerialization.
@Test
public void testGenericInvokeWithBeanSerialization() throws Exception {
ServiceConfig<DemoService> service = new ServiceConfig<DemoService>();
service.setInterface(DemoService.class);
DemoServiceImpl impl = new DemoServiceImpl();
service.setRef(impl);
ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>();
reference.setInterface(DemoService.class);
reference.setUrl("dubbo://127.0.0.1:29581?scope=remote&timeout=3000");
reference.setGeneric(GENERIC_SERIALIZATION_BEAN);
DubboBootstrap bootstrap = DubboBootstrap.getInstance().application(new ApplicationConfig("generic-test")).registry(new RegistryConfig("N/A")).protocol(new ProtocolConfig("dubbo", 29581)).service(service).reference(reference);
bootstrap.start();
try {
GenericService genericService = bootstrap.getCache().get(reference);
User user = new User();
user.setName("zhangsan");
List<User> users = new ArrayList<User>();
users.add(user);
Object result = genericService.$invoke("getUsers", new String[] { ReflectUtils.getName(List.class) }, new Object[] { JavaBeanSerializeUtil.serialize(users, JavaBeanAccessor.METHOD) });
Assertions.assertTrue(result instanceof JavaBeanDescriptor);
JavaBeanDescriptor descriptor = (JavaBeanDescriptor) result;
Assertions.assertTrue(descriptor.isCollectionType());
Assertions.assertEquals(1, descriptor.propertySize());
descriptor = (JavaBeanDescriptor) descriptor.getProperty(0);
Assertions.assertTrue(descriptor.isBeanType());
Assertions.assertEquals(user.getName(), ((JavaBeanDescriptor) descriptor.getProperty("name")).getPrimitiveProperty());
} finally {
bootstrap.stop();
}
}
use of org.apache.dubbo.common.beanutil.JavaBeanDescriptor in project dubbo by alibaba.
the class GenericFilter method invoke.
@Override
public Result invoke(Invoker<?> invoker, Invocation inv) throws RpcException {
if ((inv.getMethodName().equals($INVOKE) || inv.getMethodName().equals($INVOKE_ASYNC)) && inv.getArguments() != null && inv.getArguments().length == 3 && !GenericService.class.isAssignableFrom(invoker.getInterface())) {
String name = ((String) inv.getArguments()[0]).trim();
String[] types = (String[]) inv.getArguments()[1];
Object[] args = (Object[]) inv.getArguments()[2];
try {
Method method = ReflectUtils.findMethodByMethodSignature(invoker.getInterface(), name, types);
Class<?>[] params = method.getParameterTypes();
if (args == null) {
args = new Object[params.length];
}
if (types == null) {
types = new String[params.length];
}
if (args.length != types.length) {
throw new RpcException("GenericFilter#invoke args.length != types.length, please check your " + "params");
}
String generic = inv.getAttachment(GENERIC_KEY);
if (StringUtils.isBlank(generic)) {
generic = RpcContext.getContext().getAttachment(GENERIC_KEY);
}
if (StringUtils.isEmpty(generic) || ProtocolUtils.isDefaultGenericSerialization(generic) || ProtocolUtils.isGenericReturnRawResult(generic)) {
try {
args = PojoUtils.realize(args, params, method.getGenericParameterTypes());
} catch (IllegalArgumentException e) {
throw new RpcException(e);
}
} else if (ProtocolUtils.isGsonGenericSerialization(generic)) {
args = getGsonGenericArgs(args, method.getGenericParameterTypes());
} else if (ProtocolUtils.isJavaGenericSerialization(generic)) {
Configuration configuration = ApplicationModel.getEnvironment().getConfiguration();
if (!configuration.getBoolean(CommonConstants.ENABLE_NATIVE_JAVA_GENERIC_SERIALIZE, false)) {
String notice = "Trigger the safety barrier! " + "Native Java Serializer is not allowed by default." + "This means currently maybe being attacking by others. " + "If you are sure this is a mistake, " + "please set `" + CommonConstants.ENABLE_NATIVE_JAVA_GENERIC_SERIALIZE + "` enable in configuration! " + "Before doing so, please make sure you have configure JEP290 to prevent serialization attack.";
logger.error(notice);
throw new RpcException(new IllegalStateException(notice));
}
for (int i = 0; i < args.length; i++) {
if (byte[].class == args[i].getClass()) {
try (UnsafeByteArrayInputStream is = new UnsafeByteArrayInputStream((byte[]) args[i])) {
args[i] = ExtensionLoader.getExtensionLoader(Serialization.class).getExtension(GENERIC_SERIALIZATION_NATIVE_JAVA).deserialize(null, is).readObject();
} catch (Exception e) {
throw new RpcException("Deserialize argument [" + (i + 1) + "] failed.", e);
}
} else {
throw new RpcException("Generic serialization [" + GENERIC_SERIALIZATION_NATIVE_JAVA + "] only support message type " + byte[].class + " and your message type is " + args[i].getClass());
}
}
} else if (ProtocolUtils.isBeanGenericSerialization(generic)) {
for (int i = 0; i < args.length; i++) {
if (args[i] instanceof JavaBeanDescriptor) {
args[i] = JavaBeanSerializeUtil.deserialize((JavaBeanDescriptor) args[i]);
} else {
throw new RpcException("Generic serialization [" + GENERIC_SERIALIZATION_BEAN + "] only support message type " + JavaBeanDescriptor.class.getName() + " and your message type is " + args[i].getClass().getName());
}
}
} else if (ProtocolUtils.isProtobufGenericSerialization(generic)) {
// as proto3 only accept one protobuf parameter
if (args.length == 1 && args[0] instanceof String) {
try (UnsafeByteArrayInputStream is = new UnsafeByteArrayInputStream(((String) args[0]).getBytes())) {
args[0] = ExtensionLoader.getExtensionLoader(Serialization.class).getExtension(GENERIC_SERIALIZATION_PROTOBUF).deserialize(null, is).readObject(method.getParameterTypes()[0]);
} catch (Exception e) {
throw new RpcException("Deserialize argument failed.", e);
}
} else {
throw new RpcException("Generic serialization [" + GENERIC_SERIALIZATION_PROTOBUF + "] only support one " + String.class.getName() + " argument and your message size is " + args.length + " and type is" + args[0].getClass().getName());
}
}
RpcInvocation rpcInvocation = new RpcInvocation(method, invoker.getInterface().getName(), invoker.getUrl().getProtocolServiceKey(), args, inv.getObjectAttachments(), inv.getAttributes());
rpcInvocation.setInvoker(inv.getInvoker());
rpcInvocation.setTargetServiceUniqueName(inv.getTargetServiceUniqueName());
return invoker.invoke(rpcInvocation);
} catch (NoSuchMethodException | ClassNotFoundException e) {
throw new RpcException(e.getMessage(), e);
}
}
return invoker.invoke(inv);
}
use of org.apache.dubbo.common.beanutil.JavaBeanDescriptor in project dubbo by alibaba.
the class GenericImplFilter method onResponse.
@Override
public void onResponse(Result appResponse, Invoker<?> invoker, Invocation invocation) {
String generic = invoker.getUrl().getParameter(GENERIC_KEY);
String methodName = invocation.getMethodName();
Class<?>[] parameterTypes = invocation.getParameterTypes();
Object genericImplMarker = invocation.get(GENERIC_IMPL_MARKER);
if (genericImplMarker != null && (boolean) invocation.get(GENERIC_IMPL_MARKER)) {
if (!appResponse.hasException()) {
Object value = appResponse.getValue();
try {
Class<?> invokerInterface = invoker.getInterface();
if (!$INVOKE.equals(methodName) && !$INVOKE_ASYNC.equals(methodName) && invokerInterface.isAssignableFrom(GenericService.class)) {
try {
// find the real interface from url
String realInterface = invoker.getUrl().getParameter(Constants.INTERFACE);
invokerInterface = ReflectUtils.forName(realInterface);
} catch (Throwable e) {
// ignore
}
}
Method method = invokerInterface.getMethod(methodName, parameterTypes);
if (ProtocolUtils.isBeanGenericSerialization(generic)) {
if (value == null) {
appResponse.setValue(value);
} else if (value instanceof JavaBeanDescriptor) {
appResponse.setValue(JavaBeanSerializeUtil.deserialize((JavaBeanDescriptor) value));
} else {
throw new RpcException("The type of result value is " + value.getClass().getName() + " other than " + JavaBeanDescriptor.class.getName() + ", and the result is " + value);
}
} else {
Type[] types = ReflectUtils.getReturnTypes(method);
appResponse.setValue(PojoUtils.realize(value, (Class<?>) types[0], types[1]));
}
} catch (NoSuchMethodException e) {
throw new RpcException(e.getMessage(), e);
}
} else if (appResponse.getException() instanceof com.alibaba.dubbo.rpc.service.GenericException) {
com.alibaba.dubbo.rpc.service.GenericException exception = (com.alibaba.dubbo.rpc.service.GenericException) appResponse.getException();
try {
String className = exception.getExceptionClass();
Class<?> clazz = ReflectUtils.forName(className);
Throwable targetException = null;
Throwable lastException = null;
try {
targetException = (Throwable) clazz.newInstance();
} catch (Throwable e) {
lastException = e;
for (Constructor<?> constructor : clazz.getConstructors()) {
try {
targetException = (Throwable) constructor.newInstance(new Object[constructor.getParameterTypes().length]);
break;
} catch (Throwable e1) {
lastException = e1;
}
}
}
if (targetException != null) {
try {
Field field = Throwable.class.getDeclaredField("detailMessage");
ReflectUtils.makeAccessible(field);
field.set(targetException, exception.getExceptionMessage());
} catch (Throwable e) {
logger.warn(e.getMessage(), e);
}
appResponse.setException(targetException);
} else if (lastException != null) {
throw lastException;
}
} catch (Throwable e) {
throw new RpcException("Can not deserialize exception " + exception.getExceptionClass() + ", message: " + exception.getExceptionMessage(), e);
}
}
}
}
use of org.apache.dubbo.common.beanutil.JavaBeanDescriptor in project dubbo by alibaba.
the class GenericImplFilter method invoke.
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
String generic = invoker.getUrl().getParameter(GENERIC_KEY);
// calling a generic impl service
if (isCallingGenericImpl(generic, invocation)) {
RpcInvocation invocation2 = new RpcInvocation(invocation);
/**
* Mark this invocation as a generic impl call, this value will be removed automatically before passing on the wire.
* See {@link RpcUtils#sieveUnnecessaryAttachments(Invocation)}
*/
invocation2.put(GENERIC_IMPL_MARKER, true);
String methodName = invocation2.getMethodName();
Class<?>[] parameterTypes = invocation2.getParameterTypes();
Object[] arguments = invocation2.getArguments();
String[] types = new String[parameterTypes.length];
for (int i = 0; i < parameterTypes.length; i++) {
types[i] = ReflectUtils.getName(parameterTypes[i]);
}
Object[] args;
if (ProtocolUtils.isBeanGenericSerialization(generic)) {
args = new Object[arguments.length];
for (int i = 0; i < arguments.length; i++) {
args[i] = JavaBeanSerializeUtil.serialize(arguments[i], JavaBeanAccessor.METHOD);
}
} else {
args = PojoUtils.generalize(arguments);
}
if (RpcUtils.isReturnTypeFuture(invocation)) {
invocation2.setMethodName($INVOKE_ASYNC);
} else {
invocation2.setMethodName($INVOKE);
}
invocation2.setParameterTypes(GENERIC_PARAMETER_TYPES);
invocation2.setParameterTypesDesc(GENERIC_PARAMETER_DESC);
invocation2.setArguments(new Object[] { methodName, types, args });
return invoker.invoke(invocation2);
} else // making a generic call to a normal service
if (isMakingGenericCall(generic, invocation)) {
Object[] args = (Object[]) invocation.getArguments()[2];
if (ProtocolUtils.isJavaGenericSerialization(generic)) {
for (Object arg : args) {
if (byte[].class != arg.getClass()) {
error(generic, byte[].class.getName(), arg.getClass().getName());
}
}
} else if (ProtocolUtils.isBeanGenericSerialization(generic)) {
for (Object arg : args) {
if (!(arg instanceof JavaBeanDescriptor)) {
error(generic, JavaBeanDescriptor.class.getName(), arg.getClass().getName());
}
}
}
invocation.setAttachment(GENERIC_KEY, invoker.getUrl().getParameter(GENERIC_KEY));
}
return invoker.invoke(invocation);
}
Aggregations