use of net.bytebuddy.implementation.bind.annotation.Origin in project kin-rsocket-broker by huangjianqin.
the class ReactiveGrpcCallInterceptor method intercept.
@SuppressWarnings("unchecked")
@RuntimeType
public Object intercept(@Origin Method method, @AllArguments Object[] params) {
if (Object.class.equals(method.getDeclaringClass())) {
// 过滤Object方法
try {
return method.invoke(this, params);
} catch (IllegalAccessException | InvocationTargetException e) {
ExceptionUtils.throwExt(e);
}
}
if (StringUtils.isBlank(serviceId)) {
serviceId = ServiceLocator.gsv(group, service, version);
}
ReactiveGrpcMethodMetadata methodMetadata;
if (!methodMetadataMap.containsKey(method)) {
methodMetadata = new ReactiveGrpcMethodMetadata(method, group, service, version, endpoint, sticky);
methodMetadataMap.put(method, methodMetadata);
} else {
methodMetadata = methodMetadataMap.get(method);
}
RSocket requester = selector.select(serviceId);
if (methodMetadata.getRpcType().equals(ReactiveGrpcMethodMetadata.UNARY)) {
// request response
Mono<GeneratedMessageV3> monoParam = (Mono<GeneratedMessageV3>) params[0];
return monoParam.map(param -> Unpooled.wrappedBuffer(param.toByteArray())).flatMap(paramBodyBytes -> rsocketRpc(requester, methodMetadata, paramBodyBytes));
} else if (methodMetadata.getRpcType().equals(ReactiveGrpcMethodMetadata.SERVER_STREAMING)) {
// request stream
Mono<GeneratedMessageV3> monoParam = (Mono<GeneratedMessageV3>) params[0];
return monoParam.map(param -> Unpooled.wrappedBuffer(param.toByteArray())).flatMapMany(paramBodyBytes -> rsocketStream(requester, methodMetadata, paramBodyBytes));
} else if (methodMetadata.getRpcType().equals(ReactiveGrpcMethodMetadata.CLIENT_STREAMING) || methodMetadata.getRpcType().equals(ReactiveGrpcMethodMetadata.BIDIRECTIONAL_STREAMING)) {
// client streaming or bidirectional streaming, rsocket request channel
// param flux
Flux<Payload> paramsPayloadFlux = ((Flux<GeneratedMessageV3>) params[0]).map(param -> ByteBufPayload.create(Unpooled.wrappedBuffer(param.toByteArray()), PayloadUtils.getCompositeMetaDataWithEncoding()));
Flux<?> responseFlux = rsocketChannel(requester, methodMetadata, paramsPayloadFlux);
if (methodMetadata.getRpcType().equals(ReactiveGrpcMethodMetadata.CLIENT_STREAMING)) {
// return one
return responseFlux.last();
} else {
// return many
return responseFlux;
}
}
return Mono.error(new ReactiveMethodInvokeException("incorrect rpc type for grpc"));
}
use of net.bytebuddy.implementation.bind.annotation.Origin 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())));
}
}
}
use of net.bytebuddy.implementation.bind.annotation.Origin in project alibaba-rsocket-broker by alibaba.
the class GrpcReactiveCallInterceptor method intercept.
@SuppressWarnings("unchecked")
@RuntimeType
public Object intercept(@Origin Method method, @AllArguments Object[] params) {
if (!methodMetadataMap.containsKey(method)) {
methodMetadataMap.put(method, new ReactiveGrpcMethodMetadata(method, group, service, version));
}
ReactiveGrpcMethodMetadata methodMetadata = methodMetadataMap.get(method);
if (methodMetadata.getRpcType().equals(ReactiveGrpcMethodMetadata.UNARY)) {
Mono<GeneratedMessageV3> monoParam = (Mono<GeneratedMessageV3>) params[0];
return monoParam.map(param -> ByteBufPayload.create(Unpooled.wrappedBuffer(param.toByteArray()), methodMetadata.getCompositeMetadataByteBuf().retainedDuplicate())).flatMap(requestPayload -> rsocketRpc(rsocket, requestPayload, methodMetadata.getInferredClassForReturn()).timeout(this.timeout));
} else if (methodMetadata.getRpcType().equals(ReactiveGrpcMethodMetadata.SERVER_STREAMING)) {
Mono<GeneratedMessageV3> monoParam = (Mono<GeneratedMessageV3>) params[0];
return monoParam.map(param -> ByteBufPayload.create(Unpooled.wrappedBuffer(param.toByteArray()), methodMetadata.getCompositeMetadataByteBuf().retainedDuplicate())).flatMapMany(requestPayload -> rsocketStream(rsocket, requestPayload, methodMetadata.getInferredClassForReturn()));
} else if (methodMetadata.getRpcType().equals(ReactiveGrpcMethodMetadata.CLIENT_STREAMING)) {
Payload routePayload = ByteBufPayload.create(Unpooled.EMPTY_BUFFER, methodMetadata.getCompositeMetadataByteBuf().retainedDuplicate());
Flux<Payload> paramsPayloadFlux = ((Flux<GeneratedMessageV3>) params[0]).map(param -> ByteBufPayload.create(Unpooled.wrappedBuffer(param.toByteArray()), PayloadUtils.getCompositeMetaDataWithEncoding().retainedDuplicate()));
return rsocketChannel(rsocket, paramsPayloadFlux.startWith(routePayload), methodMetadata.getInferredClassForReturn()).last();
} else if (methodMetadata.getRpcType().equals(ReactiveGrpcMethodMetadata.BIDIRECTIONAL_STREAMING)) {
Payload routePayload = ByteBufPayload.create(Unpooled.EMPTY_BUFFER, methodMetadata.getCompositeMetadataByteBuf().retainedDuplicate());
Flux<Payload> paramsPayloadFlux = ((Flux<GeneratedMessageV3>) params[0]).map(param -> ByteBufPayload.create(Unpooled.wrappedBuffer(param.toByteArray()), PayloadUtils.getCompositeMetaDataWithEncoding().retainedDuplicate()));
return rsocketChannel(rsocket, paramsPayloadFlux.startWith(routePayload), methodMetadata.getInferredClassForReturn());
}
return Mono.error(new Exception(RsocketErrorCode.message("RST-611301")));
}
use of net.bytebuddy.implementation.bind.annotation.Origin 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()));
}
}
}
Aggregations