use of org.kin.rsocket.core.metadata.RSocketCompositeMetadata in project kin-rsocket-broker by huangjianqin.
the class RSocketServiceQueryController method queryDefinition.
@GetMapping(value = "/definition/{service}")
public Mono<String> queryDefinition(@RequestParam(name = "group", defaultValue = "") String group, @PathVariable(name = "service") String service, @RequestParam(name = "version", defaultValue = "") String version) {
ByteBuf bodyBuf = Unpooled.wrappedBuffer(("[\"".concat(service).concat("\"]")).getBytes(StandardCharsets.UTF_8));
RSocketEndpoint RSocketEndpoint = serviceManager.routeByServiceId(ServiceLocator.of(group, service, version).getId());
if (Objects.nonNull(RSocketEndpoint)) {
GSVRoutingMetadata routingMetadata = GSVRoutingMetadata.of("", RSocketServiceInfoSupport.class.getName() + ".getReactiveServiceInfoByName", "");
RSocketCompositeMetadata compositeMetadata = RSocketCompositeMetadata.of(routingMetadata, JSON_ENCODING_METADATA);
return RSocketEndpoint.requestResponse(ByteBufPayload.create(bodyBuf, compositeMetadata.getContent())).map(Payload::getDataUtf8);
}
return Mono.error(new Exception(String.format("Service not found '%s'", service)));
}
use of org.kin.rsocket.core.metadata.RSocketCompositeMetadata in project kin-rsocket-broker by huangjianqin.
the class BrokerRequestHandler method requestResponse.
@Nonnull
@Override
public Mono<Payload> requestResponse(Payload payload) {
BinaryRoutingMetadata binaryRoutingMetadata = BinaryRoutingMetadata.extract(payload.metadata());
GSVRoutingMetadata gsvRoutingMetadata;
if (binaryRoutingMetadata != null) {
gsvRoutingMetadata = binaryRoutingMetadata.toGSVRoutingMetadata();
} else {
RSocketCompositeMetadata compositeMetadata = RSocketCompositeMetadata.of(payload.metadata());
gsvRoutingMetadata = compositeMetadata.getMetadata(RSocketMimeType.ROUTING);
if (gsvRoutingMetadata == null) {
return Mono.error(new InvalidException("No Routing metadata"));
}
}
// request filters
Mono<RSocket> destination;
if (this.filterChain.isFiltersPresent()) {
RSocketFilterContext filterContext = RSocketFilterContext.of(FrameType.REQUEST_RESPONSE, gsvRoutingMetadata, this.upstreamBrokerMetadata, payload);
// filter可能会改变gsv metadata的数据, 影响路由结果
destination = filterChain.filter(filterContext).then(findDestination(gsvRoutingMetadata));
} else {
destination = findDestination(gsvRoutingMetadata);
}
// call destination
return destination.flatMap(rsocket -> {
MetricsUtils.metrics(gsvRoutingMetadata, FrameType.REQUEST_RESPONSE.name());
return rsocket.requestResponse(payload);
});
}
use of org.kin.rsocket.core.metadata.RSocketCompositeMetadata 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()));
}
}
}
use of org.kin.rsocket.core.metadata.RSocketCompositeMetadata in project kin-rsocket-broker by huangjianqin.
the class CloudEventSupport method extractCloudEventsFromMetadata.
/**
* 从payload metadata中获取元数据
*/
static CloudEventData<JsonNode> extractCloudEventsFromMetadata(Payload payload) {
String jsonText = null;
byte firstByte = payload.metadata().getByte(0);
// json text: well known type > 127, and normal mime type's length < 127
if (firstByte == '{') {
jsonText = payload.getMetadataUtf8();
} else {
// composite metadata
RSocketCompositeMetadata compositeMetadata = RSocketCompositeMetadata.of(payload.metadata());
if (compositeMetadata.contains(RSocketMimeType.CLOUD_EVENTS_JSON)) {
jsonText = compositeMetadata.getMetadataBytes(RSocketMimeType.CLOUD_EVENTS_JSON).toString(StandardCharsets.UTF_8);
}
}
if (jsonText != null) {
return org.kin.rsocket.core.utils.JSON.decodeValue(jsonText);
}
return null;
}
use of org.kin.rsocket.core.metadata.RSocketCompositeMetadata in project kin-rsocket-broker by huangjianqin.
the class BrokerRequestHandler method requestChannel.
private Flux<Payload> requestChannel(Payload signal, Publisher<Payload> payloads) {
BinaryRoutingMetadata binaryRoutingMetadata = BinaryRoutingMetadata.extract(signal.metadata());
GSVRoutingMetadata gsvRoutingMetadata;
if (binaryRoutingMetadata != null) {
gsvRoutingMetadata = binaryRoutingMetadata.toGSVRoutingMetadata();
} else {
RSocketCompositeMetadata compositeMetadata = RSocketCompositeMetadata.of(signal.metadata());
gsvRoutingMetadata = compositeMetadata.getMetadata(RSocketMimeType.ROUTING);
if (gsvRoutingMetadata == null) {
return Flux.error(new InvalidException("No Routing metadata"));
}
}
Mono<RSocket> destination = findDestination(gsvRoutingMetadata);
return destination.flatMapMany(rsocket -> {
MetricsUtils.metrics(gsvRoutingMetadata, FrameType.REQUEST_CHANNEL.name());
return rsocket.requestChannel(payloads);
});
}
Aggregations