* 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
230 lines
8.4 KiB
Go
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))
|
|
}
|