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()));
}
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);
}
}
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()));
}
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);
}
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();
}
Aggregations