Search in sources :

Example 1 with This

use of net.bytebuddy.implementation.bind.annotation.This in project alibaba-rsocket-broker by alibaba.

the class RSocketRequesterRpcProxy method invoke.

@Override
@RuntimeType
public Object invoke(@This Object proxy, @Origin Method method, @AllArguments Object[] allArguments) throws Throwable {
    // interface default method validation for JDK Proxy only, not necessary for ByteBuddy
    if (jdkProxy && method.isDefault()) {
        return DefaultMethodHandler.getMethodHandle(method, serviceInterface).bindTo(proxy).invokeWithArguments(allArguments);
    } else if (method.getDeclaringClass().equals(Object.class)) {
        // delegate hashCode, equals, or toString methods to this
        return method.invoke(this);
    }
    MutableContext mutableContext = new MutableContext();
    if (!methodMetadataMap.containsKey(method)) {
        methodMetadataMap.put(method, new ReactiveMethodMetadata(group, service, version, method, encodingType, this.acceptEncodingTypes, endpoint, sticky, sourceUri));
    }
    ReactiveMethodMetadata methodMetadata = methodMetadataMap.get(method);
    mutableContext.put(ReactiveMethodMetadata.class, methodMetadata);
    Object[] args = allArguments;
    if (methodMetadata.isKotlinSuspend()) {
        args = Arrays.copyOfRange(args, 0, args.length - 1);
        mutableContext.put(Continuation.class, allArguments[allArguments.length - 1]);
    }
    // ----- return type deal------
    if (methodMetadata.getRsocketFrameType() == FrameType.REQUEST_CHANNEL) {
        metrics(methodMetadata);
        Payload routePayload;
        Flux<Object> source;
        // 1 param or 2 params
        if (args.length == 1) {
            routePayload = ByteBufPayload.create(Unpooled.EMPTY_BUFFER, methodMetadata.getCompositeMetadataByteBuf().retainedDuplicate());
            source = methodMetadata.getReactiveAdapter().toFlux(args[0]);
        } else {
            ByteBuf bodyBuffer = encodingFacade.encodingResult(args[0], methodMetadata.getParamEncoding());
            routePayload = ByteBufPayload.create(bodyBuffer, methodMetadata.getCompositeMetadataByteBuf().retainedDuplicate());
            source = methodMetadata.getReactiveAdapter().toFlux(args[1]);
        }
        Flux<Payload> payloadFlux = source.startWith(routePayload).map(obj -> {
            if (obj instanceof Payload)
                return (Payload) obj;
            return ByteBufPayload.create(encodingFacade.encodingResult(obj, encodingType), methodMetadata.getCompositeMetadataByteBuf().retainedDuplicate());
        });
        Flux<Payload> payloads = upstreamManager.getRSocket(this.serviceId).requestChannel(payloadFlux);
        Flux<Object> fluxReturn = payloads.concatMap(payload -> {
            try {
                RSocketCompositeMetadata compositeMetadata = RSocketCompositeMetadata.from(payload.metadata());
                return Mono.justOrEmpty(encodingFacade.decodeResult(extractPayloadDataMimeType(compositeMetadata, encodingType), payload.data(), methodMetadata.getInferredClassForReturn()));
            } catch (Exception e) {
                return Flux.error(e);
            }
        }).subscriberContext(mutableContext::putAll);
        if (methodMetadata.isMonoChannel()) {
            return fluxReturn.last();
        } else {
            return methodMetadata.getReactiveAdapter().fromPublisher(fluxReturn, method.getReturnType());
        }
    } else {
        // body content
        ByteBuf bodyBuffer = encodingFacade.encodingParams(args, methodMetadata.getParamEncoding());
        Class<?> returnType = method.getReturnType();
        if (methodMetadata.getRsocketFrameType() == FrameType.REQUEST_RESPONSE) {
            metrics(methodMetadata);
            Mono<Payload> payloadMono = remoteRequestResponse(methodMetadata, methodMetadata.getCompositeMetadataByteBuf().retainedDuplicate(), bodyBuffer);
            Mono<Object> result = payloadMono.handle((payload, sink) -> {
                try {
                    RSocketCompositeMetadata compositeMetadata = RSocketCompositeMetadata.from(payload.metadata());
                    Object obj = encodingFacade.decodeResult(extractPayloadDataMimeType(compositeMetadata, encodingType), payload.data(), methodMetadata.getInferredClassForReturn());
                    if (obj != null) {
                        sink.next(obj);
                    }
                    sink.complete();
                } catch (Exception e) {
                    sink.error(e);
                }
            });
            return methodMetadata.getReactiveAdapter().fromPublisher(result, returnType, mutableContext);
        } else if (methodMetadata.getRsocketFrameType() == FrameType.REQUEST_FNF) {
            metrics(methodMetadata);
            return remoteFireAndForget(methodMetadata, methodMetadata.getCompositeMetadataByteBuf().retainedDuplicate(), bodyBuffer);
        } else if (methodMetadata.getRsocketFrameType() == FrameType.REQUEST_STREAM) {
            metrics(methodMetadata);
            Flux<Payload> flux = remoteRequestStream(methodMetadata, methodMetadata.getCompositeMetadataByteBuf().retainedDuplicate(), bodyBuffer);
            Flux<Object> result = flux.concatMap((payload) -> {
                try {
                    RSocketCompositeMetadata compositeMetadata = RSocketCompositeMetadata.from(payload.metadata());
                    return Mono.justOrEmpty(encodingFacade.decodeResult(extractPayloadDataMimeType(compositeMetadata, encodingType), payload.data(), methodMetadata.getInferredClassForReturn()));
                } catch (Exception e) {
                    return Mono.error(e);
                }
            });
            return methodMetadata.getReactiveAdapter().fromPublisher(result, returnType, mutableContext);
        } else {
            ReferenceCountUtil.safeRelease(bodyBuffer);
            return Mono.error(new Exception(RsocketErrorCode.message("RST-200405", methodMetadata.getRsocketFrameType())));
        }
    }
}
Also used : This(net.bytebuddy.implementation.bind.annotation.This) Continuation(kotlin.coroutines.Continuation) Arrays(java.util.Arrays) Origin(net.bytebuddy.implementation.bind.annotation.Origin) LoggerFactory(org.slf4j.LoggerFactory) TimeoutException(java.util.concurrent.TimeoutException) Metrics(io.micrometer.core.instrument.Metrics) Unpooled(io.netty.buffer.Unpooled) RuntimeType(net.bytebuddy.implementation.bind.annotation.RuntimeType) MessageMimeTypeMetadata(com.alibaba.rsocket.metadata.MessageMimeTypeMetadata) ByteBuf(io.netty.buffer.ByteBuf) AllArguments(net.bytebuddy.implementation.bind.annotation.AllArguments) MutableContext(com.alibaba.rsocket.MutableContext) Duration(java.time.Duration) Map(java.util.Map) URI(java.net.URI) Method(java.lang.reflect.Method) RSocketEncodingFacade(com.alibaba.rsocket.encoding.RSocketEncodingFacade) ByteBufPayload(io.rsocket.util.ByteBufPayload) RSocketMimeType(com.alibaba.rsocket.metadata.RSocketMimeType) FrameType(io.rsocket.frame.FrameType) Logger(org.slf4j.Logger) RsocketErrorCode(com.alibaba.rsocket.observability.RsocketErrorCode) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Mono(reactor.core.publisher.Mono) RSocketCompositeMetadata(com.alibaba.rsocket.metadata.RSocketCompositeMetadata) Nullable(org.jetbrains.annotations.Nullable) Flux(reactor.core.publisher.Flux) Payload(io.rsocket.Payload) ReferenceCountUtil(io.netty.util.ReferenceCountUtil) UpstreamManager(com.alibaba.rsocket.upstream.UpstreamManager) InvocationHandler(java.lang.reflect.InvocationHandler) NotNull(org.jetbrains.annotations.NotNull) ServiceLocator(com.alibaba.rsocket.ServiceLocator) RSocketCompositeMetadata(com.alibaba.rsocket.metadata.RSocketCompositeMetadata) MutableContext(com.alibaba.rsocket.MutableContext) ByteBuf(io.netty.buffer.ByteBuf) TimeoutException(java.util.concurrent.TimeoutException) ByteBufPayload(io.rsocket.util.ByteBufPayload) Payload(io.rsocket.Payload) RuntimeType(net.bytebuddy.implementation.bind.annotation.RuntimeType)

