func getTelemetryConfiguration(dbTelemetrySetupId int64) (currentConfig *messages.TelemetryConfigurationResponse, err error) {
	currentConfig = &messages.TelemetryConfigurationResponse{}
	teleConfig := &models.TelemetryConfiguration{}
	if dbTelemetrySetupId <= 0 {
		teleConfig = models.DefaultValueTelemetryConfiguration()
	} else {
		teleConfig, err = models.GetTelemetryConfiguration(dbTelemetrySetupId)
		if err != nil {
			return  nil, err
		}
	}
	if teleConfig != nil {
		currentConfig.MeasurementInterval = teleConfig.MeasurementInterval
		currentConfig.MeasurementSample = teleConfig.MeasurementSample
		currentConfig.LowPercentile = decimal.NewFromFloat(teleConfig.LowPercentile).Round(2)
		currentConfig.MidPercentile = decimal.NewFromFloat(teleConfig.MidPercentile).Round(2)
		currentConfig.HighPercentile = decimal.NewFromFloat(teleConfig.HighPercentile).Round(2)
		unitConfigList := []messages.UnitConfigResponse{}
		for _, v := range teleConfig.UnitConfigList {
			unitConfig := messages.UnitConfigResponse{Unit: v.Unit, UnitStatus: v.UnitStatus}
			unitConfigList = append(unitConfigList, unitConfig)
		}
		currentConfig.UnitConfigList = unitConfigList
		currentConfig.ServerOriginatedTelemetry = &teleConfig.ServerOriginatedTelemetry
		if teleConfig.TelemetryNotifyInterval >= 1 {
			currentConfig.TelemetryNotifyInterval = &teleConfig.TelemetryNotifyInterval
		}
	}
	return currentConfig, nil
}
Get telemetry configuration
package controllers
import (
	"errors"
	"fmt"
	"strconv"
	"strings"
	"github.com/shopspring/decimal"
	"github.com/nttdots/go-dots/dots_common/messages"
	"github.com/nttdots/go-dots/dots_server/db_models"
	"github.com/nttdots/go-dots/dots_server/models"
	log "github.com/sirupsen/logrus"
	common "github.com/nttdots/go-dots/dots_common"
	types "github.com/nttdots/go-dots/dots_common/types/data"
	dots_config "github.com/nttdots/go-dots/dots_server/config"
	data_controllers "github.com/nttdots/go-dots/dots_server/controllers/data"
)
 type TelemetrySetupRequest struct {
	Controller
}
func (t *TelemetrySetupRequest) HandlePut(request Request, customer *models.Customer) (res Response, err error) {
	log.WithField("request", request).Debug("HandlePut")
	var errMsg string
	cuid, tsid, cdid, err := parseTelemetrySetupUriPath(request.PathInfo)
	if err != nil {
		errMsg = fmt.Sprintf("Failed to parse Uri-Path, error: %s", err)
		log.Error(errMsg)
		res = Response {
			Type: common.Acknowledgement,
			Code: common.BadRequest,
			Body: errMsg,
		}
		return res, nil
	}
	if cuid == "" || tsid == nil {
		errMsg = "Missing required Uri-Path Parameter(cuid, tsid)."
		log.Error(errMsg)
		res = Response {
			Type: common.Acknowledgement,
			Code: common.BadRequest,
			Body: errMsg,
		}
		return res, nil
	}
	if request.Body == nil {
		errMsg = "Request body must be provided for PUT method"
		log.Error(errMsg)
		res = Response {
			Type: common.Acknowledgement,
			Code: common.BadRequest,
			Body: errMsg,
		}
		return res, nil
	}
	body := request.Body.(*messages.TelemetrySetupRequest)
	if len(body.TelemetrySetup.Telemetry) != 1 {
		errMsg = "Request body must contain only one telemetry setup configuration"
		log.Error(errMsg)
		res = Response {
			Type: common.Acknowledgement,
			Code: common.BadRequest,
			Body: errMsg,
		}
		return res, nil
	}
	telemetry := body.TelemetrySetup.Telemetry[0]
	if (telemetry.TelemetryConfigurationCurrent != nil && len(telemetry.TotalPipeCapacity) > 0) ||
		(telemetry.TelemetryConfigurationCurrent != nil && len(telemetry.Baseline) > 0) ||
		(len(telemetry.Baseline) > 0 && len(telemetry.TotalPipeCapacity) > 0) {
		errMsg = "A DOTS telemetry setup message MUST include only telemetry-related configuration parameters or information about DOTS client domain pipe capacity or telemetry traffic baseline"
		log.Error(errMsg)
		res = Response {
			Type: common.Acknowledgement,
			Code: common.BadRequest,
			Body: errMsg,
		}
		return res, nil
	}
	if telemetry.TelemetryConfigurationCurrent != nil {
		res, err = handlePutTelemetryConfiguration(telemetry.TelemetryConfigurationCurrent, customer, cuid, cdid, *tsid)
	} else if len(telemetry.TotalPipeCapacity) > 0 {
		res, err = handlePutTotalPipeCapacity(telemetry.TotalPipeCapacity, customer, cuid, cdid, *tsid)
	} else if len(telemetry.Baseline) > 0 {
		res, err = handlePutBaseline(telemetry.Baseline, customer, cuid, cdid, *tsid)
	} else {
		errMsg = "The body request doesn't contain telemetry setup data"
		log.Error(errMsg)
		res = Response {
			Type: common.Acknowledgement,
			Code: common.BadRequest,
			Body: errMsg,
		}
	}
	return res, err
}
func (t *TelemetrySetupRequest) HandleGet(request Request, customer *models.Customer) (res Response, err error) {
	log.WithField("request", request).Debug("[GET] receive message")
	var errMsg string
	cuid, tsid, _, err := parseTelemetrySetupUriPath(request.PathInfo)
	if err != nil {
		errMsg = fmt.Sprintf("Failed to parse Uri-Path, error: %s", err)
		log.Error(errMsg)
		res = Response {
			Type: common.Acknowledgement,
			Code: common.BadRequest,
			Body: errMsg,
		}
		return res, nil
	}
	if cuid == "" {
		errMsg = "Missing required Uri-Path Parameter cuid."
		log.Error(errMsg)
		res = Response {
			Type: common.Acknowledgement,
			Code: common.BadRequest,
			Body: errMsg,
		}
		return res, nil
	}
	if tsid != nil {
		log.Debug("Get one telemetry setup configuration")
		res, err = handleGetOneTelemetrySetup(customer.Id, cuid, *tsid)
	} else {
		log.Debug("Get all telemetry configuration")
		res, err = handleGetAllTelemetrySetup(customer.Id, cuid)
	}
	return
}
 func (t *TelemetrySetupRequest) HandleDelete(request Request, customer *models.Customer) (res Response, err error) {
	log.WithField("request", request).Debug("[DELETE] receive message")
	var errMsg string
	cuid, tsid, cdid, err := parseTelemetrySetupUriPath(request.PathInfo)
	if err != nil {
		errMsg = fmt.Sprintf("Failed to parse Uri-Path, error: %s", err)
		log.Error(errMsg)
		res = Response {
			Type: common.Acknowledgement,
			Code: common.BadRequest,
			Body: errMsg,
		}
		return res, nil
	}
	if cuid == "" {
		errMsg = "Missing required Uri-Path Parameter cuid."
		log.Error(errMsg)
		res = Response {
			Type: common.Acknowledgement,
			Code: common.BadRequest,
			Body: errMsg,
		}
		return res, nil
	}
	if tsid != nil {
		log.Debug("Delete one telemetry setup configuration")
		err = handleDeleteOneTelemetrySetup(customer.Id, cuid, cdid, *tsid)
		if err != nil {
			return Response{}, err
		}
	} else {
		log.Debug("Delete all telemetry setup configuration")
		err = models.DeleteAllTelemetrySetup(customer.Id, cuid, cdid)
		if err != nil {
			return Response{}, err
		}
	}
	res = Response{
		Type: common.Acknowledgement,
		Code: common.Deleted,
		Body: "Deleted",
	}
	return res, err
}
func handlePutTelemetryConfiguration(bodyRequest *messages.TelemetryConfigurationCurrent, customer *models.Customer, cuid string, cdid string, tsid int) (res Response, err error) {
	isPresent, isUnprocessableEntity, errMsg := models.ValidateTelemetryConfiguration(customer.Id, cuid, tsid, bodyRequest)
	if errMsg != "" {
		if isUnprocessableEntity {
			res = Response {
				Type: common.Acknowledgement,
				Code: common.UnprocessableEntity,
				Body: errMsg,
			}
			return res, nil
		}
		res = Response {
			Type: common.Acknowledgement,
			Code: common.BadRequest,
			Body: errMsg,
		}
		return res, nil
	}
	telemetryConfiguration := models.NewTelemetryConfiguration(bodyRequest)
	if !isPresent {
		log.Debug("Create telemetry configuration")
		err := models.CreateTelemetryConfiguration(customer.Id, cuid, cdid, tsid, telemetryConfiguration)
		if err != nil {
			return Response{}, err
		}
		res = Response{
			Type: common.Acknowledgement,
			Code: common.Created,
			Body: nil,
		}
		return res, nil
	}
	log.Debug("Update telemetry configuration")
	err = models.UpdateTelemetryConfiguration(customer.Id, cuid, cdid, tsid, telemetryConfiguration)
	if err != nil {
		return Response{}, err
	}
	res = Response{
		Type: common.Acknowledgement,
		Code: common.Changed,
		Body: nil,
	}
	return res, nil
}
func handlePutTotalPipeCapacity(bodyRequest []messages.TotalPipeCapacity, customer *models.Customer, cuid string, cdid string, tsid int) (res Response, err error) {
	var conflictInfo *models.ConflictInformation
	isPresent, isUnprocessableEntity, errMsg := models.ValidateTotalPipeCapacity(customer.Id, cuid, tsid, bodyRequest)
	if errMsg != "" {
		if isUnprocessableEntity {
			res = Response {
				Type: common.Acknowledgement,
				Code: common.UnprocessableEntity,
				Body: errMsg,
			}
			return res, nil
		}
		res = Response {
			Type: common.Acknowledgement,
			Code: common.BadRequest,
			Body: errMsg,
		}
		return res, nil
	}
	totalPipeCapacity := models.NewTotalPipeCapacity(bodyRequest)
	isConflict, err := models.CreateTotalPipeCapacity(customer.Id, cuid, cdid, tsid, totalPipeCapacity, isPresent)
	if err != nil {
		return Response{}, err
	}
	if isConflict {
		log.Error("[Conflicted] Existed total pipe capacity")
		conflictInfo = &models.ConflictInformation {
			ConflictCause:  models.OVERLAPPING_TARGETS,
			ConflictScope:  nil,
		}
		res = Response {
			Type: common.Acknowledgement,
			Code: common.Conflict,
			Body: messages.NewTelemetrySetupConfigurationResponseConflict(tsid, conflictInfo.ParseToResponse()),
		}
		return res, nil
	}
	if !isPresent {
		res = Response{
			Type: common.Acknowledgement,
			Code: common.Created,
			Body: nil,
		}
		return res, nil
	}
	res = Response{
		Type: common.Acknowledgement,
		Code: common.Changed,
		Body: nil,
	}
	return res, nil
}
func handlePutBaseline(bodyRequest []messages.Baseline, customer *models.Customer, cuid string, cdid string, tsid int) (res Response, err error) {
	var conflictInfo *models.ConflictInformation
	isPresent, isUnprocessableEntity, errMsg := models.ValidateBaseline(customer, cuid, tsid, bodyRequest)
	if errMsg != "" {
		if isUnprocessableEntity {
			res = Response {
				Type: common.Acknowledgement,
				Code: common.UnprocessableEntity,
				Body: errMsg,
			}
			return res, nil
		}
		res = Response {
			Type: common.Acknowledgement,
			Code: common.BadRequest,
			Body: errMsg,
		}
		return res, nil
	}
	var aliases types.Aliases
	if bodyRequest[0].AliasName != nil {
		aliases, err = data_controllers.GetDataAliasesByName(customer, cuid, bodyRequest[0].AliasName)
		if err != nil {
			log.Errorf("Get data alias error: %+v", err)
			return Response{}, err
		}
		if len(aliases.Alias) <= 0 {
			errMsg = "'alias-name' doesn't exist in DB"
			res = Response {
				Type: common.Acknowledgement,
				Code: common.NotFound,
				Body: errMsg,
			}
			return res, nil
		}
	}
	baselineList, err := models.NewBaselineList(bodyRequest, aliases)
	if err != nil {
		return Response{}, err
	}
	isConflict, err := models.CreateBaseline(customer.Id, cuid, cdid, tsid, baselineList, isPresent)
	if err != nil {
		return Response{}, err
	}
	if isConflict {
		log.Error("[Conflicted] Existed baseline")
		conflictInfo = &models.ConflictInformation {
			ConflictCause:  models.OVERLAPPING_TARGETS,
			ConflictScope:  nil,
		}
		res = Response {
			Type: common.Acknowledgement,
			Code: common.Conflict,
			Body: messages.NewTelemetrySetupConfigurationResponseConflict(tsid, conflictInfo.ParseToResponse()),
		}
		return res, nil
	}
	if !isPresent {
		res = Response{
			Type: common.Acknowledgement,
			Code: common.Created,
			Body: nil,
		}
		return res, nil
	}
	res = Response{
		Type: common.Acknowledgement,
		Code: common.Changed,
		Body: nil,
	}
	return res, nil
}
func handleGetOneTelemetrySetup(customerId int, cuid string, tsid int) (res Response, err error) {
	dbTelemetrySetupList, err := models.GetTelemetrySetupByTsid(customerId, cuid, tsid)
	if err != nil {
		log. Errorf("Get telemetry_setup by tsid err: %+v", err)
		return Response{}, err
	}
	if len(dbTelemetrySetupList) < 1 {
		errMsg := fmt.Sprintf("Not found telemetry setup with tsid = %+v", tsid)
		log.Error(errMsg)
		res = Response{
			Type: common.Acknowledgement,
			Code: common.NotFound,
			Body: errMsg,
		}
		return res, nil
	}
	telemetrySetupResp := messages.TelemetrySetupResponse{}
	telemetry := messages.TelemetryResponse{}
	telemetry.Tsid = tsid
	for _, dbTelemetrySetup := range dbTelemetrySetupList {
		err = getTelemetrySetup(customerId, cuid, dbTelemetrySetup, &telemetry)
		if err != nil {
			return Response{}, err
		}
	}
	telemetrySetupResp.TelemetrySetup.Telemetry = append(telemetrySetupResp.TelemetrySetup.Telemetry, telemetry)
	res = Response{
		Type: common.Acknowledgement,
		Code: common.Content,
		Body: telemetrySetupResp,
	}
	return res, nil
}
func handleGetAllTelemetrySetup(customerId int, cuid string) (res Response, err error) {
	telemetrySetupResp := messages.TelemetrySetupResponse{}
	dbTelemetrySetupList, err := models.GetTelemetrySetupByCuidAndNonNegativeTsid(customerId, cuid)
	if err != nil {
		log. Errorf("Get telemetry_setup by cuid err: %+v", err)
		return Response{}, err
	}
	if len(dbTelemetrySetupList) > 0 {
		telemetrySetupList := messages.TelemetrySetupResp{}
		for _, vDbTelemetrySetup := range dbTelemetrySetupList {
			if vDbTelemetrySetup.Tsid > 0 {
				telemetry := messages.TelemetryResponse{}
				telemetry.Tsid = vDbTelemetrySetup.Tsid
				for k, vTelemetrySetup := range telemetrySetupList.Telemetry {
					if vDbTelemetrySetup.Tsid == vTelemetrySetup.Tsid {
						telemetry = vTelemetrySetup
						telemetrySetupList.Telemetry = append(telemetrySetupList.Telemetry[:k], telemetrySetupList.Telemetry[k+1:]...)
					}
				}
				err = getTelemetrySetup(customerId, cuid, vDbTelemetrySetup, &telemetry)
				if err != nil {
					return Response{}, err
				}
				telemetrySetupList.Telemetry = append(telemetrySetupList.Telemetry, telemetry)
			}
		}
		telemetrySetupResp.TelemetrySetup = telemetrySetupList
	}
	maxConfig, minConfig, supportedUnit := getMinMaxConfigValues()
	telemetrySetupResp.TelemetrySetup.MaxConfig     = maxConfig
	telemetrySetupResp.TelemetrySetup.MinConfig     = minConfig
	telemetrySetupResp.TelemetrySetup.SupportedUnit = supportedUnit
	telemetrySetupResp.TelemetrySetup.QueryType = dots_config.GetServerSystemConfig().QueryType
	res = Response{
		Type: common.Acknowledgement,
		Code: common.Content,
		Body: telemetrySetupResp,
	}
	return res, nil
}
func handleDeleteOneTelemetrySetup(customerId int, cuid string, cdid string, tsid int) (err error) {
	dbTelemetrySetupList, err := models.GetTelemetrySetupByTsid(customerId, cuid, tsid)
	if err != nil {
		log. Errorf("Get telemetry_setup err: %+v", err)
		return err
	}
	if len(dbTelemetrySetupList) > 0 {
		err = models.DeleteOneTelemetrySetup(customerId, cuid, cdid, tsid, dbTelemetrySetupList)
		if err != nil {
			return err
		}
	}
	return nil
}
func getTelemetrySetup(customerId int, cuid string, dbTelemetrySetup db_models.TelemetrySetup,telemetry *messages.TelemetryResponse) (err error) {
	if dbTelemetrySetup.SetupType == string(models.TELEMETRY_CONFIGURATION) {
		currentConfig, err := getTelemetryConfiguration(dbTelemetrySetup.Id)
		if err != nil {
			return err
		}
		telemetry.CurrentConfig = currentConfig
	} else if dbTelemetrySetup.SetupType == string(models.PIPE) {
		pipeList, err := getTotalPipeCapacity(dbTelemetrySetup.Id)
		if err != nil {
			return err
		}
		telemetry.TotalPipeCapacity = pipeList
	} else if dbTelemetrySetup.SetupType == string(models.BASELINE) {
		baselineList, err := getBaseline(customerId, cuid, dbTelemetrySetup.Id)
		if err != nil {
			return err
		}
		telemetry.Baseline = baselineList
	}
	return nil
}
func getMinMaxConfigValues()(maxConfig *messages.TelemetryConfigurationResponse, minConfig *messages.TelemetryConfigurationResponse, supportedUnit *messages.SupportedUnitResponse) {
	maxConfig = &messages.TelemetryConfigurationResponse{}
	minConfig = &messages.TelemetryConfigurationResponse{}
	supportedUnit = &messages.SupportedUnitResponse{}
	config := dots_config.GetServerSystemConfig().TelemetryConfigurationParameter
	if config != nil {
		maxConfig.MeasurementInterval       = config.MeasurementInterval.End().(int)
		maxConfig.MeasurementSample         = config.MeasurementSample.End().(int)
		maxConfig.LowPercentile             = decimal.NewFromFloat(config.LowPercentile.End().(float64)).Round(2)
		maxConfig.MidPercentile             = decimal.NewFromFloat(config.MidPercentile.End().(float64)).Round(2)
		maxConfig.HighPercentile            = decimal.NewFromFloat(config.HighPercentile.End().(float64)).Round(2)
		maxConfig.ServerOriginatedTelemetry = &config.ServerOriginatedTelemetry
		maxTelemetryNotifyInterval          := config.TelemetryNotifyInterval.End().(int)
		maxConfig.TelemetryNotifyInterval   = &maxTelemetryNotifyInterval
		minConfig.MeasurementInterval     = config.MeasurementInterval.Start().(int)
		minConfig.MeasurementSample       = config.MeasurementSample.Start().(int)
		minConfig.LowPercentile           = decimal.NewFromFloat(config.LowPercentile.Start().(float64)).Round(2)
		minConfig.MidPercentile           = decimal.NewFromFloat(config.MidPercentile.Start().(float64)).Round(2)
		minConfig.HighPercentile          = decimal.NewFromFloat(config.HighPercentile.Start().(float64)).Round(2)
		minTelemetryNotifyInterval        := config.TelemetryNotifyInterval.Start().(int)
		minConfig.TelemetryNotifyInterval = &minTelemetryNotifyInterval
		unitConfig := messages.UnitConfigResponse{Unit: config.Unit, UnitStatus: config.UnitStatus}
		supportedUnit.UnitConfigList = append(supportedUnit.UnitConfigList, unitConfig)
	}
	return
}