Files
houston-be/cmd/app/handler/incident_handler.go
Dhruv Joshi 5c46ee2406 INFRA-3635 | Dhruv | Adds auto incident status change to investigating flow (#455)
* INFRA-3635 | Dhruv | Adds auto incident status change to investigating flow

* INFRA-3635 | Dhruv | Reformats to remove too many changes visible

* INFRA-3635 | Dhruv | Adds initial tests

* INFRA-3635 | Dhruv | fix pr comments

* INFRA-3635 | Dhruv | Fix pr comments

* INFRA-3635 | Dhruv | removes unwanted file change

* INFRA-3635 | Dhruv | initial tests

* INFRA-3635 | Dhruv | updates tests
2024-09-12 16:37:27 +05:30

230 lines
8.4 KiB
Go

package handler
import (
"fmt"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"gorm.io/gorm"
"houston/common/metrics"
"houston/common/util"
stringUtils "houston/common/util/string"
"houston/logger"
incidentService "houston/service/incident/impl"
"houston/service/orchestration"
request "houston/service/request"
"houston/service/request/incident"
common "houston/service/response/common"
utils "houston/service/utils"
"net/http"
)
const (
logTag = "[incident_handler]"
)
type IncidentHandler struct {
gin *gin.Engine
db *gorm.DB
service *incidentService.IncidentServiceV2
orchestrator orchestration.IncidentOrchestrator
}
func NewIncidentHandler(
gin *gin.Engine,
db *gorm.DB,
incidentService *incidentService.IncidentServiceV2,
orchestrator orchestration.IncidentOrchestrator,
) *IncidentHandler {
return &IncidentHandler{
gin: gin,
db: db,
service: incidentService,
orchestrator: orchestrator,
}
}
func (handler *IncidentHandler) HandleCreateIncidentV3(c *gin.Context) {
var createIncidentRequest incident.CreateIncidentRequestV3
if err := c.ShouldBindJSON(&createIncidentRequest); err != nil {
c.JSON(http.StatusInternalServerError, err)
return
}
if err := utils.ValidateCreateIncidentRequestV3(createIncidentRequest); err != nil {
logger.Error(fmt.Sprintf("%s Received invalid request to create new incident", logTag), zap.Error(err))
c.JSON(http.StatusBadRequest, common.ErrorResponse(err, http.StatusBadRequest, nil))
return
}
incidentResponse, err := handler.orchestrator.CreateIncident(&createIncidentRequest, "")
if err != nil {
logger.Error(fmt.Sprintf("%s Failed to create incident", logTag), zap.Error(err))
metrics.PublishHoustonFlowFailureMetrics(incidentService.CREATE_INCIDENT, err.Error())
c.JSON(http.StatusInternalServerError, common.ErrorResponse(err, http.StatusInternalServerError, nil))
return
}
c.JSON(http.StatusOK, common.SuccessResponse(incidentResponse, http.StatusOK))
}
func (handler *IncidentHandler) HandleUpdateIncident(c *gin.Context) {
userEmail := c.GetHeader(util.UserEmailHeader)
var updateIncidentRequest request.UpdateIncidentRequest
if err := c.ShouldBindJSON(&updateIncidentRequest); err != nil {
c.JSON(http.StatusBadRequest, common.ErrorResponse(err, http.StatusBadRequest, nil))
return
}
if err := utils.ValidateUpdateIncidentRequest(updateIncidentRequest, userEmail); err != nil {
c.JSON(http.StatusBadRequest, common.ErrorResponse(err, http.StatusBadRequest, nil))
return
}
incidentServiceV2 := incidentService.NewIncidentServiceV2(handler.db)
result, err := incidentServiceV2.UpdateIncident(updateIncidentRequest, userEmail)
if err != nil {
logger.Error(fmt.Sprintf("%s Failed to update incident", logTag), zap.Error(err))
c.JSON(http.StatusBadRequest, common.ErrorResponse(err, http.StatusBadRequest, nil))
return
}
c.JSON(http.StatusOK, common.SuccessResponse(result, http.StatusOK))
}
func (handler *IncidentHandler) HandleResolveIncident(c *gin.Context) {
userEmail := c.GetHeader(util.UserEmailHeader)
var resolveIncidentRequest request.ResolveIncidentRequest
if err := c.ShouldBindJSON(&resolveIncidentRequest); err != nil {
c.JSON(http.StatusBadRequest, common.ErrorResponse(err, http.StatusBadRequest, nil))
return
}
if err := utils.ValidateResolveIncidentRequest(resolveIncidentRequest); err != nil {
c.JSON(http.StatusBadRequest, common.ErrorResponse(err, http.StatusBadRequest, nil))
return
}
err := handler.service.ResolveIncident(resolveIncidentRequest, userEmail)
if err != nil {
common.HandleErrorResponse(c, err)
return
}
c.JSON(http.StatusOK, common.SuccessResponse("Incident resolved successfully", http.StatusOK))
}
func (handler *IncidentHandler) HandleEscalateIncident(c *gin.Context) {
err := handler.service.EscalateIncidents()
if err != nil {
logger.Error(fmt.Sprintf("%s failed to escalate incidents", logTag), zap.Error(err))
metrics.PublishHoustonFlowFailureMetrics(incidentService.ESCALATE_INCIDENT, err.Error())
c.JSON(http.StatusInternalServerError, common.ErrorResponse(err, http.StatusInternalServerError, nil))
return
}
c.JSON(http.StatusOK, common.SuccessResponse("Incidents escalated successfully", http.StatusOK))
}
func (handler *IncidentHandler) HandleMoveIncidentsToInvestigating(c *gin.Context) {
err := handler.service.MoveIncidentsToInvestigating()
if err != nil {
logger.Error(fmt.Sprintf("%s failed to move incidents to investigating", logTag), zap.Error(err))
metrics.PublishHoustonFlowFailureMetrics(incidentService.MOVE_INCIDENT_TO_INVESTIGATING, err.Error())
c.JSON(http.StatusInternalServerError, common.ErrorResponse(err, http.StatusInternalServerError, nil))
return
}
c.JSON(http.StatusOK, common.SuccessResponse("Incidents moved to investigating successfully", http.StatusOK))
}
func (handler *IncidentHandler) HandleJiraLinking(c *gin.Context) {
var linkJiraRequest request.LinkJiraRequest
if err := c.ShouldBindJSON(&linkJiraRequest); err != nil {
c.JSON(http.StatusBadRequest, err)
return
}
if err := utils.ValidateLinkJiraRequest(linkJiraRequest); err != nil {
logger.Debug(fmt.Sprintf("%s invalid request to link JIRA reveived. %s", logTag, err.Error()))
c.JSON(http.StatusBadRequest, common.ErrorResponse(err, http.StatusBadGateway, nil))
return
}
err := handler.service.LinkJiraToIncident(linkJiraRequest.IncidentID, linkJiraRequest.User, linkJiraRequest.JiraLink)
if err != nil {
logger.Error(
fmt.Sprintf(
"%s failed to link JIRA to the incident %d", logTag, linkJiraRequest.IncidentID,
), zap.Error(err),
)
c.JSON(http.StatusInternalServerError, common.ErrorResponse(err, http.StatusBadRequest, nil))
return
}
c.JSON(http.StatusOK, common.SuccessResponse("JIRA link added successfully", http.StatusOK))
}
func (handler *IncidentHandler) HandleJiraUnLinking(c *gin.Context) {
var unlinkJiraRequest request.LinkJiraRequest
if err := c.ShouldBindJSON(&unlinkJiraRequest); err != nil {
c.JSON(http.StatusBadRequest, err)
return
}
if err := utils.ValidateLinkJiraRequest(unlinkJiraRequest); err != nil {
logger.Debug(fmt.Sprintf("%s invalid request to unLink Jira reveived. %s", logTag, err.Error()))
c.JSON(http.StatusBadRequest, common.ErrorResponse(err, http.StatusBadGateway, nil))
return
}
if err := handler.service.UnLinkJiraFromIncident(
unlinkJiraRequest.IncidentID, unlinkJiraRequest.User, unlinkJiraRequest.JiraLink,
); err != nil {
logger.Error(
fmt.Sprintf(
"%s failed to unlink jira from the incident %d", logTag, unlinkJiraRequest.IncidentID,
), zap.Error(err),
)
c.JSON(http.StatusInternalServerError, common.ErrorResponse(err, http.StatusNotFound, nil))
return
}
c.JSON(http.StatusOK, common.SuccessResponse("JIRA link removed successfully", http.StatusOK))
}
func (handler *IncidentHandler) HandleGetJiraStatuses(c *gin.Context) {
IncidentName := c.Query("incident_name")
pageSize, pageNumber, err :=
utils.ValidatePage(c.Query("page_size"), c.Query("page_number"))
if err != nil {
logger.Error("error in query parameters", zap.Int64("page_size", pageSize),
zap.Int64("page_number", pageNumber), zap.Error(err))
c.JSON(http.StatusBadRequest, common.ErrorResponse(err, http.StatusBadRequest, nil))
return
}
statuses, err := handler.service.GetJiraStatuses(IncidentName, pageNumber, pageSize)
if err != nil {
c.JSON(http.StatusInternalServerError, err)
}
c.JSON(http.StatusOK, statuses)
}
func (handler *IncidentHandler) HandleGetProductsOfUser(c *gin.Context) {
emailID := c.GetHeader(util.UserEmailHeader)
products, err := handler.orchestrator.GetProductsOfUserByEmailID(emailID)
if err != nil {
c.JSON(http.StatusInternalServerError, common.ErrorResponse(err, http.StatusInternalServerError, nil))
}
c.JSON(http.StatusOK, common.SuccessResponse(products.ToResponse(), http.StatusOK))
}
func (handler *IncidentHandler) HandleGetReportingAndResponderTeams(c *gin.Context) {
emailID := c.GetHeader(util.UserEmailHeader)
productIDsAsStringArray := c.QueryArray("productID")
productIDs, err := stringUtils.StringArrayToUintArray(productIDsAsStringArray)
if err != nil {
c.JSON(http.StatusBadRequest, common.ErrorResponse(err, http.StatusBadRequest, nil))
return
}
reportingAndResponderTeams, err := handler.orchestrator.GetReportingAndResponderTeams(emailID, productIDs)
if err != nil {
c.JSON(http.StatusInternalServerError, common.ErrorResponse(err, http.StatusInternalServerError, nil))
}
c.JSON(http.StatusOK, common.SuccessResponse(reportingAndResponderTeams.ToResponse(), http.StatusOK))
}