Example 2 with This

use of net.bytebuddy.implementation.bind.annotation.This in project mule by mulesoft.

the class ObjectFactoryClassRepository method getObjectFactoryDynamicClass.

@Deprecated
public Class<ObjectFactory> getObjectFactoryDynamicClass(final ComponentBuildingDefinition componentBuildingDefinition, final Class objectFactoryType, final Class createdObjectType, final Supplier<Boolean> isLazyInitFunction) {
    /*
     * We need this to allow spring create the object using a FactoryBean but using the object factory setters and getters so we
     * create as FactoryBean a dynamic class that will have the same attributes and methods as the ObjectFactory that the user
     * defined. This way our API does not expose spring specific classes.
     */
    Enhancer enhancer = new Enhancer();
    // Use SmartFactoryBean since it's the only way to force spring to pre-instantiate FactoryBean for singletons
    enhancer.setInterfaces(new Class[] { SmartFactoryBean.class });
    enhancer.setSuperclass(objectFactoryType);
    enhancer.setCallbackType(MethodInterceptor.class);
    if (SmartFactoryBean.class.getClassLoader() != objectFactoryType.getClassLoader()) {
        // CGLIB needs access to both the spring interface and the extended factory class.
        // If the factory class is defined in a plugin, its classloader has to be passed.
        enhancer.setClassLoader(COMPOSITE_CL_CACHE.get(objectFactoryType.getClassLoader()));
    }
    // The use of the CGLIB cache is turned off when a post creation function is passed as argument in order to
    // enrich the created proxy with properties. This is only to enable injecting properties in components
    // from the compatibility module.
    // Setting this to false will generate an excessive amount of different proxy classes loaded by the container CL
    // that will end up in Metaspace OOM.
    enhancer.setUseCache(true);
    // MG says: this is super important. Generating this variable here prevents the lambda below from
    // keeping a reference to the componentBuildingDefinition, which in turn references a classloader and has
    // caused leaks in the past
    final boolean prototype = componentBuildingDefinition.isPrototype();
    Class<ObjectFactory> factoryBeanClass = enhancer.createClass();
    registerStaticCallbacks(factoryBeanClass, new Callback[] { (MethodInterceptor) (obj, method, args, proxy) -> {
        final boolean eager = !isLazyInitFunction.get();
        if (method.getName().equals(IS_SINGLETON)) {
            return !prototype;
        }
        if (method.getName().equals("getObjectType") && !ObjectTypeProvider.class.isAssignableFrom(obj.getClass())) {
            return createdObjectType;
        }
        if (method.getName().equals("getObject")) {
            return proxy.invokeSuper(obj, args);
        }
        if (method.getName().equals(IS_PROTOTYPE)) {
            return prototype;
        }
        if (method.getName().equals(IS_EAGER_INIT)) {
            return eager;
        }
        return proxy.invokeSuper(obj, args);
    } });
    return factoryBeanClass;
}
Also used : This(net.bytebuddy.implementation.bind.annotation.This) Origin(net.bytebuddy.implementation.bind.annotation.Origin) MethodDelegation.toField(net.bytebuddy.implementation.MethodDelegation.toField) ByteBuddy(net.bytebuddy.ByteBuddy) MethodDelegation.to(net.bytebuddy.implementation.MethodDelegation.to) Caffeine.newBuilder(com.github.benmanes.caffeine.cache.Caffeine.newBuilder) MethodCall.invokeSuper(net.bytebuddy.implementation.MethodCall.invokeSuper) IMITATE_SUPER_CLASS(net.bytebuddy.dynamic.scaffold.subclass.ConstructorStrategy.Default.IMITATE_SUPER_CLASS) Supplier(java.util.function.Supplier) PRIVATE(net.bytebuddy.description.modifier.Visibility.PRIVATE) RuntimeType(net.bytebuddy.implementation.bind.annotation.RuntimeType) ElementMatchers.isDeclaredBy(net.bytebuddy.matcher.ElementMatchers.isDeclaredBy) AllArguments(net.bytebuddy.implementation.bind.annotation.AllArguments) FactoryBean(org.springframework.beans.factory.FactoryBean) Enhancer(net.sf.cglib.proxy.Enhancer) ObjectFactory(org.mule.runtime.dsl.api.component.ObjectFactory) Method(java.lang.reflect.Method) Enhancer.registerStaticCallbacks(net.sf.cglib.proxy.Enhancer.registerStaticCallbacks) Callback(net.sf.cglib.proxy.Callback) MethodInterceptor(net.sf.cglib.proxy.MethodInterceptor) ElementMatchers.named(net.bytebuddy.matcher.ElementMatchers.named) LoadingCache(com.github.benmanes.caffeine.cache.LoadingCache) INJECTION(net.bytebuddy.dynamic.loading.ClassLoadingStrategy.Default.INJECTION) Class.forName(java.lang.Class.forName) ObjectTypeProvider(org.mule.runtime.dsl.api.component.ObjectTypeProvider) ComponentBuildingDefinition(org.mule.runtime.dsl.api.component.ComponentBuildingDefinition) SmartFactoryBean(org.springframework.beans.factory.SmartFactoryBean) FieldAccessor.ofBeanProperty(net.bytebuddy.implementation.FieldAccessor.ofBeanProperty) MethodCall.invoke(net.bytebuddy.implementation.MethodCall.invoke) InvocationHandler(java.lang.reflect.InvocationHandler) CompositeClassLoader.from(org.mule.runtime.core.internal.util.CompositeClassLoader.from) ObjectTypeProvider(org.mule.runtime.dsl.api.component.ObjectTypeProvider) Enhancer(net.sf.cglib.proxy.Enhancer) ObjectFactory(org.mule.runtime.dsl.api.component.ObjectFactory) SmartFactoryBean(org.springframework.beans.factory.SmartFactoryBean)

