Distributed-Storage-Project / Storage-Layer

0 stars 0 forks source link

Receive a response (array of rows) from /api/query (Storage layer) and return it to User #10

Closed HannahBagtasos closed 1 year ago

HannahBagtasos commented 1 year ago

Receive a response (array of rows) from /api/query (Storage layer) and return it to User.

/api/query (Storage layer) -> HTTP response with array of rows -> Compute layer (HomeController) -> User

You can use this example to make HTTP request - https://github.com/Distributed-Storage-Project/Compute-Layer/blob/task4/task4.cs

HannahBagtasos commented 1 year ago

Compute Controller (without KQL to SQL function for now)

using ComputeLayer.Models;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System.Text;

namespace ComputeLayer.Controllers
{
    [ApiController]
    [Route("/query")]
    public class HomeController : Controller
    {

        [HttpPost]
        public async Task<IActionResult> AddJSON([FromBody] Query query)
        {
            try
            {
                // From Task 1 : Convert Kusto query to SQL query
                string sqlQuery = ConvertToSql(query);

                // Make HTTP request to Storage Layer
                using (HttpClient httpClient = new HttpClient())
                {
                    var content = new StringContent(JsonConvert.SerializeObject(new { query = sqlQuery }), Encoding.UTF8, "application/json");
                    var response = await httpClient.PostAsync("https://localhost:7076/api/query", content);
                    if (response.IsSuccessStatusCode)
                    {
                        string responseData = await response.Content.ReadAsStringAsync();

                        var responseDto = JsonConvert.DeserializeObject<QueryResponseDto>(responseData);

                        if (responseDto.IsSuccess)
                        {
                            // Build response to return to user
                            var data = responseDto.Data;
                            responseDto = new QueryResponseDto
                            {
                                IsSuccess = true,
                                Data = data
                            };
                            Console.WriteLine("Response was successful.");
                            return Ok(responseDto);
                        }
                        else
                        {
                            // Handle query error
                            return StatusCode(StatusCodes.Status500InternalServerError, responseDto.Message);
                        }
                    }
                    else
                    {
                        // Handle HTTP error
                        return StatusCode(StatusCodes.Status500InternalServerError, "An error occurred while processing your request.");
                    }
                }
            }
            catch (Exception ex)
            {
                // Handle errors
                return StatusCode(StatusCodes.Status500InternalServerError, "An error occurred while processing your request.");
            }
        }

        private string ConvertToSql(Query query)
        {
            //string tableName = "<table-name>"; // replace with the actual table name
            //string sqlQuery = $"SELECT * FROM {tableName} " + query.query

            string sqlQuery = query.query
            .Replace("| where", "WHERE")
            .Replace("==", "=")
            .Replace("datetime(", "CAST(")
            .Replace(")", " AS DATETIME)");

            return sqlQuery;

            // return $"SELECT * FROM Logs;";

        }

    }
}

Storage Controller:

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Data.SqlClient;
using System.Collections.Generic;
using System.Data;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Collections;
using System.Text.Json.Nodes;
using Newtonsoft.Json.Linq;
using storageApplication.Repository;

namespace storageApplication.Controllers
{

    [Route("api/[controller]")]
    [ApiController]
    public class QueryController : ControllerBase
    {
        protected readonly IRepository _repository;

        public QueryController(IRepository repository)
        {
            _repository = repository;
        }

        [HttpPost(Name = "query")]
        public QueryResponse Query([FromBody] QueryRequest request)
        {
            string? query = request.query;
            if (string.IsNullOrEmpty(query) || !query.ToLower().StartsWith("select")) {
                return new QueryResponse(false, "Query is invalid!");
            }
            QueryResponse response = new QueryResponse();
            try
            {
                List<List<string>> data = _repository.query(query);
                response.data = data;
            }
            catch (Exception e)
            {
                response.isSucess = false;
                response.message = e.Message;
                Console.WriteLine(e.StackTrace);
            }

            return response;
        }

    }
}

Postman: Response has been received into storage controller and gives back the response when the query is not a "SELECT" format image

HannahBagtasos commented 1 year ago
   public HomeController()
        {
            HttpClientHandler clientHandler = new HttpClientHandler();
            clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };

            _httpClient = new HttpClient(clientHandler);
        }

        [HttpPost]
        public async Task<IActionResult> AddJSON([FromBody] Query query)
        {
            try
            {
                // Convert Kusto query to SQL
                string sqlQuery = KustoToSqlConverter.Convert(query);

                // Create a JSON payload with the parsed query
                var requestBody = JsonConvert.SerializeObject(new { query = sqlQuery });
                var content = new StringContent(requestBody, Encoding.UTF8, "application/json");

                // Call the QueryController endpoint and get the response
                var response = await _httpClient.PostAsync(_queryControllerUrl, content);
                var responseContent = await response.Content.ReadAsStringAsync();

                // Return the response content directly as an IActionResult
                return Content(responseContent, "application/json");
            }
            catch (Exception e)
            {
                return StatusCode(500, e.Message);
            }
        }
    }