285 lines
9.5 KiB
Go
285 lines
9.5 KiB
Go
package monitoringService
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"github.com/spf13/viper"
|
|
"go.uber.org/zap"
|
|
"houston/common/util"
|
|
"houston/logger"
|
|
"houston/model"
|
|
"houston/pkg/rest"
|
|
service "houston/service/response"
|
|
"io"
|
|
"net/http"
|
|
"os"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
type ActionsImpl struct {
|
|
BaseURL string
|
|
Client rest.HttpRestClient
|
|
DefaultTimeout time.Duration
|
|
GetGrafanaImagesPath string
|
|
GetImpactedCustomersCSVPath string
|
|
}
|
|
|
|
func NewMonitoringServiceActionsImpl(client rest.HttpRestClient) *ActionsImpl {
|
|
return &ActionsImpl{
|
|
Client: client,
|
|
BaseURL: viper.GetString("MONITORING_SERVICE_BASEURL"),
|
|
DefaultTimeout: viper.GetDuration("DEFAULT_MONITORING_SERVICE_TIMEOUT"),
|
|
GetGrafanaImagesPath: viper.GetString("MONITORING_SERVICE_GET_GRAFANA_IMAGES_PATH"),
|
|
GetImpactedCustomersCSVPath: viper.GetString("MONITORING_SERVICE_GET_IMPACTED_CUSTOMERS_CSV_PATH"),
|
|
}
|
|
}
|
|
|
|
func (monitoringService *ActionsImpl) GetGrafanaImages(incidents []string, requestId string,
|
|
responseChannel chan service.MonitoringServiceClientResponse) {
|
|
|
|
fullURL := monitoringService.BaseURL + monitoringService.GetGrafanaImagesPath
|
|
requestHeaders := map[string]string{
|
|
"Content-Type": "application/json",
|
|
"CORRELATION_ID": requestId,
|
|
}
|
|
getGrafanaImagesRequestBody := model.GetGrafanaImagesRequest{
|
|
Incidents: incidents,
|
|
}
|
|
payload, err := json.Marshal(getGrafanaImagesRequestBody)
|
|
if err != nil {
|
|
logger.Error("Error while marshalling request body", zap.Error(err))
|
|
responseChannel <- service.MonitoringServiceClientResponse{Error: err}
|
|
return
|
|
}
|
|
|
|
response, err := monitoringService.Client.PostWithTimeout(fullURL, *bytes.NewBuffer(payload), requestHeaders,
|
|
monitoringService.DefaultTimeout, nil)
|
|
if err != nil {
|
|
logger.Error("Error while getting grafana images", zap.Error(err))
|
|
responseChannel <- service.MonitoringServiceClientResponse{Error: err}
|
|
return
|
|
}
|
|
|
|
if response.StatusCode == http.StatusNotFound {
|
|
logger.Info("No grafana images found for the given incident")
|
|
responseChannel <- service.MonitoringServiceClientResponse{}
|
|
return
|
|
}
|
|
|
|
if response.StatusCode != http.StatusOK {
|
|
logger.Error("Error while generating grafana images", zap.Error(err))
|
|
responseChannel <- service.MonitoringServiceClientResponse{Error: errors.New("error while generating grafana images")}
|
|
return
|
|
}
|
|
if response.Body == nil {
|
|
logger.Error("empty response body received from monitoring service")
|
|
responseChannel <- service.MonitoringServiceClientResponse{
|
|
Error: errors.New("empty response body received from monitoring service"),
|
|
}
|
|
return
|
|
}
|
|
directoryPath, err := processGrafanaImagesResponse(requestId, response)
|
|
if err != nil {
|
|
logger.Error("Error while processing grafana images response", zap.Error(err))
|
|
responseChannel <- service.MonitoringServiceClientResponse{Error: err}
|
|
return
|
|
}
|
|
responseChannel <- service.MonitoringServiceClientResponse{DirectoryPath: directoryPath}
|
|
return
|
|
}
|
|
|
|
func processGrafanaImagesResponse(requestId string, response *http.Response) (string, error) {
|
|
currentDirectory, _ := os.Getwd()
|
|
grafanaFilesDirectory := currentDirectory + "/krakatoa_files"
|
|
// Create files directory if not exists to store all grafana images
|
|
err := util.CheckAndCreateDirectory(grafanaFilesDirectory)
|
|
if err != nil {
|
|
logger.Error("Error while creating directory", zap.Error(err))
|
|
return "", err
|
|
}
|
|
|
|
destinationDirectoryPath := fmt.Sprintf("%v/%v", grafanaFilesDirectory, requestId)
|
|
err = util.CheckAndCreateDirectory(destinationDirectoryPath)
|
|
|
|
zipFileName := requestId + ".zip"
|
|
zipFilePath := fmt.Sprintf("%v/%v.zip", destinationDirectoryPath, requestId)
|
|
zipFile, err := util.CreateFileWithName(destinationDirectoryPath, zipFileName)
|
|
if err != nil {
|
|
logger.Error("Error while creating zip file", zap.Error(err))
|
|
return "", err
|
|
}
|
|
defer util.CloseFile(zipFile)
|
|
|
|
_, err = io.Copy(zipFile, response.Body)
|
|
if err != nil {
|
|
logger.Error("Error while copying zip file", zap.Error(err))
|
|
return "", err
|
|
}
|
|
err = unzipAndDeleteZipFile(zipFilePath, destinationDirectoryPath)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return destinationDirectoryPath, nil
|
|
}
|
|
|
|
func (monitoringService *ActionsImpl) GetImpactedCustomersCSV(incidents []string, requestId string,
|
|
responseChannel chan service.MonitoringServiceClientResponse) {
|
|
fullURL := monitoringService.BaseURL + monitoringService.GetImpactedCustomersCSVPath
|
|
requestHeaders := map[string]string{
|
|
"Content-Type": "application/json",
|
|
"CORRELATION_ID": requestId,
|
|
}
|
|
getImpactedCustomersCSVRequestBody := model.GetGrafanaImagesRequest{
|
|
Incidents: incidents,
|
|
}
|
|
payload, err := json.Marshal(getImpactedCustomersCSVRequestBody)
|
|
if err != nil {
|
|
logger.Error("Error while marshalling request body", zap.Error(err))
|
|
responseChannel <- service.MonitoringServiceClientResponse{Error: err}
|
|
return
|
|
}
|
|
|
|
response, err := monitoringService.Client.PostWithTimeout(fullURL, *bytes.NewBuffer(payload), requestHeaders,
|
|
monitoringService.DefaultTimeout, nil)
|
|
if response == nil {
|
|
logger.Error("no response received from monitoring service")
|
|
responseChannel <- service.MonitoringServiceClientResponse{
|
|
Error: errors.New("no response received from monitoring service"),
|
|
}
|
|
return
|
|
}
|
|
|
|
if response.StatusCode == http.StatusNotFound {
|
|
logger.Error("no configs found for the given incidents", zap.Error(err))
|
|
responseChannel <- service.MonitoringServiceClientResponse{}
|
|
}
|
|
|
|
if err != nil {
|
|
logger.Error("Error while getting impacted customers csv", zap.Error(err))
|
|
responseChannel <- service.MonitoringServiceClientResponse{Error: err}
|
|
return
|
|
}
|
|
if response.StatusCode != http.StatusOK {
|
|
logger.Error("error while generating impacted customers csv", zap.Error(err))
|
|
responseChannel <- service.MonitoringServiceClientResponse{Error: errors.New(
|
|
"error while generating impacted customers csv")}
|
|
return
|
|
}
|
|
if response.Body == nil {
|
|
logger.Error("empty response body received from monitoring service")
|
|
responseChannel <- service.MonitoringServiceClientResponse{
|
|
Error: errors.New("empty response body received from monitoring service"),
|
|
}
|
|
return
|
|
}
|
|
directoryPath, err := processImpactedCustomersCSV(requestId, response, monitoringService.Client)
|
|
if err != nil {
|
|
logger.Error("Error while processing impacted customers csv response", zap.Error(err))
|
|
responseChannel <- service.MonitoringServiceClientResponse{Error: err}
|
|
return
|
|
}
|
|
responseChannel <- service.MonitoringServiceClientResponse{
|
|
DirectoryPath: directoryPath,
|
|
}
|
|
return
|
|
}
|
|
|
|
func processImpactedCustomersCSV(requestId string, response *http.Response,
|
|
restClient rest.HttpRestClient) (string, error) {
|
|
currentDirectory, _ := os.Getwd()
|
|
grafanaFilesDirectory := currentDirectory + "/krakatoa_files"
|
|
|
|
responseBody, err := io.ReadAll(response.Body)
|
|
if err != nil {
|
|
logger.Error("Error while reading response body", zap.Error(err))
|
|
return "", err
|
|
}
|
|
var impactedCustomersCSVPaths []string
|
|
err = json.Unmarshal(responseBody, &impactedCustomersCSVPaths)
|
|
if err != nil {
|
|
logger.Error("error while unmarshalling response body", zap.Error(err))
|
|
return "", errors.New("error while unmarshalling response body")
|
|
}
|
|
|
|
err = util.CheckAndCreateDirectory(grafanaFilesDirectory)
|
|
if err != nil {
|
|
logger.Error("Error while creating directory", zap.Error(err))
|
|
return "", err
|
|
}
|
|
|
|
destinationDirectoryPath := fmt.Sprintf("%v/%v", grafanaFilesDirectory, requestId)
|
|
err = util.CheckAndCreateDirectory(destinationDirectoryPath)
|
|
if err != nil {
|
|
logger.Error("Error while creating directory", zap.Error(err))
|
|
return "", err
|
|
}
|
|
var waitGroup sync.WaitGroup
|
|
var downloadErrors []error
|
|
for _, impactedCustomersCSVPath := range impactedCustomersCSVPaths {
|
|
waitGroup.Add(1)
|
|
impactedCustomersCSVPath := impactedCustomersCSVPath
|
|
go func() {
|
|
err := downloadAndSaveCSVFile(restClient, impactedCustomersCSVPath, destinationDirectoryPath, &waitGroup)
|
|
if err != nil {
|
|
logger.Error("error while downloading and saving csv file", zap.Error(err))
|
|
downloadErrors = append(downloadErrors, err)
|
|
}
|
|
}()
|
|
}
|
|
waitGroup.Wait()
|
|
if len(downloadErrors) > 0 {
|
|
return "", errors.New("error while downloading and saving csv files")
|
|
} else {
|
|
return destinationDirectoryPath, nil
|
|
}
|
|
}
|
|
|
|
func downloadAndSaveCSVFile(restClient rest.HttpRestClient, fileURL string, destinationDirectoryPath string,
|
|
waitGroup *sync.WaitGroup) error {
|
|
defer waitGroup.Done()
|
|
response, err := restClient.Get(fileURL, nil, nil, true)
|
|
if err != nil {
|
|
logger.Error("Error while getting csv file", zap.Error(err))
|
|
return err
|
|
}
|
|
if response.StatusCode == http.StatusNotFound {
|
|
logger.Info("No CSV found for the given incident")
|
|
return nil
|
|
}
|
|
if response.StatusCode != http.StatusOK || response.Body == nil {
|
|
return errors.New("error while getting csv file")
|
|
}
|
|
fileName := strings.Trim(fmt.Sprintf("%v.csv", response.Header.Get("ETag")), "\"")
|
|
csvFile, err := util.CreateFileWithName(destinationDirectoryPath, fileName)
|
|
if err != nil {
|
|
logger.Error("Error while creating csv file", zap.Error(err))
|
|
return err
|
|
}
|
|
defer util.CloseFile(csvFile)
|
|
_, err = io.Copy(csvFile, response.Body)
|
|
if err != nil {
|
|
logger.Error("Error while copying csv file", zap.Error(err))
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func unzipAndDeleteZipFile(zipFilePath string, destinationDirectoryPath string) error {
|
|
err := util.UnzipFile(zipFilePath, destinationDirectoryPath)
|
|
if err != nil {
|
|
logger.Error("Error while unzipping file", zap.Error(err))
|
|
return err
|
|
}
|
|
|
|
err = util.DeleteFile(zipFilePath)
|
|
if err != nil {
|
|
logger.Error("Error while deleting file", zap.Error(err))
|
|
return err
|
|
}
|
|
return nil
|
|
}
|