Example #1
0
        public static async Task <IActionResult> Read(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "host/{ip}")]
            HttpRequest req, string ip, [DurableClient] IDurableEntityClient client, ILogger logger)
        {
            try
            {
                IPAddress.Parse(ip);
            }
            catch
            {
                return(new BadRequestResult());
            }

            var entity = await client.ReadEntityStateAsync <HostEntity>(HostEntity.Id(ip));

            if (!entity.EntityExists)
            {
                return(new NotFoundResult());
            }

            return(new OkObjectResult(new
            {
                uptime = entity.EntityState.DnsUptime * 100m + "%", ipAddress = entity.EntityState.IpAddress,
                monitoringSince = entity.EntityState.MonitoringSince, ARecords = entity.EntityState.ipv4Support,
                isRecursive = true, isHandshake = (bool?)null
            }));
        }
Example #2
0
        public static async Task <IActionResult> Create(
            [HttpTrigger(AuthorizationLevel.Anonymous, "put", Route = "host/{ip}")]
            HttpRequest req,
            string ip,
            [DurableClient] IDurableEntityClient client,
            ILogger log)
        {
            try
            {
                IPAddress.Parse(ip);
            }
            catch
            {
                return(new BadRequestObjectResult(new { error = "Invalid ip address" }));
            }

            log.LogInformation("Adding {ipAddress} to bucket", ip);

            await client.SignalEntityAsync <IHostEntity>(HostEntity.Id(ip), entity => entity.SetIp(ip));

            await client.SignalEntityAsync <IHostEntity>(HostEntity.Id(ip),
                                                         entity => entity.CheckUp());

            return(new OkResult());
        }
Example #3
0
 private static void AddTo(List <object> output, HostEntity state)
 {
     output.Add(new
     {
         state.IpAddress,
         state.DnsUptime,
         state.ipv4Support,
         state.ipv6Support,
     });
 }
Example #4
0
        public static async Task <bool> Run([OrchestrationTrigger] IDurableOrchestrationContext context, ILogger logger)
        {
            var hostId = context.GetInput <EntityId>();

            logger = context.CreateReplaySafeLogger(logger);

            var state = await context.CallActivityAsync <EntityStateResponse <HostEntity> >(nameof(GetHostState), hostId);

            if (!state.EntityExists)
            {
                logger.LogError("Attempted to start watch dog for a non-existing host entity: {hostId}", hostId);
                throw new Exception("Failed to start watch dog for non-existing entity");
            }

            if (context.InstanceId != HostEntity.calculateHash(state.EntityState.IpAddress))
            {
                throw new Exception("violent suicide committed on watchdog!");
            }

            if (state.EntityState.ipv4Support || state.EntityState.ipv6Support)
            {
                context.SignalEntity(HostList.Id, HostList.AddHost, hostId);
                logger.LogInformation("Adding {hostId} to active hosts", hostId);
            }
            else
            {
                context.SignalEntity(HostList.Id, HostList.RemoveHost, hostId);
                logger.LogInformation("Removing {hostId} from active hosts", hostId);
            }

            var nextCheck = state.EntityState.DnsUptime switch
            {
                { } v when v < 0.2m => TimeSpan.FromDays(1),
                { } v when v >= 0.2m && v < 0.75m => TimeSpan.FromHours(12 + new Random().Next(-1, 1)),
                { } v when v >= 0.75m => TimeSpan.FromMinutes(60 + new Random().Next(-5, 5)),
                _ => TimeSpan.FromHours(1)
            };

#if DEBUG
            nextCheck = TimeSpan.FromMinutes(5);
#endif

            await context.CreateTimer(context.CurrentUtcDateTime + nextCheck, CancellationToken.None);

            var host = context.CreateEntityProxy <IHostEntity>(hostId);

            await host.CheckUp();

            context.ContinueAsNew(hostId);

            return(true);
        }
    }