public Task ConnectProducerFromOtherNode(NotifyProducerConnectionDetails notifyProducerConnectionDetails) { _producerHubRepository.AddProducer($"EXTERNAL-{Guid.NewGuid()}", new Model.Producers.Producer() { IsLocal = false, Component = notifyProducerConnectionDetails.Component, Id = notifyProducerConnectionDetails.Id, ProducerName = notifyProducerConnectionDetails.ProducerName, Product = notifyProducerConnectionDetails.Product, Tenant = notifyProducerConnectionDetails.Tenant, Topic = notifyProducerConnectionDetails.Topic }); return(Task.CompletedTask); }
public override Task OnConnectedAsync() { Producer producerToRegister; string clientConnectionId = Context.ConnectionId; var headers = Context.GetHttpContext().Request.Headers; // authorization tokens // TODO: Implement token validation string tenantToken = headers["x-andyx-tenant-authoriziation"]; string componentToken = headers["x-andyx-component-authoriziation"]; string tenant = headers["x-andyx-tenant"].ToString(); string product = headers["x-andyx-product"].ToString(); string component = headers["x-andyx-component"].ToString(); string topic = headers["x-andyx-topic"].ToString(); bool isPersistent = Boolean.Parse(headers["x-andyx-topic-is-persistent"]); string producerName = headers["x-andyx-producer"].ToString(); logger.LogInformation($"Producer '{producerName}' at {tenant}/{product}/{component}/{topic} requested connection"); //check if the producer is already connected var connectedTenant = tenantRepository.GetTenant(tenant); if (connectedTenant == null) { logger.LogInformation($"Producer '{producerName}' failed to connect, tenant '{tenant}' does not exists"); return(OnDisconnectedAsync(new Exception($"There is no tenant registered with this name '{tenant}'"))); } // check tenant token validation bool isTenantTokenValidated = tenantRepository.ValidateTenantToken(tenant, tenantToken); if (isTenantTokenValidated != true) { logger.LogInformation($"Producer '{producerName}' failed to connect, access is forbidden. Not authorized"); return(OnDisconnectedAsync(new Exception($"Producer '{producerName}' failed to connect, access is forbidden"))); } var connectedProduct = tenantRepository.GetProduct(tenant, product); if (connectedProduct == null) { if (connectedTenant.Settings.AllowProductCreation != true) { logger.LogInformation($"Producer '{producerName}' failed to connect, tenant '{tenant}' does not allow to create new product"); return(OnDisconnectedAsync(new Exception($"There is no product registered with this name '{product}'. Tenant '{tenant}' does not allow to create new product"))); } var productDetails = tenantFactory.CreateProduct(product); tenantRepository.AddProduct(tenant, product, productDetails); storageHubService.CreateProductAsync(tenant, productDetails); } else { storageHubService.UpdateProductAsync(tenant, connectedProduct); } var connectedComponent = tenantRepository.GetComponent(tenant, product, component); if (connectedComponent == null) { var componentDetails = tenantFactory.CreateComponent(component); tenantRepository.AddComponent(tenant, product, component, componentDetails); storageHubService.CreateComponentAsync(tenant, product, componentDetails); } else { // check component token validation bool isComponentTokenValidated = tenantRepository.ValidateComponentToken(tenant, product, component, componentToken, producerName, false); if (isComponentTokenValidated != true) { logger.LogInformation($"Producer '{producerName}' failed to connect, access is forbidden. Not authorized, check component token"); return(OnDisconnectedAsync(new Exception($"Producer '{producerName}' failed to connect, access is forbidden, check component token"))); } storageHubService.UpdateComponentAsync(tenant, product, connectedComponent); } var connectedTopic = tenantRepository.GetTopic(tenant, product, component, topic); if (connectedTopic == null) { // Check if the component allows to create a new topic. connectedComponent = tenantRepository.GetComponent(tenant, product, component); if (connectedComponent.Settings.AllowTopicCreation != true) { logger.LogInformation($"Component '{component}' does not allow to create a new topic {topic} at '{tenant}/{product}/{component}'. To allow creating update property AllowTopicCreation at component."); return(OnDisconnectedAsync(new Exception($"Component '{component}' does not allow to create a new topic {topic} at '{tenant}/{product}/{component}'. To allow creating update property AllowTopicCreation at component."))); } var topicDetails = tenantFactory.CreateTopic(topic, isPersistent); tenantRepository.AddTopic(tenant, product, component, topic, topicDetails); storageHubService.CreateTopicAsync(tenant, product, component, topicDetails); } else { storageHubService.UpdateTopicAsync(tenant, product, component, connectedTopic); } if (producerHubRepository.GetProducerByProducerName(tenant, product, component, topic, producerName).Equals(default(KeyValuePair <string, Producer>)) != true) { logger.LogWarning($"Producer '{producerName}' at {tenant}/{product}/{component}/{topic} is already connected"); return(OnDisconnectedAsync(new Exception($"There is a producer with name '{producerName}' at {tenant}/{product}/{component}/{topic} connected to this node"))); } producerToRegister = producerFactory.CreateProducer(tenant, product, component, topic, producerName); producerHubRepository.AddProducer(clientConnectionId, producerToRegister); storageHubService.ConnectProducerAsync(producerToRegister); Clients.Caller.ProducerConnected(new Model.Producers.Events.ProducerConnectedDetails() { Id = producerToRegister.Id, Tenant = tenant, Product = product, Component = component, Topic = topic, ProducerName = producerName }); logger.LogInformation($"Producer '{producerName}' at {tenant}/{product}/{component}/{topic} is connected"); return(base.OnConnectedAsync()); }