diff --git a/pkg/scd/actions/constraint.go b/pkg/scd/actions/constraint.go index a165bfdb0..702c48c69 100644 --- a/pkg/scd/actions/constraint.go +++ b/pkg/scd/actions/constraint.go @@ -20,6 +20,87 @@ func init() { Decode: dssstore.DecodeJSON[*restapi.DeleteConstraintReferenceRequest], Execute: ExecuteDeleteConstraint, } + Registry[restapi.GetConstraintReferenceOperationID] = dssstore.OperationHandler[repos.Repository]{ + Encode: dssstore.EncodeJSON, + Decode: dssstore.DecodeJSON[*restapi.GetConstraintReferenceRequest], + Execute: ExecuteGetConstraint, + IsReadOnly: true, + } + Registry[restapi.QueryConstraintReferencesOperationID] = dssstore.OperationHandler[repos.Repository]{ + Encode: dssstore.EncodeJSON, + Decode: dssstore.DecodeJSON[*restapi.QueryConstraintReferencesRequest], + Execute: ExecuteQueryConstraintReferences, + IsReadOnly: true, + } +} + +func ExecuteGetConstraint(ctx context.Context, repo repos.Repository, request dssstore.OperationRequest) (any, error) { + req, ok := request.(*restapi.GetConstraintReferenceRequest) + if !ok { + return nil, stacktrace.NewError("unexpected request type %T for operation %q", request, restapi.GetConstraintReferenceOperationID) + } + + id, err := dssmodels.IDFromString(string(req.Entityid)) + if err != nil { + return nil, stacktrace.NewErrorWithCode(dsserr.BadRequest, "Invalid ID format: `%s`", req.Entityid) + } + + constraint, err := repo.GetConstraint(ctx, id) + switch { + case err == pgx.ErrNoRows: + return nil, stacktrace.NewErrorWithCode(dsserr.NotFound, "Constraint %s not found", id.String()) + case err != nil: + return nil, stacktrace.Propagate(err, "Unable to get Constraint from repo") + } + + if constraint.Manager != dssmodels.Manager(*req.Auth.ClientID) { + constraint.OVN = scdmodels.NoOvnPhrase + } + + // Return response to client + return &restapi.GetConstraintReferenceResponse{ + ConstraintReference: *constraint.ToRest(), + }, nil +} + +func ExecuteQueryConstraintReferences(ctx context.Context, repo repos.Repository, request dssstore.OperationRequest) (any, error) { + req, ok := request.(*restapi.QueryConstraintReferencesRequest) + if !ok { + return nil, stacktrace.NewError("unexpected request type %T for operation %q", request, restapi.QueryConstraintReferencesOperationID) + } + + // Retrieve the area of interest parameter + aoi := req.Body.AreaOfInterest + if aoi == nil { + return nil, stacktrace.NewErrorWithCode(dsserr.BadRequest, "Missing area_of_interest") + } + + // Parse area of interest to common Volume4D + vol4, err := scdmodels.Volume4DFromSCDRest(aoi) + if err != nil { + return nil, stacktrace.PropagateWithCode(err, dsserr.BadRequest, "Failed to convert to internal geometry model") + } + + // Perform search query on Store + constraints, err := repo.SearchConstraints(ctx, vol4) + if err != nil { + return nil, err + } + + // Create response for client + response := &restapi.QueryConstraintReferencesResponse{ + ConstraintReferences: make([]restapi.ConstraintReference, 0, len(constraints)), + } + for _, constraint := range constraints { + p := constraint.ToRest() + if constraint.Manager != dssmodels.Manager(*req.Auth.ClientID) { + noOvnPhrase := restapi.EntityOVN(scdmodels.NoOvnPhrase) + p.Ovn = &noOvnPhrase + } + response.ConstraintReferences = append(response.ConstraintReferences, *p) + } + + return response, nil } func ExecuteDeleteConstraint(ctx context.Context, repo repos.Repository, request dssstore.OperationRequest) (any, error) { diff --git a/pkg/scd/constraints_handler.go b/pkg/scd/constraints_handler.go index 83465c4da..24db03e60 100644 --- a/pkg/scd/constraints_handler.go +++ b/pkg/scd/constraints_handler.go @@ -66,7 +66,7 @@ func (a *Server) DeleteConstraintReference(ctx context.Context, req *restapi.Del func (a *Server) GetConstraintReference(ctx context.Context, req *restapi.GetConstraintReferenceRequest, ) restapi.GetConstraintReferenceResponseSet { - id, err := dssmodels.IDFromString(string(req.Entityid)) + _, err := dssmodels.IDFromString(string(req.Entityid)) if err != nil { return restapi.GetConstraintReferenceResponseSet{Response400: &restapi.ErrorResponse{ Message: dsserr.Handle(ctx, stacktrace.NewErrorWithCode(dsserr.BadRequest, "Invalid ID format: `%s`", req.Entityid))}} @@ -77,29 +77,7 @@ func (a *Server) GetConstraintReference(ctx context.Context, req *restapi.GetCon Message: dsserr.Handle(ctx, stacktrace.NewErrorWithCode(dsserr.PermissionDenied, "Missing manager"))}} } - var response *restapi.GetConstraintReferenceResponse - action := func(ctx context.Context, r repos.Repository) (err error) { - constraint, err := r.GetConstraint(ctx, id) - switch { - case err == pgx.ErrNoRows: - return stacktrace.NewErrorWithCode(dsserr.NotFound, "Constraint %s not found", id.String()) - case err != nil: - return stacktrace.Propagate(err, "Unable to get Constraint from repo") - } - - if constraint.Manager != dssmodels.Manager(*req.Auth.ClientID) { - constraint.OVN = scdmodels.NoOvnPhrase - } - - // Return response to client - response = &restapi.GetConstraintReferenceResponse{ - ConstraintReference: *constraint.ToRest(), - } - - return nil - } - - _, err = a.Store.Transact(ctx, dssstore.NewFuncOperation(action)) + response, err := dssstore.TransactWithResult[repos.Repository, *restapi.GetConstraintReferenceResponse](ctx, a.Store, req) if err != nil { err = stacktrace.Propagate(err, "Could not get constraint") if stacktrace.GetCode(err) == dsserr.NotFound { @@ -355,37 +333,13 @@ func (a *Server) QueryConstraintReferences(ctx context.Context, req *restapi.Que } // Parse area of interest to common Volume4D - vol4, err := scdmodels.Volume4DFromSCDRest(aoi) + _, err := scdmodels.Volume4DFromSCDRest(aoi) if err != nil { return restapi.QueryConstraintReferencesResponseSet{Response400: &restapi.ErrorResponse{ Message: dsserr.Handle(ctx, stacktrace.PropagateWithCode(err, dsserr.BadRequest, "Failed to convert to internal geometry model"))}} } - var response *restapi.QueryConstraintReferencesResponse - action := func(ctx context.Context, r repos.Repository) (err error) { - // Perform search query on Store - constraints, err := r.SearchConstraints(ctx, vol4) - if err != nil { - return err - } - - // Create response for client - response = &restapi.QueryConstraintReferencesResponse{ - ConstraintReferences: make([]restapi.ConstraintReference, 0, len(constraints)), - } - for _, constraint := range constraints { - p := constraint.ToRest() - if constraint.Manager != dssmodels.Manager(*req.Auth.ClientID) { - noOvnPhrase := restapi.EntityOVN(scdmodels.NoOvnPhrase) - p.Ovn = &noOvnPhrase - } - response.ConstraintReferences = append(response.ConstraintReferences, *p) - } - - return nil - } - - _, err = a.Store.Transact(ctx, dssstore.NewFuncOperation(action)) + response, err := dssstore.TransactWithResult[repos.Repository, *restapi.QueryConstraintReferencesResponse](ctx, a.Store, req) if err != nil { return restapi.QueryConstraintReferencesResponseSet{Response500: &api.InternalServerErrorBody{ ErrorMessage: *dsserr.Handle(ctx, stacktrace.Propagate(err, "Got an unexpected error"))}}