Search in sources :

Example 1 with AppMetadata

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

the class RSocketServiceManager method registerRSocketEndpoint.

/**
 * 注册downstream信息
 */
private void registerRSocketEndpoint(RSocketEndpoint rsocketEndpoint) {
    AppMetadata appMetadata = rsocketEndpoint.getAppMetadata();
    Lock writeLock = lock.writeLock();
    writeLock.lock();
    try {
        // copy on write
        Map<String, RSocketEndpoint> uuid2Endpoint = new UnifiedMap<>(this.uuid2Endpoint);
        uuid2Endpoint.put(appMetadata.getUuid(), rsocketEndpoint);
        Integer instanceId = rsocketEndpoint.getId();
        Map<Integer, RSocketEndpoint> instanceId2Endpoint = new UnifiedMap<>(this.instanceId2Endpoint);
        instanceId2Endpoint.put(instanceId, rsocketEndpoint);
        FastListMultimap<String, RSocketEndpoint> appName2Endpoint = new FastListMultimap<>(this.appName2Endpoint);
        appName2Endpoint.put(appMetadata.getName(), rsocketEndpoint);
        UnifiedSetMultimap<String, Integer> p2pServiceConsumers = new UnifiedSetMultimap<>(this.p2pServiceConsumers);
        for (String p2pService : appMetadata.getP2pServiceIds()) {
            p2pServiceConsumers.put(p2pService, instanceId);
            rsocketEndpoint.fireCloudEvent(newServiceInstanceChangedCloudEvent(p2pService)).subscribe();
        }
        this.uuid2Endpoint = uuid2Endpoint;
        this.instanceId2Endpoint = instanceId2Endpoint;
        this.appName2Endpoint = appName2Endpoint;
        this.p2pServiceConsumers = p2pServiceConsumers;
    } finally {
        writeLock.unlock();
    }
    // 广播事件
    RSocketAppContext.CLOUD_EVENT_SINK.tryEmitNext(AppStatusEvent.connected(appMetadata.getUuid()).toCloudEvent());
    if (!brokerManager.isStandAlone()) {
        // 如果不是单节点, 则广播broker uris变化给downstream
        rsocketEndpoint.fireCloudEvent(newBrokerClustersChangedCloudEvent(brokerManager.all(), appMetadata.getTopology())).subscribe();
    }
    notificationSink.tryEmitNext(String.format("app '%s' with ip '%s' online now!", appMetadata.getName(), appMetadata.getIp()));
}
Also used : UnifiedSetMultimap(org.eclipse.collections.impl.multimap.set.UnifiedSetMultimap) UnifiedMap(org.eclipse.collections.impl.map.mutable.UnifiedMap) AppMetadata(org.kin.rsocket.core.metadata.AppMetadata) FastListMultimap(org.eclipse.collections.impl.multimap.list.FastListMultimap) ReentrantReadWriteLock(java.util.concurrent.locks.ReentrantReadWriteLock) ReadWriteLock(java.util.concurrent.locks.ReadWriteLock) Lock(java.util.concurrent.locks.Lock)

Example 2 with AppMetadata

use of org.kin.rsocket.core.metadata.AppMetadata 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 AppMetadata

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

the class RSocketServiceManager method onRSocketEndpointDisposed.

/**
 * {@link RSocketEndpoint} disposed时触发的逻辑
 */
private void onRSocketEndpointDisposed(RSocketEndpoint rsocketEndpoint) {
    AppMetadata appMetadata = rsocketEndpoint.getAppMetadata();
    Lock writeLock = lock.writeLock();
    writeLock.lock();
    try {
        // copy on write
        Map<String, RSocketEndpoint> uuid2Endpoint = new UnifiedMap<>(this.uuid2Endpoint);
        uuid2Endpoint.remove(rsocketEndpoint.getUuid());
        Integer instanceId = rsocketEndpoint.getId();
        Map<Integer, RSocketEndpoint> instanceId2Endpoint = new UnifiedMap<>(this.instanceId2Endpoint);
        instanceId2Endpoint.remove(instanceId);
        FastListMultimap<String, RSocketEndpoint> appName2Endpoint = new FastListMultimap<>(this.appName2Endpoint);
        appName2Endpoint.remove(appMetadata.getName(), rsocketEndpoint);
        UnifiedSetMultimap<String, Integer> p2pServiceConsumers = new UnifiedSetMultimap<>(this.p2pServiceConsumers);
        for (String p2pService : appMetadata.getP2pServiceIds()) {
            p2pServiceConsumers.remove(p2pService, instanceId);
        }
        this.uuid2Endpoint = uuid2Endpoint;
        this.instanceId2Endpoint = instanceId2Endpoint;
        this.appName2Endpoint = appName2Endpoint;
        this.p2pServiceConsumers = p2pServiceConsumers;
    } finally {
        writeLock.unlock();
    }
    log.info(String.format("succeed to remove connection from application '%s'", appMetadata.getName()));
    RSocketAppContext.CLOUD_EVENT_SINK.tryEmitNext(AppStatusEvent.stopped(appMetadata.getUuid()).toCloudEvent());
    this.notificationSink.tryEmitNext(String.format("app '%s' with ip '%s' offline now!", appMetadata.getName(), appMetadata.getIp()));
}
Also used : UnifiedSetMultimap(org.eclipse.collections.impl.multimap.set.UnifiedSetMultimap) UnifiedMap(org.eclipse.collections.impl.map.mutable.UnifiedMap) AppMetadata(org.kin.rsocket.core.metadata.AppMetadata) FastListMultimap(org.eclipse.collections.impl.multimap.list.FastListMultimap) ReentrantReadWriteLock(java.util.concurrent.locks.ReentrantReadWriteLock) ReadWriteLock(java.util.concurrent.locks.ReadWriteLock) Lock(java.util.concurrent.locks.Lock)

