func RegisterAttackDetail(session *xorm.Session, telePreMitigationId int64, attackDetail AttackDetail) (*db_models.AttackDetail, error) {
	newAttackDetail := db_models.AttackDetail{
		TelePreMitigationId: telePreMitigationId,
		VendorId:            attackDetail.VendorId,
		AttackId:            attackDetail.AttackId,
		AttackName:          attackDetail.AttackName,
		AttackSeverity:      ConvertAttackSeverityToString(attackDetail.AttackSeverity),
		StartTime:           attackDetail.StartTime,
		EndTime:             attackDetail.EndTime,
	}
	_, err := session.Insert(&newAttackDetail)
	if err != nil {
		log.Errorf("attack detail insert err: %s", err)
		return nil, err
	}
	return &newAttackDetail, nil
}
Registered attack detail
package models
import (
	"fmt"
	"reflect"
	"strconv"
	"strings"
	"github.com/go-xorm/xorm"
	"github.com/nttdots/go-dots/dots_common/messages"
	"github.com/nttdots/go-dots/dots_server/db_models"
	log "github.com/sirupsen/logrus"
	types "github.com/nttdots/go-dots/dots_common/types/data"
)
type PercentileType string
const (
	LOW_PERCENTILE_L  PercentileType = "LOW_PERCENTILE_L"
	MID_PERCENTILE_L  PercentileType = "MID_PERCENTILE_L"
	HIGH_PERCENTILE_L PercentileType = "HIGH_PERCENTILE_L"
	PEAK_L            PercentileType = "PEAK_L"
	LOW_PERCENTILE_C  PercentileType = "LOW_PERCENTILE_C"
	MID_PERCENTILE_C  PercentileType = "MID_PERCENTILE_C"
	HIGH_PERCENTILE_C PercentileType = "HIGH_PERCENTILE_C"
	PEAK_C            PercentileType = "PEAK_C"
)
func CreateTelemetryPreMitigation(customer *Customer, cuid string, cdid string, tmid int, dataRequest messages.PreOrOngoingMitigation, aliases types.Aliases, isPresent bool) error {
	engine, err := ConnectDB()
	if err != nil {
		log.Errorf("Database connect error: %s", err)
		return err
	}
	session := engine.NewSession()
	defer session.Close()
	err = session.Begin()
	if err != nil {
		return err
	}
	newPreMitigation, err := NewTelemetryPreMitigation(customer, cuid, dataRequest, aliases)
	if err != nil {
		return err
	}
	currentPreMitgations, err := GetTelemetryPreMitigationByCustomerIdAndCuid(customer.Id, cuid)
	if err != nil {
		return err
	}
	for _, currentPreMitigation := range currentPreMitgations {
		targets, err := GetTelemetryTargets(engine, customer.Id, cuid, currentPreMitigation.Id)
		if err != nil {
			return err
		}
		if tmid == currentPreMitigation.Tmid {
			continue
		}
		isOverlap := CheckOverlapTargetList(newPreMitigation.Targets.TargetList, targets.TargetList)
		if isOverlap && tmid > currentPreMitigation.Tmid {
			log.Debugf("Delete telemetry pre-mitigation aggregated by client with tmid = %+v", currentPreMitigation.Tmid)
			err = DeleteCurrentTelemetryPreMitigation(engine, session, customer.Id, cuid, false, currentPreMitigation.Id)
			if err != nil {
				session.Rollback()
				return err
			}
		}
	}
	currentUriFilteringTarget, err := GetUriFilteringPreMitigationList(engine, customer.Id, cuid)
	if err != nil {
		session.Rollback()
		return err
	}
	for _, ufTarget := range currentUriFilteringTarget {
		if tmid == ufTarget.Tmid {
			continue
		}
		isOverlap := CheckOverlapTargetList(newPreMitigation.Targets.TargetList, ufTarget.TargetList)
		if isOverlap && tmid > ufTarget.Tmid {
			log.Debugf("Delete telemetry pre-mitigation aggregated by server with tmid = %+v", ufTarget.Tmid)
			err = DeleteCurrentUriFilteringTelemetryPreMitigation(engine, session, customer.Id, cuid, ufTarget.Tmid)
			if err != nil {
				session.Rollback()
				return err
			}
		}
	}
	if len(dataRequest.TotalTraffic) == 0 && len(dataRequest.TotalTrafficProtocol) == 0 && len(dataRequest.TotalTrafficPort) == 0 && len(dataRequest.TotalAttackTraffic) == 0 &&
	len(dataRequest.TotalAttackTrafficProtocol) == 0 && len(dataRequest.TotalAttackTrafficPort) == 0 && !isExistedTotalAttackConnection(dataRequest.TotalAttackConnection) &&
	!isExistedTotalAttackConnectionPort(dataRequest.TotalAttackConnectionPort) && len(dataRequest.AttackDetail) == 0 {
		if !isPresent {
			log.Debugf("Create telemetry pre-mitigation aggregated by server")
			err = RegisterUriFilteringTelemetryPreMitigation(session, customer.Id, cuid, cdid, tmid, newPreMitigation)
			if err != nil {
				session.Rollback()
				return err
			}
		} else {
			log.Debugf("Update telemetry pre-mitigation aggregated by server")
			err = updateUriFilteringTelemetryPreMitigation(session, customer.Id, cuid, cdid, tmid, newPreMitigation)
			if err != nil {
				session.Rollback()
				return err
			}
		}
	} else {
		if !isPresent {
			log.Debug("Create telemetry pre-mitigation aggregated by client")
			err = createTelemetryPreMitigation(session, customer.Id, cuid, cdid, tmid, nil, newPreMitigation, nil)
			if err != nil {
				session.Rollback()
				return err
			}
		} else {
			log.Debug("Update telemetry pre-mitigation aggregated by client")
			err = updateTelemetryPreMitigation(engine, session, customer.Id, cuid, cdid, tmid, newPreMitigation)
			if err != nil {
				session.Rollback()
				return err
			}
		}
	}
	err = session.Commit()
	return err
}
func createTelemetryPreMitigation(session *xorm.Session, customerId int, cuid string, cdid string, tmid int, currentPreMitigation *db_models.TelemetryPreMitigation, newPreMitigation *TelemetryPreMitigation, preMitigation *TelemetryPreMitigation) error {
	var currentPreMitigationId int64
	if currentPreMitigation == nil {
		newTelePreMitigation, err := RegisterTelemetryPreMitigation(session, customerId, cuid, cdid, tmid)
		if err != nil {
			return err
		}
		currentPreMitigationId = newTelePreMitigation.Id
	} else if preMitigation != nil {
		currentPreMitigationId = currentPreMitigation.Id
		if !reflect.DeepEqual(GetModelsTelemetryPreMitigation(*newPreMitigation), GetModelsTelemetryPreMitigation(*preMitigation)) {
			_, err := session.Id(currentPreMitigation.Id).Update(currentPreMitigation)
			if err != nil {
				log.Errorf("telemetry_pre_mitigation update err: %s", err)
				return err
			}
		}
	}
	err := CreateTargets(session, currentPreMitigationId, newPreMitigation.Targets)
	if err != nil {
		return err
	}
	err = RegisterTraffic(session, string(TELEMETRY), string(TARGET_PREFIX), currentPreMitigationId, string(TOTAL_TRAFFIC), newPreMitigation.TotalTraffic)
	if err != nil {
		return err
	}
	err = RegisterTrafficPerProtocol(session, string(TELEMETRY), currentPreMitigationId, string(TOTAL_TRAFFIC), newPreMitigation.TotalTrafficProtocol)
	if err != nil {
		return err
	}
	err = RegisterTrafficPerPort(session, string(TELEMETRY), currentPreMitigationId, string(TOTAL_TRAFFIC), newPreMitigation.TotalTrafficPort)
	if err != nil {
		return err
	}
	err = RegisterTraffic(session, string(TELEMETRY), string(TARGET_PREFIX), currentPreMitigationId, string(TOTAL_ATTACK_TRAFFIC), newPreMitigation.TotalAttackTraffic)
	if err != nil {
		return err
	}
	err = RegisterTrafficPerProtocol(session, string(TELEMETRY), currentPreMitigationId, string(TOTAL_ATTACK_TRAFFIC), newPreMitigation.TotalAttackTrafficProtocol)
	if err != nil {
		return err
	}
	err = RegisterTrafficPerPort(session, string(TELEMETRY), currentPreMitigationId, string(TOTAL_ATTACK_TRAFFIC), newPreMitigation.TotalAttackTrafficPort)
	if err != nil {
		return err
	}
	err = CreateTotalAttackConnection(session, string(TARGET_PREFIX),currentPreMitigationId, newPreMitigation.TotalAttackConnection)
	if err != nil {
		return err
	}
	err = CreateTotalAttackConnectionPort(session, currentPreMitigationId, newPreMitigation.TotalAttackConnectionPort)
	if err != nil {
		return err
	}
	err = CreateAttackDetail(session, currentPreMitigationId, newPreMitigation.AttackDetail)
	if err != nil {
		return err
	}
	return nil
}
func updateUriFilteringTelemetryPreMitigation(session *xorm.Session, customerId int, cuid string, cdid string, tmid int, newPreMitigation *TelemetryPreMitigation) error {
	currentPreMitigation, err := db_models.GetTelemetryPreMitigationByTmid(engine, customerId, cuid, tmid)
	if err != nil {
		log.Errorf("Failed to get telemetry pre-mitigation. Error: %+v", err)
		return err
	}
	if currentPreMitigation.Id > 0 {
		log.Debugf("Delete telemetry pre-mitigation aggregated by client with tmid = %+v", tmid)
		err = DeleteCurrentTelemetryPreMitigation(engine, session, customerId, cuid, false, currentPreMitigation.Id)
		if err != nil {
			return err
		}
	} else {
		err = DeleteCurrentUriFilteringTelemetryPreMitigation(engine, session, customerId, cuid, tmid)
		if err != nil {
			return err
		}
	}
	err = RegisterUriFilteringTelemetryPreMitigation(session, customerId, cuid, cdid, tmid, newPreMitigation)
	if err != nil {
		return err
	}
	return nil
}
func updateTelemetryPreMitigation(engine *xorm.Engine, session *xorm.Session, customerId int, cuid string, cdid string, tmid int, newPreMitigation *TelemetryPreMitigation) error {
	currentPreMitigation, err := db_models.GetTelemetryPreMitigationByTmid(engine, customerId, cuid, tmid)
	if err != nil {
		log.Errorf("Failed to get telemetry pre-mitigation. Error: %+v", err)
		return err
	}
	var preMitigation *TelemetryPreMitigation
	if currentPreMitigation.Id > 0 {
		preMitigationTmp, err := GetTelemetryPreMitigationAttributes(customerId, cuid, currentPreMitigation.Id)
		if err != nil {
			return err
		}
		preMitigation = &preMitigationTmp
		err = DeleteCurrentTelemetryPreMitigation(engine, session, customerId, cuid, true, currentPreMitigation.Id)
		if err != nil {
			return err
		}
	} else {
		preMitigation = nil
		currentPreMitigation = nil
		log.Debugf("Delete telemetry pre-mitigation aggregated by server with tmid=%+v", tmid)
		err = DeleteCurrentUriFilteringTelemetryPreMitigation(engine, session, customerId, cuid, tmid)
		if err != nil {
			return err
		}
	}
	err = createTelemetryPreMitigation(session, customerId, cuid, cdid, tmid, currentPreMitigation, newPreMitigation, preMitigation)
	return nil
}
func UpdateTelemetryTotalAttackTraffic(engine *xorm.Engine, session *xorm.Session, mitigationScopeId int64, totalAttackTraffic []Traffic) (err error) {
	trafficList, err := db_models.GetTelemetryTraffic(engine, string(TARGET_PREFIX), mitigationScopeId, string(TOTAL_ATTACK_TRAFFIC))
	if err != nil {
		return err
	}
	if len(trafficList) > 0 {
		log.Debugf("Delete telemetry attributes as total-attack-traffic")
		err = db_models.DeleteTelemetryTraffic(session, string(TARGET_PREFIX), mitigationScopeId, string(TOTAL_ATTACK_TRAFFIC))
		if err != nil {
			log.Errorf("Failed to delete total-attack-traffic. Error: %+v", err)
			return
		}
	}
	if len(totalAttackTraffic) > 0 {
		log.Debugf("Create new telemetry attributes as total-attack-traffic")
		err = RegisterTelemetryTraffic(session, string(TARGET_PREFIX), mitigationScopeId, string(TOTAL_ATTACK_TRAFFIC), totalAttackTraffic)
		if err != nil {
			return
		}
	}
	return
}
func UpdateTelemetryAttackDetail(engine *xorm.Engine, session *xorm.Session, mitigationScopeId int64, attackDetailList []TelemetryAttackDetail) (err error) {
	err = DeleteTelemetryAttackDetail(engine, session, mitigationScopeId, attackDetailList)
	if err != nil {
		return
	}
	if len(attackDetailList) > 0 {
		err = CreateTelemetryAttackDetail(session, mitigationScopeId, attackDetailList)
		if err != nil {
			return
		}
	}
	return
}
func RegisterTelemetryPreMitigation(session *xorm.Session, customerId int, cuid string, cdid string, tmid int) (*db_models.TelemetryPreMitigation, error) {
	newTelemetryPreMitigation := db_models.TelemetryPreMitigation{
		CustomerId: customerId,
		Cuid:       cuid,
		Cdid:       cdid,
		Tmid:       tmid,
	}
	_, err := session.Insert(&newTelemetryPreMitigation)
	if err != nil {
		log.Errorf("telemetry pre-mitigation insert err: %s", err)
		return nil, err
	}
	return &newTelemetryPreMitigation , nil
}
func CreateTargets(session *xorm.Session, telePreMitigationId int64, targets Targets) error {
	err := RegisterTelemetryPrefix(session, string(TELEMETRY), telePreMitigationId, string(TARGET_PREFIX), targets.TargetPrefix)
	if err != nil {
		return err
	}
	err = RegisterTelemetryPortRange(session, string(TELEMETRY), telePreMitigationId, string(TARGET_PREFIX), targets.TargetPortRange)
	if err != nil {
		return err
	}
	err = CreateTelemetryParameterValue(session, string(TELEMETRY), telePreMitigationId, targets.TargetProtocol, targets.FQDN, targets.URI, targets.AliasName)
	if err != nil {
		return err
	}
	return nil
}
func CreateTotalAttackConnection(session *xorm.Session, prefixType string, prefixId int64, tac TotalAttackConnection) error {
	if tac.LowPercentileL != nil {
		err := RegisterTotalAttackConnection(session, prefixType, prefixId, string(LOW_PERCENTILE_L), tac.LowPercentileL)
		if err != nil {
			return err
		}
	}
	if tac.MidPercentileL != nil {
		err := RegisterTotalAttackConnection(session, prefixType, prefixId, string(MID_PERCENTILE_L), tac.MidPercentileL)
		if err != nil {
			return err
		}
	}
	if tac.HighPercentileL != nil {
		err := RegisterTotalAttackConnection(session, prefixType, prefixId, string(HIGH_PERCENTILE_L), tac.HighPercentileL)
		if err != nil {
			return err
		}
	}
	if tac.PeakL != nil {
		err := RegisterTotalAttackConnection(session, prefixType, prefixId, string(PEAK_L), tac.PeakL)
		if err != nil {
			return err
		}
	}
	return nil
}
func CreateTotalAttackConnectionPort(session *xorm.Session, telemetryPreMitigationId int64, tac TotalAttackConnectionPort) error {
	if tac.LowPercentileL != nil {
		err := RegisterTotalAttackConnectionPort(session, telemetryPreMitigationId, string(LOW_PERCENTILE_L), tac.LowPercentileL)
		if err != nil {
			return err
		}
	}
	if tac.MidPercentileL != nil {
		err := RegisterTotalAttackConnectionPort(session, telemetryPreMitigationId, string(MID_PERCENTILE_L), tac.MidPercentileL)
		if err != nil {
			return err
		}
	}
	if tac.HighPercentileL != nil {
		err := RegisterTotalAttackConnectionPort(session, telemetryPreMitigationId, string(HIGH_PERCENTILE_L), tac.HighPercentileL)
		if err != nil {
			return err
		}
	}
	if tac.PeakL != nil {
		err := RegisterTotalAttackConnectionPort(session, telemetryPreMitigationId, string(PEAK_L), tac.PeakL)
		if err != nil {
			return err
		}
	}
	return nil
}
func CreateAttackDetail(session *xorm.Session, telePreMitigationId int64, attackDetails []AttackDetail) error {
	for _, attackDetail := range attackDetails {
		newAttackDetail, err := RegisterAttackDetail(session, telePreMitigationId, attackDetail)
		if err != nil {
			return err
		}
		if !reflect.DeepEqual(GetModelsSourceCount(&attackDetail.SourceCount), GetModelsSourceCount(nil)) {
			err := RegisterSourceCount(session, newAttackDetail.Id, attackDetail.SourceCount)
			if err != nil {
				return err
			}
		}
		if len(attackDetail.TopTalker) > 0 {
			err := CreateTopTalker(session, newAttackDetail.Id, attackDetail.TopTalker)
			if err != nil {
				return err
			}
		}
	}
	return nil
}
func CreateTopTalker(session *xorm.Session, adId int64, topTalkers []TopTalker) error {
	for _, topTalker := range topTalkers {
		newTopTalker, err := RegisterTopTalker(session, adId, topTalker.SpoofedStatus)
		if err != nil {
			return err
		}
		prefixs := []Prefix{}
		prefixs = append(prefixs, topTalker.SourcePrefix) 
		err = RegisterTelemetryPrefix(session, string(TELEMETRY), newTopTalker.Id, string(SOURCE_PREFIX), prefixs)
		if err != nil {
			return err
		}
		err = RegisterTelemetryPortRange(session, string(TELEMETRY), newTopTalker.Id, string(SOURCE_PREFIX), topTalker.SourcePortRange)
		if err != nil {
			return err
		}
		err = RegisterTelemetryIcmpTypeRange(session, newTopTalker.Id, topTalker.SourceIcmpTypeRange)
		if err != nil {
			return err
		}
		err = RegisterTraffic(session, string(TELEMETRY), string(SOURCE_PREFIX), newTopTalker.Id, string(TOTAL_ATTACK_TRAFFIC), topTalker.TotalAttackTraffic)
		if err != nil {
			return err
		}
		err = CreateTotalAttackConnection(session, string(SOURCE_PREFIX), newTopTalker.Id, topTalker.TotalAttackConnection)
		if err != nil {
			return err
		}
	}
	return nil
}
func CreateTelemetryAttackDetail(session *xorm.Session, mitigationScopeId int64, attackDetailList []TelemetryAttackDetail) error {
	log.Debugf("Create new telemetry attributes as attack-detail")
	for _, attackDetail := range attackDetailList {
		newAttackDetail, err := RegisterTelemetryAttackDetail(session, mitigationScopeId, attackDetail)
		if err != nil {
			return err
		}
		if !reflect.DeepEqual(GetModelsSourceCount(&attackDetail.SourceCount), GetModelsSourceCount(nil)) {
			err := RegisterTelemetrySourceCount(session, newAttackDetail.Id, attackDetail.SourceCount)
			if err != nil {
				return err
			}
		}
		if len(attackDetail.TopTalker) > 0 {
			err := CreateTelemetryTopTalker(session, newAttackDetail.Id, attackDetail.TopTalker)
			if err != nil {
				return err
			}
		}
	}
	return nil
}
func CreateTelemetryTopTalker(session *xorm.Session, adId int64, topTalkers []TelemetryTopTalker) error {
	for _, topTalker := range topTalkers {
		newTopTalker, err := RegisterTelemetryTopTalker(session, adId, topTalker.SpoofedStatus)
		if err != nil {
			return err
		}
		err = RegisterTelemetrySourcePrefix(session, newTopTalker.Id, topTalker.SourcePrefix)
		if err != nil {
			return err
		}
		err = RegisterTelemetrySourcePortRange(session, newTopTalker.Id, topTalker.SourcePortRange)
		if err != nil {
			return err
		}
		err = RegisterTelemetrySourceIcmpTypeRange(session, newTopTalker.Id, topTalker.SourceIcmpTypeRange)
		if err != nil {
			return err
		}
		err = RegisterTelemetryTraffic(session, string(SOURCE_PREFIX), newTopTalker.Id, string(TOTAL_ATTACK_TRAFFIC), topTalker.TotalAttackTraffic)
		if err != nil {
			return err
		}
		err = CreateTelemetryTotalAttackConnection(session, string(SOURCE_PREFIX), newTopTalker.Id, topTalker.TotalAttackConnection)
		if err != nil {
			return err
		}
	}
	return nil
}
func CreateTelemetryTotalAttackConnection(session *xorm.Session, prefixType string, prefixId int64, tac TelemetryTotalAttackConnection) error {
	if !reflect.DeepEqual(GetModelsTelemetryConnectionPercentile(&tac.LowPercentileC), GetModelsTelemetryConnectionPercentile(nil)) {
		err := RegisterTelemetryTotalAttackConnection(session, prefixType, prefixId, string(LOW_PERCENTILE_C), tac.LowPercentileC)
		if err != nil {
			return err
		}
	}
	if !reflect.DeepEqual(GetModelsTelemetryConnectionPercentile(&tac.MidPercentileC), GetModelsTelemetryConnectionPercentile(nil)) {
		err := RegisterTelemetryTotalAttackConnection(session, prefixType, prefixId, string(MID_PERCENTILE_C), tac.MidPercentileC)
		if err != nil {
			return err
		}
	}
	if !reflect.DeepEqual(GetModelsTelemetryConnectionPercentile(&tac.HighPercentileC), GetModelsTelemetryConnectionPercentile(nil)) {
		err := RegisterTelemetryTotalAttackConnection(session, prefixType, prefixId, string(HIGH_PERCENTILE_C), tac.HighPercentileC)
		if err != nil {
			return err
		}
	}
	if !reflect.DeepEqual(GetModelsTelemetryConnectionPercentile(&tac.PeakC), GetModelsTelemetryConnectionPercentile(nil)) {
		err := RegisterTelemetryTotalAttackConnection(session, prefixType, prefixId, string(PEAK_C), tac.PeakC)
		if err != nil {
			return err
		}
	}
	return nil
}
func RegisterTotalAttackConnection(session *xorm.Session, prefixType string, prefixId int64, percentileType string, cpps []ConnectionProtocolPercentile) error {
	tacList := []db_models.TotalAttackConnection{}
	for _, v := range cpps {
		tac := db_models.TotalAttackConnection{
			PrefixType:       prefixType,
			PrefixTypeId:     prefixId,
			PercentileType:   percentileType,
			Protocol:         v.Protocol,
			Connection:       v.Connection,
			Embryonic:        v.Embryonic,
			ConnectionPs:     v.ConnectionPs,
			RequestPs:        v.RequestPs,
			PartialRequestPs: v.PartialRequestPs,
		}
		tacList = append(tacList, tac)
	}
	if len(tacList) > 0 {
		_, err := session.Insert(&tacList)
		if err != nil {
			log.Errorf("total attack connection insert err: %s", err)
			return err
		}
	}
	return nil
}
func RegisterTotalAttackConnectionPort(session *xorm.Session, telePreMitigationId int64, percentileType string, cpps []ConnectionProtocolPortPercentile) error {
	tacList := []db_models.TotalAttackConnectionPort{}
	for _, v := range cpps {
		tac := db_models.TotalAttackConnectionPort{
			TelePreMitigationId: telePreMitigationId,
			PercentileType:      percentileType,
			Protocol:            v.Protocol,
			Port:                v.Port,
			Connection:          v.Connection,
			Embryonic:           v.Embryonic,
			ConnectionPs:        v.ConnectionPs,
			RequestPs:           v.RequestPs,
			PartialRequestPs:    v.PartialRequestPs,
		}
		tacList = append(tacList, tac)
	}
	if len(tacList) > 0 {
		_, err := session.Insert(&tacList)
		if err != nil {
			log.Errorf("total attack connection port insert err: %s", err)
			return err
		}
	}
	return nil
}