Example 3 with This

use of net.bytebuddy.implementation.bind.annotation.This in project kin-rsocket-broker by huangjianqin.

the class RequesterProxy method invoke.

@Override
@RuntimeType
public Object invoke(@This Object proxy, @Origin Method method, @AllArguments Object[] args) {
    if (!RSocketAppContext.ENHANCE && method.isDefault()) {
        // jdk代理下, 如果是调用default方法, 直接使用句柄掉漆
        try {
            return MethodHandleUtils.getInterfaceDefaultMethodHandle(method, serviceInterface).bindTo(proxy).invokeWithArguments(args);
        } catch (Throwable throwable) {
            ExceptionUtils.throwExt(throwable);
        }
    }
    if (method.getDeclaringClass().equals(Object.class)) {
        // 过滤Object方法
        try {
            return method.invoke(this, args);
        } catch (IllegalAccessException | InvocationTargetException e) {
            ExceptionUtils.throwExt(e);
        }
    }
    ReactiveMethodMetadata methodMetadata = methodMetadataMap.get(method);
    if (Objects.isNull(methodMetadata)) {
        // lazy init method metadata
        methodMetadata = new ReactiveMethodMetadata(group, service, version, method, defaultEncodingType, defaultAcceptEncodingTypes, endpoint, sticky, sourceUri);
        methodMetadataMap.put(method, methodMetadata);
    }
    MutableContext mutableContext = new MutableContext();
    mutableContext.put(ReactiveMethodMetadata.class, methodMetadata);
    if (methodMetadata.getFrameType() == FrameType.REQUEST_CHANNEL) {
        // request channel
        metrics(methodMetadata);
        ByteBuf routeBytes;
        Flux<Object> paramBodys;
        if (args.length == 1) {
            // 1 param
            routeBytes = Unpooled.EMPTY_BUFFER;
            paramBodys = ReactiveObjAdapter.INSTANCE.toFlux(args[0]);
        } else {
            // 2 params
            routeBytes = Codecs.INSTANCE.encodeResult(args[0], methodMetadata.getDataEncodingType());
            paramBodys = ReactiveObjAdapter.INSTANCE.toFlux(args[1]);
        }
        // handle return
        ReactiveMethodMetadata finalMethodMetadata1 = methodMetadata;
        Flux<Object> result = requestChannel(methodMetadata, methodMetadata.getCompositeMetadataBytes(), routeBytes, paramBodys).concatMap(payload -> {
            try {
                RSocketCompositeMetadata compositeMetadata = RSocketCompositeMetadata.of(payload.metadata());
                return Mono.justOrEmpty(Codecs.INSTANCE.decodeResult(extractPayloadDataMimeType(compositeMetadata, finalMethodMetadata1.getAcceptEncodingTypes()[0]), payload.data(), finalMethodMetadata1.getInferredClassForReturn()));
            } catch (Exception e) {
                return Flux.error(e);
            }
        }).contextWrite(c -> mutableContext.putAll(c.readOnly()));
        if (methodMetadata.isMonoChannel()) {
            return result.last();
        } else {
            return result;
        }
    } else {
        // body content
        ByteBuf paramBodyBytes = Codecs.INSTANCE.encodeParams(args, methodMetadata.getDataEncodingType());
        if (methodMetadata.getFrameType() == FrameType.REQUEST_RESPONSE) {
            // request response
            metrics(methodMetadata);
            ReactiveMethodMetadata finalMethodMetadata = methodMetadata;
            // handle return
            Mono<Object> result = requestResponse(methodMetadata, methodMetadata.getCompositeMetadataBytes(), paramBodyBytes).handle((payload, sink) -> {
                try {
                    RSocketCompositeMetadata compositeMetadata = RSocketCompositeMetadata.of(payload.metadata());
                    Object obj = Codecs.INSTANCE.decodeResult(extractPayloadDataMimeType(compositeMetadata, finalMethodMetadata.getAcceptEncodingTypes()[0]), payload.data(), finalMethodMetadata.getInferredClassForReturn());
                    if (obj != null) {
                        sink.next(obj);
                    }
                    sink.complete();
                } catch (Exception e) {
                    sink.error(e);
                }
            });
            return ReactiveObjAdapter.INSTANCE.fromPublisher(result, mutableContext);
        } else if (methodMetadata.getFrameType() == FrameType.REQUEST_FNF) {
            // request and forget
            metrics(methodMetadata);
            Mono<Void> result = fireAndForget(methodMetadata, methodMetadata.getCompositeMetadataBytes(), paramBodyBytes);
            if (methodMetadata.isReturnVoid()) {
                // 返回void
                result.subscribe();
                return null;
            } else {
                return result;
            }
        } else if (methodMetadata.getFrameType() == FrameType.REQUEST_STREAM) {
            // request stream
            metrics(methodMetadata);
            ReactiveMethodMetadata finalMethodMetadata = methodMetadata;
            Flux<Object> result = requestStream(methodMetadata, methodMetadata.getCompositeMetadataBytes(), paramBodyBytes).concatMap((payload) -> {
                try {
                    RSocketCompositeMetadata compositeMetadata = RSocketCompositeMetadata.of(payload.metadata());
                    return Mono.justOrEmpty(Codecs.INSTANCE.decodeResult(extractPayloadDataMimeType(compositeMetadata, finalMethodMetadata.getAcceptEncodingTypes()[0]), payload.data(), finalMethodMetadata.getInferredClassForReturn()));
                } catch (Exception e) {
                    return Mono.error(e);
                }
            });
            return ReactiveObjAdapter.INSTANCE.fromPublisher(result, mutableContext);
        } else {
            ReferenceCountUtil.safeRelease(paramBodyBytes);
            return Mono.error(new Exception("unknown RSocket Frame type: " + methodMetadata.getFrameType().name()));
        }
    }
}
Also used : This(net.bytebuddy.implementation.bind.annotation.This) Origin(net.bytebuddy.implementation.bind.annotation.Origin) MessageMimeTypeMetadata(org.kin.rsocket.core.metadata.MessageMimeTypeMetadata) LoggerFactory(org.slf4j.LoggerFactory) TimeoutException(java.util.concurrent.TimeoutException) Metrics(io.micrometer.core.instrument.Metrics) Unpooled(io.netty.buffer.Unpooled) RuntimeType(net.bytebuddy.implementation.bind.annotation.RuntimeType) ByteBuf(io.netty.buffer.ByteBuf) AllArguments(net.bytebuddy.implementation.bind.annotation.AllArguments) Duration(java.time.Duration) Map(java.util.Map) URI(java.net.URI) Method(java.lang.reflect.Method) ByteBufPayload(io.rsocket.util.ByteBufPayload) FrameType(io.rsocket.frame.FrameType) RSocketCompositeMetadata(org.kin.rsocket.core.metadata.RSocketCompositeMetadata) Logger(org.slf4j.Logger) org.kin.rsocket.core(org.kin.rsocket.core) MethodHandleUtils(org.kin.framework.utils.MethodHandleUtils) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Mono(reactor.core.publisher.Mono) ExceptionUtils(org.kin.framework.utils.ExceptionUtils) CollectionUtils(org.kin.framework.utils.CollectionUtils) InvocationTargetException(java.lang.reflect.InvocationTargetException) Objects(java.util.Objects) StringUtils(org.kin.framework.utils.StringUtils) Flux(reactor.core.publisher.Flux) Payload(io.rsocket.Payload) ReferenceCountUtil(io.netty.util.ReferenceCountUtil) Codecs(org.kin.rsocket.core.codec.Codecs) InvocationHandler(java.lang.reflect.InvocationHandler) RSocketCompositeMetadata(org.kin.rsocket.core.metadata.RSocketCompositeMetadata) Mono(reactor.core.publisher.Mono) ByteBuf(io.netty.buffer.ByteBuf) InvocationTargetException(java.lang.reflect.InvocationTargetException) TimeoutException(java.util.concurrent.TimeoutException) InvocationTargetException(java.lang.reflect.InvocationTargetException) RuntimeType(net.bytebuddy.implementation.bind.annotation.RuntimeType)

Aggregations

InvocationHandler (java.lang.reflect.InvocationHandler)3 Method (java.lang.reflect.Method)3 AllArguments (net.bytebuddy.implementation.bind.annotation.AllArguments)3 Origin (net.bytebuddy.implementation.bind.annotation.Origin)3 RuntimeType (net.bytebuddy.implementation.bind.annotation.RuntimeType)3 This (net.bytebuddy.implementation.bind.annotation.This)3 Metrics (io.micrometer.core.instrument.Metrics)2 ByteBuf (io.netty.buffer.ByteBuf)2 Unpooled (io.netty.buffer.Unpooled)2 ReferenceCountUtil (io.netty.util.ReferenceCountUtil)2 Payload (io.rsocket.Payload)2 FrameType (io.rsocket.frame.FrameType)2 ByteBufPayload (io.rsocket.util.ByteBufPayload)2 URI (java.net.URI)2 Duration (java.time.Duration)2 Map (java.util.Map)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 TimeoutException (java.util.concurrent.TimeoutException)2 MutableContext (com.alibaba.rsocket.MutableContext)1 ServiceLocator (com.alibaba.rsocket.ServiceLocator)1