Example 4 with AppMetadata

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

the class AppQueryController method query.

@GetMapping("/{appName}")
public Flux<AppVO> query(@PathVariable(name = "appName") String appName) {
    List<AppVO> apps = new ArrayList<>();
    Collection<RSocketEndpoint> rsocketEndpoints = serviceManager.getByAppName(appName);
    if (CollectionUtils.isEmpty(rsocketEndpoints)) {
        return Flux.empty();
    }
    for (RSocketEndpoint rsocketEndpoint : rsocketEndpoints) {
        AppMetadata appMetadata = rsocketEndpoint.getAppMetadata();
        apps.add(appMetadata.toVo());
    }
    return Flux.fromIterable(apps);
}
Also used : AppVO(org.kin.rsocket.core.domain.AppVO) ArrayList(java.util.ArrayList) AppMetadata(org.kin.rsocket.core.metadata.AppMetadata) RSocketEndpoint(org.kin.rsocket.broker.RSocketEndpoint) GetMapping(org.springframework.web.bind.annotation.GetMapping)

Example 5 with AppMetadata

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

the class PortsUpdateEventConsumer method consume.

@Override
public Mono<Void> consume(CloudEventData<?> cloudEventData, PortsUpdateEvent event) {
    if (event != null) {
        RSocketEndpoint rsocketEndpoint = serviceManager.getByUUID(event.getAppId());
        if (rsocketEndpoint != null) {
            AppMetadata appMetadata = rsocketEndpoint.getAppMetadata();
            appMetadata.updateWebPort(event.getWebPort());
            appMetadata.updateManagementPort(event.getManagementPort());
            appMetadata.updateRSocketPorts(event.getRsocketPorts());
        }
    }
    return Mono.empty();
}
Also used : AppMetadata(org.kin.rsocket.core.metadata.AppMetadata) RSocketEndpoint(org.kin.rsocket.broker.RSocketEndpoint)

Aggregations

AppMetadata (org.kin.rsocket.core.metadata.AppMetadata)7 Lock (java.util.concurrent.locks.Lock)3 ReadWriteLock (java.util.concurrent.locks.ReadWriteLock)3 ReentrantReadWriteLock (java.util.concurrent.locks.ReentrantReadWriteLock)3 UnifiedSetMultimap (org.eclipse.collections.impl.multimap.set.UnifiedSetMultimap)3 UnifiedMap (org.eclipse.collections.impl.map.mutable.UnifiedMap)2 FastListMultimap (org.eclipse.collections.impl.multimap.list.FastListMultimap)2 RSocketEndpoint (org.kin.rsocket.broker.RSocketEndpoint)2 ApplicationErrorException (io.rsocket.exceptions.ApplicationErrorException)1 RejectedSetupException (io.rsocket.exceptions.RejectedSetupException)1 ArrayList (java.util.ArrayList)1 Nonnull (javax.annotation.Nonnull)1 RSocketAppPrincipal (org.kin.rsocket.auth.RSocketAppPrincipal)1 RSocketServiceInstance (org.kin.rsocket.core.discovery.RSocketServiceInstance)1 AppVO (org.kin.rsocket.core.domain.AppVO)1 BearerTokenMetadata (org.kin.rsocket.core.metadata.BearerTokenMetadata)1 RSocketCompositeMetadata (org.kin.rsocket.core.metadata.RSocketCompositeMetadata)1 GetMapping (org.springframework.web.bind.annotation.GetMapping)1