Search in sources :

Example 1 with RSocketCompositeMetadata

use of org.kin.rsocket.core.metadata.RSocketCompositeMetadata in project kin-rsocket-broker by huangjianqin.

the class HttpGatewayController method handle.

@RequestMapping(value = "/{service}/{method}", produces = { MediaType.APPLICATION_JSON_VALUE })
public Mono<ResponseEntity<ByteBuf>> handle(@PathVariable("service") String service, @PathVariable("method") String method, @RequestParam(name = "group", required = false, defaultValue = "") String group, @RequestParam(name = "version", required = false, defaultValue = "") String version, @RequestBody(required = false) ByteBuf body, @RequestHeader(name = HttpHeaders.AUTHORIZATION, required = false, defaultValue = "") String token) {
    boolean authenticated;
    if (!config.isRestApiAuth()) {
        authenticated = true;
    } else {
        authenticated = Objects.nonNull(authenticationService.auth(token));
    }
    if (!authenticated) {
        return Mono.error(new Exception("Failed to validate JWT token, please supply correct token."));
    }
    try {
        GSVRoutingMetadata routingMetadata = GSVRoutingMetadata.of(group, service, method, version);
        RSocketCompositeMetadata compositeMetadata = RSocketCompositeMetadata.of(routingMetadata, JSON_ENCODING_MIME_TYPE);
        ByteBuf bodyBuf = body == null ? EMPTY_BUFFER : body;
        return upstreamClusterManager.getBroker().requestResponse(ByteBufPayload.create(bodyBuf, compositeMetadata.getContent())).map(payload -> {
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.setCacheControl(CacheControl.noCache().getHeaderValue());
            return new ResponseEntity<>(payload.data(), headers, HttpStatus.OK);
        });
    } catch (Exception e) {
        return Mono.error(e);
    }
}
Also used : RSocketCompositeMetadata(org.kin.rsocket.core.metadata.RSocketCompositeMetadata) GSVRoutingMetadata(org.kin.rsocket.core.metadata.GSVRoutingMetadata) ByteBuf(io.netty.buffer.ByteBuf)

Example 2 with RSocketCompositeMetadata

use of org.kin.rsocket.core.metadata.RSocketCompositeMetadata in project kin-rsocket-broker by huangjianqin.

the class RSocketServiceManager method acceptor.

/**
 * service rsocket endpoint acceptor逻辑
 */
@SuppressWarnings("ConstantConditions")
@Nonnull
private Mono<RSocket> acceptor(ConnectionSetupPayload setupPayload, RSocket requester) {
    // parse setup payload
    RSocketCompositeMetadata compositeMetadata = null;
    AppMetadata appMetadata = null;
    String credentials = "";
    RSocketAppPrincipal principal = null;
    String errorMsg = null;
    try {
        compositeMetadata = RSocketCompositeMetadata.of(setupPayload.metadata());
        if (!authRequired) {
            // authentication not required
            principal = RSocketAppPrincipal.DEFAULT;
            credentials = UUID.randomUUID().toString();
        } else if (compositeMetadata.contains(RSocketMimeType.BEARER_TOKEN)) {
            BearerTokenMetadata bearerTokenMetadata = compositeMetadata.getMetadata(RSocketMimeType.BEARER_TOKEN);
            credentials = new String(bearerTokenMetadata.getBearerToken());
            principal = authenticationService.auth(credentials);
        } else {
            // no jwt token supplied
            errorMsg = "Failed to accept the connection, please check app info and JWT token";
        }
        // validate application information
        if (principal != null && compositeMetadata.contains(RSocketMimeType.APPLICATION)) {
            AppMetadata temp = compositeMetadata.getMetadata(RSocketMimeType.APPLICATION);
            // App registration validation: app id: UUID and unique in server
            String appId = temp.getUuid();
            // validate appId data format
            if (StringUtils.isNotBlank(appId) && appId.length() >= 32) {
                int instanceId = MurmurHash3.hash32(credentials + ":" + temp.getUuid());
                temp.updateInstanceId(instanceId);
                // application instance not connected
                if (!containsInstanceId(instanceId)) {
                    appMetadata = temp;
                    appMetadata.updateConnectedAt(new Date());
                } else {
                    // application connected already
                    errorMsg = "Connection created already, Please don't create multiple connections.";
                }
            } else {
                // 没有uuid是否要拒绝连接
                // illegal application id, appID should be UUID
                errorMsg = String.format("'%s' is not legal application ID, please supply legal UUID as Application ID", appId == null ? "" : appId);
            }
        } else {
            errorMsg = "Can not found application metadata";
        }
        if (errorMsg == null) {
            // Security authentication
            if (appMetadata != null) {
                appMetadata.addMetadata("_orgs", String.join(",", principal.getOrganizations()));
                appMetadata.addMetadata("_roles", String.join(",", principal.getRoles()));
                appMetadata.addMetadata("_serviceAccounts", String.join(",", principal.getServiceAccounts()));
            } else {
                errorMsg = "Please supply message/x.rsocket.application+json metadata in setup payload";
            }
        }
    } catch (Exception e) {
        log.error("Error to parse setup payload", e);
        errorMsg = String.format("Failed to parse composite metadata: %s", e.getMessage());
    }
    // validate connection legal or not
    if (principal == null) {
        errorMsg = "Failed to accept the connection, please check app info and JWT token";
    }
    if (errorMsg != null) {
        return returnRejectedRSocket(errorMsg, requester);
    }
    // create rsocket endpoint
    try {
        RSocketBrokerResponderHandler responderHandler = new RSocketBrokerResponderHandler(setupPayload, appMetadata, principal, this, serviceMeshInspector, upstreamBrokers, rsocketFilterChain);
        RSocketEndpoint rsocketEndpoint = new RSocketEndpoint(compositeMetadata, appMetadata, requester, this, responderHandler);
        rsocketEndpoint.onClose().doOnTerminate(() -> onRSocketEndpointDisposed(rsocketEndpoint)).subscribeOn(Schedulers.parallel()).subscribe();
        // handler registration notify
        registerRSocketEndpoint(rsocketEndpoint);
        // connect success, so publish service now
        rsocketEndpoint.publishServices();
        log.info(String.format("succeed to accept connection from application '%s'", appMetadata.getName()));
        return Mono.just(responderHandler);
    } catch (Exception e) {
        String formattedErrorMsg = String.format("failed to accept the connection: %s", e.getMessage());
        log.error(formattedErrorMsg, e);
        return returnRejectedRSocket(formattedErrorMsg, requester);
    }
}
Also used : RSocketCompositeMetadata(org.kin.rsocket.core.metadata.RSocketCompositeMetadata) BearerTokenMetadata(org.kin.rsocket.core.metadata.BearerTokenMetadata) AppMetadata(org.kin.rsocket.core.metadata.AppMetadata) RSocketAppPrincipal(org.kin.rsocket.auth.RSocketAppPrincipal) RejectedSetupException(io.rsocket.exceptions.RejectedSetupException) ApplicationErrorException(io.rsocket.exceptions.ApplicationErrorException) Nonnull(javax.annotation.Nonnull)

