public async Task <AppConnectionDescriptor> AuthenticateAsync(ITransportConnection connection)
        {
            Log.Trace("Accepting new connection {0}", connection.Id);
            var channel = await connection.IncomingChannels.ReadAsync().ConfigureAwait(false);

            var frame = await channel.In.ReadAsync().ConfigureAwait(false);

            using (var payload = frame.Payload)
                using (var connectRequest = _serializer.DeserializeConnectRequest(payload))
                {
                    if (!_registryService.IsApplicationDefined(connectRequest.ApplicationId))
                    {
                        throw new BrokerException($"Connection rejected because application id is unknown to broker: {connectRequest.ApplicationId}");
                    }
                    if (!_connectionTracker.IsAppInstanceRegistered(connectRequest.ApplicationInstanceId))
                    {
                        Log.Debug("Connection with unknown application instance id: "
                                  + $"ApplicationInstanceId={connectRequest.ApplicationInstanceId}, ApplicationId={connectRequest.ApplicationId}");
                        _connectionTracker.ReportConnectionError(new AppConnectionDescriptor(
                                                                     UniqueId.Empty,
                                                                     connectRequest.ApplicationId,
                                                                     connectRequest.ApplicationInstanceId,
                                                                     connection.TransportType));

                        if (_features.HasFlag(BrokerFeatures.CheckAppInstanceId))
                        {
                            throw new BrokerException("Connection rejected because application instance id is unknown to broker: "
                                                      + $"ApplicationInstanceId={connectRequest.ApplicationInstanceId}, ApplicationId={connectRequest.ApplicationId}");
                        }
                    }
                    using (var connectResponse = _messageFactory.CreateConnectResponse(connection.Id))
                    {
                        var serializedResponse = _serializer.Serialize(connectResponse);
                        try
                        {
                            Log.Trace("Sending connect response ({0} bytes): {1}", connectResponse, serializedResponse.Count);
                            await channel.Out.WriteAsync(new TransportMessageFrame(serializedResponse)).ConfigureAwait(false);
                        }
                        catch
                        {
                            serializedResponse.Dispose();
                            throw;
                        }
                        channel.Out.TryComplete();
                        await channel.Completion.ConfigureAwait(false);

                        return(new AppConnectionDescriptor(
                                   connectResponse.ConnectionId,
                                   connectRequest.ApplicationId,
                                   connectRequest.ApplicationInstanceId,
                                   connection.TransportType));
                    }
                }
        }
Example #2
0
        public Broker(BrokerOptions options, IRegistryProvider registryProvider = null)
        {
            _features = EnvironmentHelper.GetBrokerFeatures();
            Log.Info($"Broker features: {_features}");
            var trustedLauncherId = EnvironmentHelper.GetLauncherAppInstanceId();

            Log.Info($"App launcher application instance id: {trustedLauncherId}");
            if (_features.HasFlag(BrokerFeatures.CheckAppInstanceId) && trustedLauncherId == null)
            {
                throw new BrokerException($"{EnvironmentHelper.LauncherId} must be defined if {BrokerFeatures.CheckAppInstanceId} set.");
            }
            _workingDir = Directory.GetCurrentDirectory();
            var binDir    = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            var studioDir = Path.Combine(binDir, "studio");

            Log.Info("Studio dir: {0}", studioDir);
            var metadataDir = Path.GetFullPath(options.MetadataDir ?? Path.Combine(_workingDir, "metadata"));

            Log.Info("Metadata dir: {0}", metadataDir);
            var metadataFile = Path.Combine(metadataDir, "interop.json");
            IReadOnlyDictionary <string, string> staticFileMapping = new Dictionary <string, string>
            {
                { "/metadata/interop", metadataFile },
                { "/studio", studioDir }
            };
            var webSocketTransmissionServerOptions = new WebSocketTransmissionServerOptions(_workingDir, options.Port, staticFileMapping);
            var transportServers = new List <ITransportServer>
            {
                TransportServerFactory.Instance.Create(
                    TransportType.Pipe,
                    PipeTransmissionServerFactory.Instance.Create(_workingDir),
                    DefaultTransportSerializationProvider),
                TransportServerFactory.Instance.Create(
                    TransportType.Ws,
                    WebSocketTransmissionServerFactory.Instance.Create(webSocketTransmissionServerOptions),
                    DefaultTransportSerializationProvider),
            };

            if (_features.HasFlag(BrokerFeatures.UseWSS))
            {
                var certificate = GetCertificate();
                if (certificate != null)
                {
                    var wssTransmissionServerOptions = new WebSocketTransmissionServerOptions(_workingDir, options.WssPort, staticFileMapping);
                    var sslProtocols = EnvironmentHelper.GetSslProtocols();
                    Log.Info($"{EnvironmentHelper.SslProtocols}={sslProtocols}");
                    transportServers.Add(TransportServerFactory.Instance.Create(
                                             TransportType.Wss,
                                             WebSocketTransmissionServerFactory.Instance.CreateSecure(wssTransmissionServerOptions, certificate, sslProtocols),
                                             DefaultTransportSerializationProvider));
                }
            }
            _transportServers   = transportServers;
            _connectionListener = new ServerConnectionListener(_transportServers);
            registryProvider    = registryProvider ?? new JsonRegistryProvider(Path.Combine(metadataDir, "interop.json"));
            _interopContext     = InteropContextFactory.Instance.Create(trustedLauncherId ?? default, metadataDir, registryProvider);
            _brokerProcessor    = BrokerProcessorFactory.Instance.Create(
                _connectionListener.In,
                DefaultProtocolSerializationProvider,
                _interopContext,
                _features);
            OnStop(_connectionListener.Stop);
        }