INFRA-3467 : Private Houston Incidents (#445)

* INFRA-3467 : Private Houston Incidents

* INFRA-3627 : Minor self review

* INFRA-3627 : PR Review changes

INFRA-3627 : Minor changes

INFRA-3627 : UT fix

INFRA-3637 : Message changes

INFRA-3627 : Minor changes

INFRA-3627 : Constant fix

INFRA-3627 : Do not post SLA breach in public channels for private incidents
This commit is contained in:
Vijay Joshi
2024-08-08 19:20:04 +05:30
committed by GitHub
parent 9d5c03b8da
commit 804be01c2f
36 changed files with 597 additions and 29 deletions

View File

@@ -6,12 +6,17 @@ import (
"github.com/slack-go/slack/socketmode"
"go.uber.org/zap"
"houston/appcontext"
"houston/common/metrics"
"houston/common/util"
"houston/internal/processor/action/view"
"houston/logger"
"houston/model/incident"
"houston/model/team"
"houston/repository/severity"
incidentStatusService "houston/service/incidentStatus"
"houston/service/incidentUser"
incidentUserRequest "houston/service/request/incidentUser"
userService "houston/service/user"
)
type MemberJoinAction struct {
@@ -20,6 +25,8 @@ type MemberJoinAction struct {
teamService *team.Repository
severityService *severity.Repository
incidentStatusService incidentStatusService.IncidentStatusService
userService userService.UserService
incidentUserService incidentUser.IncidentUserService
}
func NewMemberJoinAction(socketModeClient *socketmode.Client, incidentService *incident.Repository, teamService *team.Repository, severityService *severity.Repository) *MemberJoinAction {
@@ -29,11 +36,13 @@ func NewMemberJoinAction(socketModeClient *socketmode.Client, incidentService *i
teamService: teamService,
severityService: severityService,
incidentStatusService: appcontext.GetIncidentStatusService(),
userService: appcontext.GetUserService(),
incidentUserService: appcontext.GetIncidentUserService(),
}
}
func (mp *MemberJoinAction) PerformAction(memberJoinedChannelEvent *slackevents.MemberJoinedChannelEvent) {
logger.Info("processing member join action", zap.String("channel", memberJoinedChannelEvent.Channel))
logger.Info(fmt.Sprintf("processing member joined channel event: %v", memberJoinedChannelEvent))
incidentEntity, err := mp.incidentService.FindIncidentByChannelId(memberJoinedChannelEvent.Channel)
if err != nil {
@@ -46,6 +55,14 @@ func (mp *MemberJoinAction) PerformAction(memberJoinedChannelEvent *slackevents.
return
}
go func() {
err := mp.addIncidentUserMapping(incidentEntity.ID, memberJoinedChannelEvent.User)
if err != nil {
logger.Error(fmt.Sprintf("failed to add incident-user mapping"), zap.Error(err))
metrics.PublishHoustonFlowFailureMetrics(util.ADD_INCIDENT_USER_MAPPING, err.Error())
}
}()
teamEntity, err := mp.teamService.FindTeamById(incidentEntity.TeamId)
if err != nil {
logger.Error("error in fetching team", zap.String("channel", memberJoinedChannelEvent.Channel),
@@ -98,3 +115,22 @@ func (mp *MemberJoinAction) PerformAction(memberJoinedChannelEvent *slackevents.
logger.Error("post response failed", zap.Error(err))
}
}
func (mp *MemberJoinAction) addIncidentUserMapping(incidentId uint, slackUserId string) error {
user, err := mp.userService.GetHoustonUserBySlackUserId(slackUserId)
if err != nil {
logger.Error(fmt.Sprintf("failed to get user with id %s : %v", slackUserId, err))
return err
} else if user == nil {
errMsg := fmt.Sprintf("user with id %s not found", slackUserId)
logger.Error(errMsg)
return fmt.Errorf(errMsg)
}
return mp.incidentUserService.AddIncidentUser(
incidentUserRequest.AddIncidentUserRequest{
IncidentID: incidentId,
UserID: user.ID,
},
)
}

View File

@@ -0,0 +1,55 @@
package action
import (
"fmt"
"github.com/slack-go/slack/slackevents"
"houston/appcontext"
"houston/logger"
incidentServiceV2 "houston/service/incident/impl"
"houston/service/incidentUser"
userService "houston/service/user"
)
type MemberLeftChannelAction struct {
incidentService incidentServiceV2.IncidentServiceV2
userService userService.UserService
incidentUserService incidentUser.IncidentUserService
}
const mlcaLogTag = "[member-left-channel-action]"
func NewMemberLeftChannelAction(incidentService incidentServiceV2.IncidentServiceV2, userService userService.UserService) *MemberLeftChannelAction {
return &MemberLeftChannelAction{
incidentService: incidentService,
userService: userService,
incidentUserService: appcontext.GetIncidentUserService(),
}
}
func (mlca *MemberLeftChannelAction) PerformAction(memberLeftChannelEvent *slackevents.MemberLeftChannelEvent) error {
logger.Info(fmt.Sprintf("%s processing member left channel event: %v", mlcaLogTag, memberLeftChannelEvent))
incidentData, err := mlca.incidentService.GetIncidentByChannelID(memberLeftChannelEvent.Channel)
if err != nil {
errMsg := fmt.Sprintf("%s error in searching incident %v", mlcaLogTag, err)
logger.Error(errMsg)
return fmt.Errorf(errMsg)
} else if incidentData == nil {
errMsg := fmt.Sprintf("%s incident not found", mlcaLogTag)
logger.Info(errMsg)
return fmt.Errorf(errMsg)
}
user, err := mlca.userService.GetHoustonUserBySlackUserId(memberLeftChannelEvent.User)
if err != nil {
errMsg := fmt.Sprintf("%s failed to get user with id %s : %v", mlcaLogTag, memberLeftChannelEvent.User, err)
logger.Error(errMsg)
return fmt.Errorf(errMsg)
} else if user == nil {
errMsg := fmt.Sprintf("%s user with id %s not found", mlcaLogTag, memberLeftChannelEvent.User)
logger.Info(errMsg)
return fmt.Errorf(errMsg)
}
return mlca.incidentUserService.RemoveIncidentUser(incidentData.ID, user.ID)
}

View File

@@ -4,12 +4,15 @@ import (
"fmt"
"github.com/slack-go/slack/slackevents"
"github.com/slack-go/slack/socketmode"
"houston/common/metrics"
"houston/internal/processor/action"
"houston/logger"
"houston/model/incident"
"houston/model/team"
"houston/model/user"
"houston/repository/severity"
incidentServiceV2 "houston/service/incident/impl"
userService "houston/service/user"
)
type eventsApiEventProcessor interface {
@@ -64,3 +67,33 @@ func (ucep *UserChangeEventProcessor) ProcessCommand(event slackevents.EventsAPI
var payload interface{}
ucep.socketModeClient.Ack(*request, payload)
}
type MemberLeftChannelCallbackEventProcessor struct {
socketModeClient *socketmode.Client
memberLeftChannelAction *action.MemberLeftChannelAction
}
func NewMemberLeftChannelCallbackEventProcessor(socketModeClient *socketmode.Client, incidentService incidentServiceV2.IncidentServiceV2, userService userService.UserService) *MemberLeftChannelCallbackEventProcessor {
return &MemberLeftChannelCallbackEventProcessor{
socketModeClient: socketModeClient,
memberLeftChannelAction: action.NewMemberLeftChannelAction(incidentService, userService),
}
}
func (mlcc *MemberLeftChannelCallbackEventProcessor) ProcessCommand(event *slackevents.MemberLeftChannelEvent, request *socketmode.Request) {
defer func() {
if r := recover(); r != nil {
logger.Error(fmt.Sprintf("[MLCC] Exception occurred: %v", r.(error)))
}
}()
err := mlcc.memberLeftChannelAction.PerformAction(event)
if err != nil {
logger.Error(fmt.Sprintf("failed to perform action: %v", err))
metrics.PublishHoustonFlowFailureMetrics(FLOW_NAME, err.Error())
}
var payload interface{}
mlcc.socketModeClient.Ack(*request, payload)
}
const FLOW_NAME = "REMOVE_INCIDENT_USER_MAPPING"