/// <summary> /// Service discovery endpoint called by the CloudState operator in order to determine /// the list of <see cref="IStatefulService" />'s running within the current local process. /// </summary> /// <param name="request">ProxyInfo request</param> /// <param name="context">ServerCallContext</param> /// <returns></returns> public override async Task <EntitySpec> discover(ProxyInfo request, ServerCallContext context) { Logger.LogInformation( $"Received discovery call from sidecar [{request.ProxyName} {request.ProxyVersion}] supporting CloudState {request.ProtocolMajorVersion}.{request.ProtocolMinorVersion}" ); Logger.LogDebug($"Supported sidecar entity types: {string.Join(", ", request.SupportedEntityTypes)}"); var unsupportedServices = Services.Values.Where(service => !request.SupportedEntityTypes.Contains(service.StatefulServiceTypeName) ); if (unsupportedServices.Any()) { Logger.LogError( "Proxy doesn't support the entity types for the following services: " + string.Join(", ", unsupportedServices .Select(s => s.ServiceDescriptor.FullName + ": " + s.StatefulServiceTypeName) ) ); } if (false) { // TODO: verify compatibility with in.protocolMajorVersion & in.protocolMinorVersion // await Task.FromException(new CloudStateException("Proxy version not compatible with library protocol support version")); } else { var allDescriptors = new AnySupport(Services.Values.Select(x => x.ServiceDescriptor.File)).FlattenDescriptors( Services.Values.Select(x => x.ServiceDescriptor.File) ); var set = new FileDescriptorSet(); set.File.AddRange(allDescriptors.Select(x => FileDescriptorProto.Parser.ParseFrom(x.Value.SerializedData))); var fileDescriptorSet = set.ToByteString(); var entities = Services.Select(x => new Entity { EntityType = x.Value.StatefulServiceTypeName, ServiceName = x.Key, PersistenceId = x.Value.PersistenceId } ); var spec = new EntitySpec { ServiceInfo = ServiceInfo, Proto = fileDescriptorSet }; try { spec.Entities.AddRange(entities); } catch (Exception ex) { Logger.LogError($"Exception: {ex.StackTrace}", ex.InnerException ?? ex); } return(await Task.FromResult(spec)); } }