package services /* TODO: TO BE DEPRECATED IN 0.25 @RS185722 */ import ( "context" "database/sql" "errors" "fmt" "github.com/google/uuid" "github.com/hashicorp/go-multierror" "edge-infra.dev/pkg/edge/api/graph/model" sqlquery "edge-infra.dev/pkg/edge/api/sql" ) //go:generate mockgen -destination=../mocks/mock_log_classification_labels_service.go -package=mocks edge-infra.dev/pkg/edge/api/services LogClassificationLabelsService type LogClassificationLabelsService interface { GetLogClassificationLabel(ctx context.Context, logClassificationLabelEdgeID string, logClassificationEdgeID string, labelEdgeID string) (*model.LogClassificationLabel, error) GetLogClassificationLabelsByLabel(ctx context.Context, labelEdgeID string) ([]*model.LogClassificationLabel, error) GetLogClassificationLabelsByBanner(ctx context.Context, bannerEdgeID string) ([]*model.LogClassificationLabel, error) CreateLogClassificationLabel(ctx context.Context, logClassificationLabelEdgeID string, logClassificationEdgeID string, labelEdgeID string) (string, error) UpdateLogClassificationLabel(ctx context.Context, logClassificationEdgeID string, labelEdgeID string) (string, error) DeleteLogClassificationLabel(ctx context.Context, logClassificationLabelEdgeID string, logClassificationEdgeID string, labelEdgeID string) (bool, error) } type logClassificationLabelsService struct { SQLDB *sql.DB } func (l *logClassificationLabelsService) GetLogClassificationLabel(ctx context.Context, logClassificationLabelEdgeID string, logClassificationEdgeID string, labelEdgeID string) (*model.LogClassificationLabel, error) { row := l.SQLDB.QueryRowContext(ctx, sqlquery.GetLogClassificationLabel, labelEdgeID, logClassificationEdgeID, logClassificationLabelEdgeID) logClassificationLabel := &model.LogClassificationLabel{} if err := row.Scan(&logClassificationLabel.LogClassificationLabelEdgeID, &logClassificationLabel.ClassificationEdgeID, &logClassificationLabel.BannerEdgeID, &logClassificationLabel.LabelEdgeID, &logClassificationLabel.LabelName, &logClassificationLabel.Description, &logClassificationLabel.Pod, &logClassificationLabel.Container, &logClassificationLabel.Type, &logClassificationLabel.Class, &logClassificationLabel.Pattern); err != nil { return nil, err } return logClassificationLabel, nil } func (l *logClassificationLabelsService) GetLogClassificationLabelsByLabel(ctx context.Context, labelEdgeID string) ([]*model.LogClassificationLabel, error) { if !isValidUUID(labelEdgeID) { return nil, errors.New("Error Getting Log Classification Labels by Label: Label Edge ID not a valid UUID format") } return l.getMultipleClassificationLabels(ctx, sqlquery.GetLogClassificationLabelsByLabel, labelEdgeID) } func (l *logClassificationLabelsService) GetLogClassificationLabelsByBanner(ctx context.Context, bannerEdgeID string) ([]*model.LogClassificationLabel, error) { if bannerEdgeID == "" { return nil, errors.New("Error Getting Log Classification Labels by Banner: Banner Edge ID can not be blank") } if !isValidUUID(bannerEdgeID) { return nil, errors.New("Error Getting Log Classification Labels by Banner: Banner Edge ID not a valid UUID format") } return l.getMultipleClassificationLabels(ctx, sqlquery.GetLogClassificationLabelsByBanner, bannerEdgeID) } func (l *logClassificationLabelsService) CreateLogClassificationLabel(ctx context.Context, logClassificationLabelEdgeID string, logClassificationEdgeID string, labelEdgeID string) (string, error) { existingClassifications, err := l.GetLogClassificationLabelsByLabel(ctx, labelEdgeID) if err != nil { return "", err } for _, classificationLabel := range existingClassifications { if logClassificationEdgeID == classificationLabel.ClassificationEdgeID { return "", errors.New("Error Creating Log Classification Label: Classification is already tied to this label") } } /* In reality, all API calls will be blank for this value, but for testing this value need to be parameterized. This will help to avoid the uuid.NewString() mismatch during testing. Also using goMocks.Any() causes issues in the DB saying: could not convert 0 argument gomock.anyMatcher - is anything to driver value: unsupported type gomock.anyMatcher, a struct */ if logClassificationLabelEdgeID == "" { logClassificationLabelEdgeID = uuid.NewString() } transaction, err := l.newTransaction(ctx) if err != nil { return "", fmt.Errorf("Error Creating Log Classification Label: %s", err.Error()) } if _, err := transaction.ExecContext(ctx, sqlquery.CreateLogClassificationLabel, logClassificationLabelEdgeID, logClassificationEdgeID, labelEdgeID); err != nil { if rollbackErr := transaction.Rollback(); rollbackErr != nil { return "", multierror.Append(err, rollbackErr) } return "", err } err = transaction.Commit() if err != nil { return "", fmt.Errorf("Error Creating Log Classification Label: %s", err.Error()) } return fmt.Sprintf("Entry Created Successfully. Entry ID is: %v", logClassificationLabelEdgeID), nil } func (l *logClassificationLabelsService) UpdateLogClassificationLabel(ctx context.Context, logClassificationEdgeID string, labelEdgeID string) (string, error) { transaction, err := l.newTransaction(ctx) if err != nil { return "", fmt.Errorf("Error Updating Log Classification Label: %s", err.Error()) } if _, err := transaction.ExecContext(ctx, sqlquery.UpdateLogClassificationLabel, labelEdgeID, logClassificationEdgeID); err != nil { if rollbackErr := transaction.Rollback(); rollbackErr != nil { return "", multierror.Append(err, rollbackErr) } return "", err } err = transaction.Commit() if err != nil { return "", fmt.Errorf("Error Updating Log Classification Label: %s", err.Error()) } return fmt.Sprintf("Updated Successfully. Classification %v is now associated with label %v", logClassificationEdgeID, labelEdgeID), nil } func (l *logClassificationLabelsService) DeleteLogClassificationLabel(ctx context.Context, logClassificationLabelEdgeID string, logClassificationEdgeID string, labelEdgeID string) (bool, error) { _, err := l.SQLDB.ExecContext(ctx, sqlquery.DeleteLogClassificationLabel, logClassificationLabelEdgeID, logClassificationEdgeID, labelEdgeID) if err != nil { return false, fmt.Errorf("Error Deleting Log Classification Label: %s", err.Error()) } return true, nil } func (l *logClassificationLabelsService) newTransaction(ctx context.Context) (*sql.Tx, error) { transaction, err := l.SQLDB.BeginTx(ctx, nil) if err != nil { return nil, err } return transaction, nil } func (l *logClassificationLabelsService) getMultipleClassificationLabels(ctx context.Context, query string, ID string) ([]*model.LogClassificationLabel, error) { row, err := l.SQLDB.QueryContext(ctx, query, ID) if err != nil { return nil, fmt.Errorf("Error Getting Log Classification Labels: %s", err.Error()) } logClassificationLabels := []*model.LogClassificationLabel{} for row.Next() { logClassificationLabel := &model.LogClassificationLabel{} if err = row.Scan(&logClassificationLabel.LogClassificationLabelEdgeID, &logClassificationLabel.ClassificationEdgeID, &logClassificationLabel.BannerEdgeID, &logClassificationLabel.LabelEdgeID, &logClassificationLabel.LabelName, &logClassificationLabel.Description, &logClassificationLabel.Pod, &logClassificationLabel.Container, &logClassificationLabel.Type, &logClassificationLabel.Class, &logClassificationLabel.Pattern); err != nil { return nil, fmt.Errorf("Error Getting Log Classification Labels: %s", err.Error()) } logClassificationLabels = append(logClassificationLabels, logClassificationLabel) } return logClassificationLabels, nil } func isValidUUID(u string) bool { if u == "" { return false } _, err := uuid.Parse(u) return err == nil } // nolint func NewLogClassificationLabelService(sqlDB *sql.DB) *logClassificationLabelsService { return &logClassificationLabelsService{ SQLDB: sqlDB, } }