Example 3 with RSocketCompositeMetadata

use of org.kin.rsocket.core.metadata.RSocketCompositeMetadata in project kin-rsocket-broker by huangjianqin.

the class BrokerRequestHandler method fireAndForget.

@Nonnull
@Override
public Mono<Void> fireAndForget(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_FNF, 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_FNF.name());
        return rsocket.fireAndForget(payload);
    });
}
Also used : RSocketCompositeMetadata(org.kin.rsocket.core.metadata.RSocketCompositeMetadata) GSVRoutingMetadata(org.kin.rsocket.core.metadata.GSVRoutingMetadata) BinaryRoutingMetadata(org.kin.rsocket.core.metadata.BinaryRoutingMetadata) InvalidException(io.rsocket.exceptions.InvalidException) RSocket(io.rsocket.RSocket) AbstractRSocket(org.kin.rsocket.core.AbstractRSocket) Nonnull(javax.annotation.Nonnull)

Example 4 with RSocketCompositeMetadata

use of org.kin.rsocket.core.metadata.RSocketCompositeMetadata in project kin-rsocket-broker by huangjianqin.

the class BrokerRequestHandler method requestStream.

@Nonnull
@Override
public Flux<Payload> requestStream(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 Flux.error(new InvalidException("No Routing metadata"));
        }
    }
    // request filters
    Mono<RSocket> destination;
    if (this.filterChain.isFiltersPresent()) {
        RSocketFilterContext filterContext = RSocketFilterContext.of(FrameType.REQUEST_STREAM, gsvRoutingMetadata, this.upstreamBrokerMetadata, payload);
        // filter可能会改变gsv metadata的数据, 影响路由结果
        destination = filterChain.filter(filterContext).then(findDestination(gsvRoutingMetadata));
    } else {
        destination = findDestination(gsvRoutingMetadata);
    }
    return destination.flatMapMany(rsocket -> {
        MetricsUtils.metrics(gsvRoutingMetadata, FrameType.REQUEST_STREAM.name());
        return rsocket.requestStream(payload);
    });
}
Also used : RSocketCompositeMetadata(org.kin.rsocket.core.metadata.RSocketCompositeMetadata) GSVRoutingMetadata(org.kin.rsocket.core.metadata.GSVRoutingMetadata) BinaryRoutingMetadata(org.kin.rsocket.core.metadata.BinaryRoutingMetadata) InvalidException(io.rsocket.exceptions.InvalidException) RSocket(io.rsocket.RSocket) AbstractRSocket(org.kin.rsocket.core.AbstractRSocket) Nonnull(javax.annotation.Nonnull)

