Files
houston-be/cmd/app/handler/incident_handler.go
Vijay Joshi a8a0d44da9 INFRA-3098 : Auto escalate refactor (#409)
* INFRA-3098 : Auto escalate refactor

* INFRA-3098 : Delete old cron code

* INFRA-2887 : File and api name changes

* INFRA-2887 : Code review comments
2024-03-27 19:06:22 +05:30

240 lines
8.9 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) HandleCreateIncident(c *gin.Context) {
var createIncidentRequest incident.CreateIncidentRequestV2
if err := c.ShouldBindJSON(&createIncidentRequest); err != nil {
c.JSON(http.StatusInternalServerError, err)
return
}
if err := utils.ValidateCreateIncidentRequestV2(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.service.CreateIncident(createIncidentRequest, "API", "")
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) 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) 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))
}