protected void HandleSubMsg(byte[] data) { UInt16 appCode = 0, funcCode = 0; int opCode = 0; IProtocolHead ph = PackageUtils.Deserialize2Proto(data, ref appCode, ref funcCode, ref opCode, false); if (null == ph) { return; } if (ph is ProtoVO.common.packet) { ProtoVO.common.packet packet = ph as ProtoVO.common.packet; // for(int i = 0; i < packet.batchPackets.Count; i++) // { // HandleSubMsg(packet.batchPackets[i].packet); // } return; } Operation op = operationQueue.OnRecieve(opCode); int id = PackageUtils.GetProtocolID(appCode, funcCode); if (!handlerMap.ContainsKey(id)) { // Logger.LogWarning("Can't find handler for " + AppFnMapping.MAPPING[funcCode].Name); return; } HandleCallBack(ph, id, op, opCode); HandleOperationError(appCode, funcCode, op, ph); }
public static IProtocolHead Decode(byte[] package, ref UInt16 appCode, ref UInt16 funcCode, ref int opCode, bool hasHead = true) { Debug.Log("decode message"); int packageLen = hasHead ?SupposedPackageLen(package): package.Length; if (packageLen != (package.Length)) { Logger.LogError("response data head mismatch with actual length!"); Logger.LogError("SupposedPackageLen: " + packageLen); Logger.LogError("Real length: " + package.Length); appCode = 0; funcCode = 0; return(null); } int payloadLen = packageLen - (hasHead?HEAD_LENGTH:0); if (payloadLen == 0) { return(null); } byte[] payload = new byte[payloadLen]; // payload Array.Copy(package, hasHead?PAYLOAD_OFFSET:0, payload, 0, payloadLen); opCode = 0; IProtocolHead ph = DecodeMessage(payload, ref appCode, ref funcCode); return(ph); }
private static IProtocolHead DecodeMessage(byte[] data, ref UInt16 appCode, ref UInt16 funcCode) { IProtocolHead ph = null; appCode = 0; funcCode = (UInt16)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(data, 1)); System.Type targetType = GetProtocolType(appCode, funcCode); Debug.Log("decode message: " + targetType); if (targetType == null) { return(null); } try { int len = data.Length - 3; byte[] msgData = new byte[len]; Array.Copy(data, 3, msgData, 0, len); ph = DataParser.Deserialize(msgData, targetType) as IProtocolHead; } catch (Exception e) { Debug.LogError("exception ==" + e.Message); } return(ph); }
private void OnReceive(GameNetWork.SockMsgRouter router, IProtocolHead ph) { if (mAction != null) { mAction(router, ph); } UnRegister(); }
public void FakeRecieveMsg(IProtocolHead ph, int funcCode) { Delegate func = handlerMap[funcCode]; if (func != null) { ((MsgHandler)func)(this, ph); } }
public Operation(int opCode, UInt16 funcCode, IProtocolHead ph, byte[] data, bool mask = false) { // _owner = proxy; this._opCode = opCode; this._data = data; this._mask = mask; this._funcCode = funcCode; this._ph = ph; // sendTime = Time.realtimeSinceStartup;//TimeProxy.CurrentServerTime; }
private void HandleCallBack(IProtocolHead ph, int callBackId, Operation op, int opCode) { Delegate func = null; handlerMap.TryGetValue(callBackId, out func); if (func != null) { ((MsgHandler)func)(this, ph); // if(ph.GetType() != typeof(ProtoVO.common.HeartBeat)) // Logger.Log("ming receive response " + ph.GetType().Name.ToString() + "!"); } }
async Task StartProtocolHead() { string certificateValue = await SecretsHelper.GetSecret("IotHubMqttHeadCert"); byte[] cert = Convert.FromBase64String(certificateValue); var certificate = new X509Certificate2(cert); // TODO for now this is empty as will suffice for SAS X.509 thumbprint auth but we will need other CA certs for X.509 CA validation var trustBundle = new List <X509Certificate2>(); string edgeDeviceConnectionString = await SecretsHelper.GetSecretFromConfigKey("edgeCapableDeviceConnStrKey"); // TODO - After IoTHub supports MQTT, remove this and move to using MQTT for upstream connections await ConnectToIotHub(edgeDeviceConnectionString); ConfigHelper.TestConfig[EdgeHubConstants.ConfigKey.IotHubConnectionString] = edgeDeviceConnectionString; IDependencyManager dependencyManager = new DependencyManager(ConfigHelper.TestConfig, certificate, trustBundle, this.sslProtocols); Hosting hosting = Hosting.Initialize(ConfigHelper.TestConfig, certificate, dependencyManager, true, this.sslProtocols); this.hosting = hosting; IContainer container = hosting.Container; // CloudConnectionProvider and RoutingEdgeHub have a circular dependency. So set the // EdgeHub on the CloudConnectionProvider before any other operation ICloudConnectionProvider cloudConnectionProvider = await container.Resolve <Task <ICloudConnectionProvider> >(); IEdgeHub edgeHub = await container.Resolve <Task <IEdgeHub> >(); cloudConnectionProvider.BindEdgeHub(edgeHub); IConfigSource configSource = await container.Resolve <Task <IConfigSource> >(); ConfigUpdater configUpdater = await container.Resolve <Task <ConfigUpdater> >(); await configUpdater.Init(configSource); ILogger logger = container.Resolve <ILoggerFactory>().CreateLogger("EdgeHub"); MqttProtocolHead mqttProtocolHead = await container.Resolve <Task <MqttProtocolHead> >(); AmqpProtocolHead amqpProtocolHead = await container.Resolve <Task <AmqpProtocolHead> >(); var httpProtocolHead = new HttpProtocolHead(hosting.WebHost); this.protocolHead = new EdgeHubProtocolHead(new List <IProtocolHead> { mqttProtocolHead, amqpProtocolHead, httpProtocolHead }, logger); await this.protocolHead.StartAsync(); }
void OnNewUser(SockRouter router, IProtocolHead ph) { NewUser data = ph as NewUser; if (!players.ContainsKey(data.Uid)) { players.Add(data.Uid, new Player { playerName = data.Name, uid = data.Uid }); } SendEvent(new RoomEvent(RoomEvent.Join, data)); }
void OnLogin(SockRouter router, IProtocolHead ph) { Debug.Log("login success"); LoginResponse data = ph as LoginResponse; if (data.Error == 0) { ID = data.Id; UserName = data.Username; PlayerPrefs.SetInt("MasterID", ID); PlayerPrefs.SetString("username", UserName); PlayerPrefs.SetString("password", data.Password); PlayerPrefs.Save(); } SendEvent(new LoginEvent(LoginEvent.Login, data)); }
protected override void HandleMsg(byte[] data) { Debug.Log("recieved message"); UInt16 appCode = 0, funcCode = 0; int opCode = 0; IProtocolHead ph = PackageUtils.Deserialize2Proto(data, ref appCode, ref funcCode, ref opCode); if (null == ph) { return; } // if(ph is ProtoVO.common.packet) // { // ProtoVO.common.packet packet = ph as ProtoVO.common.packet; // for(int i = 0; i < packet.batchPackets.Count; i++) // { // HandleSubMsg(packet.batchPackets[i].packet); // } // return; // } // else if(ph is ProtoVO.user.UserSyncReq) // {Logger.Log("Reconnect finish"); // // ProtoVO.user.UserSyncReq sync = ph as ProtoVO.user.UserSyncReq; // // for(int i = 0; i < sync.jobQueues.Count; i++) // { // HandleSubMsg(sync.jobQueues[i].packet); // } // if(sync.userInfo != null && sync.userInfo.packet != null) // HandleSubMsg(sync.userInfo.packet); // if( blockGameMsgBack != null) // blockGameMsgBack.Invoke(); // } Operation op = operationQueue.OnRecieve(opCode); int id = PackageUtils.GetProtocolID(appCode, funcCode); // if (!handlerMap.ContainsKey(id)) // { // Logger.LogWarning("Can't find handler for " + AppFnMapping.MAPPING[funcCode].Name); // return; // } HandleCallBack(ph, id, op, opCode); HandleOperationError(appCode, funcCode, op, ph); }
void OnAllMembers(SockRouter router, IProtocolHead ph) { AllMembers data = ph as AllMembers; for (int i = 0; i < data.Members.Count; i++) { int uid = int.Parse(data.Members[i]); if (players.ContainsKey(uid)) { continue; } players.Add(uid, new Player { playerName = data.Members[i], uid = uid }); } SendEvent(new RoomEvent(RoomEvent.AllMembers, data)); }
protected override void HandleMsg(string url, MsgWrap mwrap) { UInt16 appCode = 0, funcCode = 0; int opCode = 0; if (!mwrap.req.needResponse) { return; } byte[] data = mwrap.rsp.result; IProtocolHead ph = PackageUtils.Deserialize2Proto(data, ref appCode, ref funcCode, ref opCode); if (null == ph) { Debug.LogError("package error: " + url); Debug.LogError(Convert.ToBase64String(data)); return; } int id = PackageUtils.GetProtocolID(appCode, funcCode); // if(mwrap.req._callback != null) // { // mwrap.req._callback(url, ph); // } if (!handlerDic.ContainsKey(id)) { Logger.LogWarning("Can't find handler for " + appCode + " | " + funcCode); return; } Delegate handler = handlerDic[id]; if (null != handler) { ((MsgHandler)handler)(url, ph); } }
private static byte FlagFromProto(IProtocolHead proto) { Type t = proto.GetType(); System.Reflection.MethodInfo flagProc = null; if (flagProcDict.ContainsKey(t.Name)) { flagProc = flagProcDict[t.Name]; } else { flagProc = proto.GetType().GetMethod("GetFlag"); flagProcDict[t.Name] = flagProc; } if (null == flagProc) { throw new Exception("GetFlag method not found in Type : " + proto.GetType().Name); } return((byte)flagProc.Invoke(null, null)); }
private void HandleOperationError(UInt16 appCode, UInt16 funcCode, Operation op, IProtocolHead errorPh) { if (PackageUtils.isErrorType(funcCode) && null != op) { IProtocolHead ph = op.Ph; if (null == ph) { return; } int errorId = PackageUtils.GetProtocolID(appCode, op.FuncCode); if (!oprationErrorHandlerMap.ContainsKey(errorId)) { // Logger.LogWarning("Can't find error handler for " + AppFnMapping.MAPPING[funcCode].Name); return; } Delegate func = oprationErrorHandlerMap[errorId]; if (func != null) { ((OperateErrorHandler)func)(this, ph, errorPh); } } }
static async Task <int> MainAsync(IConfigurationRoot configuration) { string logLevel = configuration.GetValue($"{Logger.RuntimeLogLevelEnvKey}", "info"); Logger.SetLogLevel(logLevel); // Set the LoggerFactory used by the Routing code. if (configuration.GetValue("EnableRoutingLogging", false)) { Routing.LoggerFactory = Logger.Factory; } ILogger logger = Logger.Factory.CreateLogger("EdgeHub"); EdgeHubCertificates certificates = await EdgeHubCertificates.LoadAsync(configuration, logger); bool clientCertAuthEnabled = configuration.GetValue(Constants.ConfigKey.EdgeHubClientCertAuthEnabled, false); string sslProtocolsConfig = configuration.GetValue(Constants.ConfigKey.SslProtocols, string.Empty); SslProtocols sslProtocols = SslProtocolsHelper.Parse(sslProtocolsConfig, DefaultSslProtocols, logger); logger.LogInformation($"Enabling SSL protocols: {sslProtocols.Print()}"); IDependencyManager dependencyManager = new DependencyManager(configuration, certificates.ServerCertificate, certificates.TrustBundle, sslProtocols); Hosting hosting = Hosting.Initialize(configuration, certificates.ServerCertificate, dependencyManager, clientCertAuthEnabled, sslProtocols); IContainer container = hosting.Container; logger.LogInformation("Initializing Edge Hub"); LogLogo(logger); LogVersionInfo(logger); logger.LogInformation($"OptimizeForPerformance={configuration.GetValue("OptimizeForPerformance", true)}"); logger.LogInformation($"MessageAckTimeoutSecs={configuration.GetValue("MessageAckTimeoutSecs", 30)}"); logger.LogInformation("Loaded server certificate with expiration date of {0}", certificates.ServerCertificate.NotAfter.ToString("o")); var metricsProvider = container.Resolve <IMetricsProvider>(); Metrics.InitWithAspNet(metricsProvider, logger); // Note this requires App.UseMetricServer() to be called in Startup.cs // Init V0 Metrics MetricsV0.BuildMetricsCollector(configuration); // EdgeHub and CloudConnectionProvider have a circular dependency. So need to Bind the EdgeHub to the CloudConnectionProvider. IEdgeHub edgeHub = await container.Resolve <Task <IEdgeHub> >(); ICloudConnectionProvider cloudConnectionProvider = await container.Resolve <Task <ICloudConnectionProvider> >(); cloudConnectionProvider.BindEdgeHub(edgeHub); // EdgeHub cloud proxy and DeviceConnectivityManager have a circular dependency, // so the cloud proxy has to be set on the DeviceConnectivityManager after both have been initialized. var deviceConnectivityManager = container.Resolve <IDeviceConnectivityManager>(); IConnectionManager connectionManager = await container.Resolve <Task <IConnectionManager> >(); (deviceConnectivityManager as DeviceConnectivityManager)?.SetConnectionManager(connectionManager); // Register EdgeHub credentials var edgeHubCredentials = container.ResolveNamed <IClientCredentials>("EdgeHubCredentials"); ICredentialsCache credentialsCache = await container.Resolve <Task <ICredentialsCache> >(); await credentialsCache.Add(edgeHubCredentials); // Initializing configuration logger.LogInformation("Initializing configuration"); IConfigSource configSource = await container.Resolve <Task <IConfigSource> >(); ConfigUpdater configUpdater = await container.Resolve <Task <ConfigUpdater> >(); await configUpdater.Init(configSource); if (!Enum.TryParse(configuration.GetValue("AuthenticationMode", string.Empty), true, out AuthenticationMode authenticationMode) || authenticationMode != AuthenticationMode.Cloud) { ConnectionReauthenticator connectionReauthenticator = await container.Resolve <Task <ConnectionReauthenticator> >(); connectionReauthenticator.Init(); } TimeSpan shutdownWaitPeriod = TimeSpan.FromSeconds(configuration.GetValue("ShutdownWaitPeriod", DefaultShutdownWaitPeriod)); (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(shutdownWaitPeriod, logger); using (IProtocolHead protocolHead = await GetEdgeHubProtocolHeadAsync(logger, configuration, container, hosting)) using (var renewal = new CertificateRenewal(certificates, logger)) { await protocolHead.StartAsync(); await Task.WhenAny(cts.Token.WhenCanceled(), renewal.Token.WhenCanceled()); logger.LogInformation("Stopping the protocol heads..."); await protocolHead.CloseAsync(CancellationToken.None); logger.LogInformation("Protocol heads stopped."); await CloseDbStoreProviderAsync(container); } completed.Set(); handler.ForEach(h => GC.KeepAlive(h)); logger.LogInformation("Shutdown complete."); return(0); }
public ProtocolHeadFixture() { this.ProtocolHead = InternalProtocolHeadFixture.Instance.ProtocolHead; }
async Task StartProtocolHead() { const int ConnectionPoolSize = 10; string certificateValue = await SecretsHelper.GetSecret("IotHubMqttHeadCert"); byte[] cert = Convert.FromBase64String(certificateValue); var certificate = new X509Certificate2(cert); string edgeDeviceConnectionString = await SecretsHelper.GetSecretFromConfigKey("edgeCapableDeviceConnStrKey"); // TODO - After IoTHub supports MQTT, remove this and move to using MQTT for upstream connections await ConnectToIotHub(edgeDeviceConnectionString); string edgeHubConnectionString = $"{edgeDeviceConnectionString};ModuleId=$edgeHub"; Client.IotHubConnectionStringBuilder iotHubConnectionStringBuilder = Client.IotHubConnectionStringBuilder.Create(edgeHubConnectionString); var topics = new MessageAddressConversionConfiguration(this.inboundTemplates, this.outboundTemplates); var builder = new ContainerBuilder(); builder.RegisterModule(new LoggingModule()); var mqttSettingsConfiguration = new Mock <IConfiguration>(); mqttSettingsConfiguration.Setup(c => c.GetSection(It.IsAny <string>())).Returns(Mock.Of <IConfigurationSection>(s => s.Value == null)); builder.RegisterBuildCallback( c => { // set up loggers for dotnetty var loggerFactory = c.Resolve <ILoggerFactory>(); InternalLoggerFactory.DefaultFactory = loggerFactory; var eventListener = new LoggerEventListener(loggerFactory.CreateLogger("ProtocolGateway")); eventListener.EnableEvents(CommonEventSource.Log, EventLevel.Informational); }); var versionInfo = new VersionInfo("v1", "b1", "c1"); var storeAndForwardConfiguration = new StoreAndForwardConfiguration(-1); builder.RegisterModule(new CommonModule(string.Empty, iotHubConnectionStringBuilder.HostName, iotHubConnectionStringBuilder.DeviceId)); builder.RegisterModule( new RoutingModule( iotHubConnectionStringBuilder.HostName, iotHubConnectionStringBuilder.DeviceId, iotHubConnectionStringBuilder.ModuleId, Option.Some(edgeHubConnectionString), this.routes, false, false, storeAndForwardConfiguration, string.Empty, ConnectionPoolSize, false, versionInfo, Option.Some(UpstreamProtocol.Amqp), true, TimeSpan.FromSeconds(5), 101, false, Option.None <string>(), Option.None <string>()) ); builder.RegisterModule(new HttpModule()); builder.RegisterModule(new MqttModule(mqttSettingsConfiguration.Object, topics, certificate, false, false, string.Empty, false)); builder.RegisterModule(new AmqpModule("amqps", 5671, certificate, iotHubConnectionStringBuilder.HostName)); this.container = builder.Build(); IConfigSource configSource = await this.container.Resolve <Task <IConfigSource> >(); ConfigUpdater configUpdater = await this.container.Resolve <Task <ConfigUpdater> >(); await configUpdater.Init(configSource); ILogger logger = this.container.Resolve <ILoggerFactory>().CreateLogger("EdgeHub"); MqttProtocolHead mqttProtocolHead = await this.container.Resolve <Task <MqttProtocolHead> >(); AmqpProtocolHead amqpProtocolHead = await this.container.Resolve <Task <AmqpProtocolHead> >(); this.protocolHead = new EdgeHubProtocolHead(new List <IProtocolHead> { mqttProtocolHead, amqpProtocolHead }, logger); await this.protocolHead.StartAsync(); }
static async Task <int> MainAsync(IConfigurationRoot configuration) { string logLevel = configuration.GetValue($"{Logger.RuntimeLogLevelEnvKey}", "info"); Logger.SetLogLevel(logLevel); // Set the LoggerFactory used by the Routing code. if (configuration.GetValue("EnableRoutingLogging", false)) { Routing.LoggerFactory = Logger.Factory; } EdgeHubCertificates certificates = await EdgeHubCertificates.LoadAsync(configuration); bool clientCertAuthEnabled = configuration.GetValue(Constants.ConfigKey.EdgeHubClientCertAuthEnabled, false); Hosting hosting = Hosting.Initialize(configuration, certificates.ServerCertificate, new DependencyManager(configuration, certificates.ServerCertificate, certificates.TrustBundle), clientCertAuthEnabled); IContainer container = hosting.Container; ILogger logger = container.Resolve <ILoggerFactory>().CreateLogger("EdgeHub"); logger.LogInformation("Initializing Edge Hub"); LogLogo(logger); LogVersionInfo(logger); logger.LogInformation("Loaded server certificate with expiration date of {0}", certificates.ServerCertificate.NotAfter.ToString("o")); // EdgeHub and CloudConnectionProvider have a circular dependency. So need to Bind the EdgeHub to the CloudConnectionProvider. IEdgeHub edgeHub = await container.Resolve <Task <IEdgeHub> >(); ICloudConnectionProvider cloudConnectionProvider = await container.Resolve <Task <ICloudConnectionProvider> >(); cloudConnectionProvider.BindEdgeHub(edgeHub); // EdgeHub cloud proxy and DeviceConnectivityManager have a circular dependency, // so the cloud proxy has to be set on the DeviceConnectivityManager after both have been initialized. var deviceConnectivityManager = container.Resolve <IDeviceConnectivityManager>(); IConnectionManager connectionManager = await container.Resolve <Task <IConnectionManager> >(); (deviceConnectivityManager as DeviceConnectivityManager)?.SetConnectionManager(connectionManager); // Register EdgeHub credentials var edgeHubCredentials = container.ResolveNamed <IClientCredentials>("EdgeHubCredentials"); ICredentialsCache credentialsCache = await container.Resolve <Task <ICredentialsCache> >(); await credentialsCache.Add(edgeHubCredentials); // Initializing configuration logger.LogInformation("Initializing configuration"); IConfigSource configSource = await container.Resolve <Task <IConfigSource> >(); ConfigUpdater configUpdater = await container.Resolve <Task <ConfigUpdater> >(); await configUpdater.Init(configSource); if (!Enum.TryParse(configuration.GetValue("AuthenticationMode", string.Empty), true, out AuthenticationMode authenticationMode) || authenticationMode != AuthenticationMode.Cloud) { ConnectionReauthenticator connectionReauthenticator = await container.Resolve <Task <ConnectionReauthenticator> >(); connectionReauthenticator.Init(); } (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(ShutdownWaitPeriod, logger); Metrics.BuildMetricsCollector(configuration); using (IProtocolHead protocolHead = await GetEdgeHubProtocolHeadAsync(logger, configuration, container, hosting)) using (var renewal = new CertificateRenewal(certificates, logger)) { await protocolHead.StartAsync(); await Task.WhenAny(cts.Token.WhenCanceled(), renewal.Token.WhenCanceled()); logger.LogInformation("Stopping the protocol heads..."); await Task.WhenAny(protocolHead.CloseAsync(CancellationToken.None), Task.Delay(TimeSpan.FromSeconds(10), CancellationToken.None)); logger.LogInformation("Protocol heads stopped."); } completed.Set(); handler.ForEach(h => GC.KeepAlive(h)); logger.LogInformation("Shutdown complete."); return(0); }
void OnPlayerMove(SockRouter router, IProtocolHead ph) { Move data = ph as Move; SendEvent(new PlayerActionEvent(PlayerActionEvent.Move, data)); }
void ShowNewMessage(SockMsgRouter router, IProtocolHead ph) { Debug.Log("get message: " + (ph as GameProtos.common.UserMessage).Content); }
public void FakeRecieveSockMsg(IProtocolHead ph, int funcCode, int channel = 0) { routers [channel].FakeRecieveMsg(ph, funcCode); }
static async Task <int> MainAsync(IConfigurationRoot configuration) { string logLevel = configuration.GetValue($"{Logger.RuntimeLogLevelEnvKey}", "info"); Logger.SetLogLevel(logLevel); // Set the LoggerFactory used by the Routing code. if (configuration.GetValue("EnableRoutingLogging", false)) { Routing.LoggerFactory = Logger.Factory; } ILogger logger = Logger.Factory.CreateLogger("EdgeHub"); EdgeHubCertificates certificates = await EdgeHubCertificates.LoadAsync(configuration, logger); bool clientCertAuthEnabled = configuration.GetValue(Constants.ConfigKey.EdgeHubClientCertAuthEnabled, false); string sslProtocolsConfig = configuration.GetValue(Constants.ConfigKey.SslProtocols, string.Empty); SslProtocols sslProtocols = SslProtocolsHelper.Parse(sslProtocolsConfig, DefaultSslProtocols, logger); logger.LogInformation($"Enabling SSL protocols: {sslProtocols.Print()}"); IDependencyManager dependencyManager = new DependencyManager(configuration, certificates.ServerCertificate, certificates.TrustBundle, certificates.ManifestTrustBundle, sslProtocols); Hosting hosting = Hosting.Initialize(configuration, certificates.ServerCertificate, dependencyManager, clientCertAuthEnabled, sslProtocols); IContainer container = hosting.Container; logger.LogInformation("Initializing Edge Hub"); LogLogo(logger); LogVersionInfo(logger); logger.LogInformation($"OptimizeForPerformance={configuration.GetValue("OptimizeForPerformance", true)}"); logger.LogInformation($"MessageAckTimeoutSecs={configuration.GetValue("MessageAckTimeoutSecs", 30)}"); logger.LogInformation("Loaded server certificate with expiration date of {0}", certificates.ServerCertificate.NotAfter.ToString("o")); var metricsProvider = container.Resolve <IMetricsProvider>(); Metrics.InitWithAspNet(metricsProvider, logger); // Note this requires App.UseMetricServer() to be called in Startup.cs // EdgeHub and CloudConnectionProvider have a circular dependency. So need to Bind the EdgeHub to the CloudConnectionProvider. IEdgeHub edgeHub = await container.Resolve <Task <IEdgeHub> >(); ICloudConnectionProvider cloudConnectionProvider = await container.Resolve <Task <ICloudConnectionProvider> >(); cloudConnectionProvider.BindEdgeHub(edgeHub); // EdgeHub cloud proxy and DeviceConnectivityManager have a circular dependency, // so the cloud proxy has to be set on the DeviceConnectivityManager after both have been initialized. var deviceConnectivityManager = container.Resolve <IDeviceConnectivityManager>(); IConnectionManager connectionManager = await container.Resolve <Task <IConnectionManager> >(); (deviceConnectivityManager as DeviceConnectivityManager)?.SetConnectionManager(connectionManager); // Register EdgeHub credentials var edgeHubCredentials = container.ResolveNamed <IClientCredentials>("EdgeHubCredentials"); ICredentialsCache credentialsCache = await container.Resolve <Task <ICredentialsCache> >(); await credentialsCache.Add(edgeHubCredentials); // Register EdgeHub indentity in device scopes cache. // When we connect upstream, we verify that identity is in scope. // On a fresh start, we may not yet received the scopes from the upstream, so we need // to force add edgeHub in the cache so it is able to connect upstream. // Once we get the scopes from the upstream, this record is replaced. ServiceIdentity edgeHubIdentity = container.ResolveNamed <ServiceIdentity>("EdgeHubIdentity"); IServiceIdentityHierarchy identityScopes = container.Resolve <IServiceIdentityHierarchy>(); await identityScopes.InsertOrUpdate(edgeHubIdentity); // Initializing configuration logger.LogInformation("Initializing configuration"); IConfigSource configSource = await container.Resolve <Task <IConfigSource> >(); ConfigUpdater configUpdater = await container.Resolve <Task <ConfigUpdater> >(); ExperimentalFeatures experimentalFeatures = CreateExperimentalFeatures(configuration); var configUpdaterStartupFailed = new TaskCompletionSource <bool>(); var configDownloadTask = configUpdater.Init(configSource); _ = configDownloadTask.ContinueWith( _ => configUpdaterStartupFailed.SetResult(false), TaskContinuationOptions.OnlyOnFaulted); if (!Enum.TryParse(configuration.GetValue("AuthenticationMode", string.Empty), true, out AuthenticationMode authenticationMode) || authenticationMode != AuthenticationMode.Cloud) { ConnectionReauthenticator connectionReauthenticator = await container.Resolve <Task <ConnectionReauthenticator> >(); connectionReauthenticator.Init(); } TimeSpan shutdownWaitPeriod = TimeSpan.FromSeconds(configuration.GetValue("ShutdownWaitPeriod", DefaultShutdownWaitPeriod)); (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(shutdownWaitPeriod, logger); using (IProtocolHead mqttBrokerProtocolHead = await GetMqttBrokerProtocolHeadAsync(experimentalFeatures, container)) using (IProtocolHead edgeHubProtocolHead = await GetEdgeHubProtocolHeadAsync(logger, configuration, experimentalFeatures, container, hosting)) using (var renewal = new CertificateRenewal(certificates, logger)) { try { await Task.WhenAll(mqttBrokerProtocolHead.StartAsync(), configDownloadTask); await edgeHubProtocolHead.StartAsync(); await Task.WhenAny(cts.Token.WhenCanceled(), renewal.Token.WhenCanceled(), configUpdaterStartupFailed.Task); } catch (Exception ex) { logger.LogError($"Error starting protocol heads: {ex.Message}"); } logger.LogInformation("Stopping the protocol heads..."); await Task.WhenAll(mqttBrokerProtocolHead.CloseAsync(CancellationToken.None), edgeHubProtocolHead.CloseAsync(CancellationToken.None)); logger.LogInformation("Protocol heads stopped."); await CloseDbStoreProviderAsync(container); } completed.Set(); handler.ForEach(h => GC.KeepAlive(h)); logger.LogInformation("Shutdown complete."); return(0); }