Example 5 with RSocketCompositeMetadata

use of org.kin.rsocket.core.metadata.RSocketCompositeMetadata in project kin-rsocket-broker by huangjianqin.

the class RSocketApiController method handle.

@RequestMapping(value = "/{service}/{method}", produces = { MediaType.APPLICATION_JSON_VALUE })
public Mono<ResponseEntity<String>> handle(@PathVariable("service") String service, @PathVariable("method") String method, @RequestParam(name = "group", required = false, defaultValue = "") String group, @RequestParam(name = "version", required = false, defaultValue = "") String version, @RequestBody(required = false) byte[] body, @RequestHeader(name = "X-Endpoint", required = false, defaultValue = "") String endpoint, @RequestHeader(name = HttpHeaders.AUTHORIZATION, required = false, defaultValue = "") String token) {
    try {
        GSVRoutingMetadata routingMetadata = GSVRoutingMetadata.of(group, service, method, version);
        int serviceId = routingMetadata.serviceId();
        ByteBuf bodyBuf = body == null ? EMPTY_BUFFER : Unpooled.wrappedBuffer(body);
        RSocketEndpoint rsocketEndpoint;
        if (endpoint.startsWith("id:")) {
            // 存在endpoint
            int instanceId = Integer.parseInt(endpoint.substring(3).trim());
            rsocketEndpoint = serviceManager.getByInstanceId(instanceId);
        } else {
            rsocketEndpoint = serviceManager.routeByServiceId(serviceId);
        }
        if (Objects.nonNull(rsocketEndpoint)) {
            if (rsocketBrokerProperties.isAuth()) {
                RSocketAppPrincipal principal = authenticationService.auth(token);
                if (principal == null || !serviceMeshInspector.isAllowed(principal, serviceId, rsocketEndpoint.getPrincipal())) {
                    return Mono.just(error(String.format("Service request not allowed '%s'", routingMetadata.gsv())));
                }
            }
            RSocketCompositeMetadata compositeMetadata = RSocketCompositeMetadata.of(routingMetadata, JSON_ENCODING_METADATA);
            return rsocketEndpoint.requestResponse(DefaultPayload.create(bodyBuf, compositeMetadata.getContent())).map(payload -> {
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_JSON);
                headers.setCacheControl(CacheControl.noCache().getHeaderValue());
                return new ResponseEntity<>(payload.getDataUtf8(), headers, HttpStatus.OK);
            });
        }
        return Mono.just(error(String.format("service not found, '%s'", routingMetadata.gsv())));
    } catch (Exception e) {
        return Mono.just(error(e.getMessage()));
    }
}
Also used : RSocketCompositeMetadata(org.kin.rsocket.core.metadata.RSocketCompositeMetadata) GSVRoutingMetadata(org.kin.rsocket.core.metadata.GSVRoutingMetadata) ByteBuf(io.netty.buffer.ByteBuf) RSocketEndpoint(org.kin.rsocket.broker.RSocketEndpoint) RSocketAppPrincipal(org.kin.rsocket.auth.RSocketAppPrincipal) RSocketEndpoint(org.kin.rsocket.broker.RSocketEndpoint)

Aggregations

RSocketCompositeMetadata (org.kin.rsocket.core.metadata.RSocketCompositeMetadata)10 GSVRoutingMetadata (org.kin.rsocket.core.metadata.GSVRoutingMetadata)7 ByteBuf (io.netty.buffer.ByteBuf)4 RSocket (io.rsocket.RSocket)4 InvalidException (io.rsocket.exceptions.InvalidException)4 Nonnull (javax.annotation.Nonnull)4 AbstractRSocket (org.kin.rsocket.core.AbstractRSocket)4 BinaryRoutingMetadata (org.kin.rsocket.core.metadata.BinaryRoutingMetadata)4 Payload (io.rsocket.Payload)2 ByteBufPayload (io.rsocket.util.ByteBufPayload)2 RSocketAppPrincipal (org.kin.rsocket.auth.RSocketAppPrincipal)2 RSocketEndpoint (org.kin.rsocket.broker.RSocketEndpoint)2 Metrics (io.micrometer.core.instrument.Metrics)1 Unpooled (io.netty.buffer.Unpooled)1 ReferenceCountUtil (io.netty.util.ReferenceCountUtil)1 ApplicationErrorException (io.rsocket.exceptions.ApplicationErrorException)1 RejectedSetupException (io.rsocket.exceptions.RejectedSetupException)1 FrameType (io.rsocket.frame.FrameType)1 InvocationHandler (java.lang.reflect.InvocationHandler)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1