public async Task FunctionalEndToEndCreateTest()
        {
            var batchService = new BatchService(ConfigurationHelper.GetConfiguration());

            Assert.IsTrue(string.IsNullOrWhiteSpace(batchService.HasValidConfiguration()));

            var controller = ControllerExtensions.NewCloudController();

            // Create a fully functional json body
            var jsonBody = new CreateApiJsonBody
            {
                TurnPoolId      = "TEST_TURN",
                RenderingPoolId = "TEST_RENDERING"
            };

            var result = await controller.Post((JObject)JToken.FromObject(jsonBody));

            Assert.IsInstanceOfType(result, typeof(HttpResponseMessage));

            var pool = batchService.GetPoolsInBatch();

            Assert.IsNotNull(pool.FirstOrDefault(p => p.Id == jsonBody.TurnPoolId));
            Assert.IsNotNull(pool.FirstOrDefault(p => p.Id == jsonBody.RenderingPoolId));
        }
        public async Task <HttpResponseMessage> Post(
            [FromBody] JObject jsonBody)
        {
            if (jsonBody == null)
            {
                return(Request.CreateResponse(HttpStatusCode.BadRequest, ApiResultMessages.ErrorBodyIsEmpty));
            }

            var totalClients     = jsonBody["totalSessions"]?.ToObject <int>();
            var totalSlots       = jsonBody["totalSlots"]?.ToObject <int>();
            var serversList      = jsonBody["servers"]?.ToObject <JObject>();
            var connectedServers = new List <ConnectedServer>();

            if (serversList != null && serversList.HasValues)
            {
                foreach (var server in serversList)
                {
                    connectedServers.Add(server.Value.ToObject <ConnectedServer>());
                }
            }

            if (!totalClients.HasValue || !totalSlots.HasValue)
            {
                return(Request.CreateResponse(HttpStatusCode.BadRequest));
            }

            var deletePoolId = string.Empty;

            switch (this.batchService.GetAutoscalingStatus(totalClients.Value, connectedServers, out deletePoolId))
            {
            case AutoscalingStatus.NotEnabled:
            {
                return(Request.CreateResponse(HttpStatusCode.BadRequest, ApiResultMessages.WarningNoAutoscaling));
            }

            case AutoscalingStatus.UpscaleRenderingPool:
            {
                if (this.downscaleTimer != null && this.downscaleTimer.Enabled)
                {
                    // We are approaching capacity, stop any down scale timer
                    this.downscaleTimer.Stop();
                }

                var controller = new Cloud3DSTKController
                {
                    Request = new HttpRequestMessage()
                };

                controller.Request.Properties.Add(
                    HttpPropertyKeys.HttpConfigurationKey,
                    new HttpConfiguration());

                // Create a json body with a specific pool and job ID. These should be unique to avoid conflict.
                var json = new CreateApiJsonBody
                {
                    RenderingPoolId = Guid.NewGuid().ToString()
                };

                // Spin up a new Rendering Pool
                var result = await controller.Post((JObject)JToken.FromObject(json));

                break;
            }

            case AutoscalingStatus.DownscaleRenderingPool:
            {
                if (this.downscaleTimer != null && !this.downscaleTimer.Enabled)
                {
                    this.downscaleTimer.Elapsed += (sender, e) => this.DownscaleElapsedMethod(sender, e, totalClients.Value, connectedServers);

                    // Wait until the downscale threshold timout is met and delete the pool
                    this.downscaleTimer.Start();
                }

                break;
            }

            case AutoscalingStatus.OK:
            {
                if (this.downscaleTimer != null && this.downscaleTimer.Enabled)
                {
                    // We are in normal parameters, stop any down scale timer
                    this.downscaleTimer.Stop();
                }

                break;
            }
            }

            return(Request.CreateResponse(HttpStatusCode.OK));
        }