Return OperationID from release-submissions #278

Merged
Quaternions merged 5 commits from release-op into staging 2025-09-23 22:31:06 +00:00
12 changed files with 89 additions and 34 deletions

View File

@@ -1164,6 +1164,10 @@ paths:
responses:
"201":
description: Successful response
content:
application/json:
schema:
$ref: "#/components/schemas/OperationID"
default:
description: General Error
content:

View File

@@ -319,7 +319,7 @@ type Invoker interface {
// Release a set of uploaded maps. Role SubmissionRelease.
//
// POST /release-submissions
ReleaseSubmissions(ctx context.Context, request []ReleaseInfo) error
ReleaseSubmissions(ctx context.Context, request []ReleaseInfo) (*OperationID, error)
// SessionRoles invokes sessionRoles operation.
//
// Get list of roles for the current session.
@@ -6422,12 +6422,12 @@ func (c *Client) sendListSubmissions(ctx context.Context, params ListSubmissions
// Release a set of uploaded maps. Role SubmissionRelease.
//
// POST /release-submissions
func (c *Client) ReleaseSubmissions(ctx context.Context, request []ReleaseInfo) error {
_, err := c.sendReleaseSubmissions(ctx, request)
return err
func (c *Client) ReleaseSubmissions(ctx context.Context, request []ReleaseInfo) (*OperationID, error) {
res, err := c.sendReleaseSubmissions(ctx, request)
return res, err
}
func (c *Client) sendReleaseSubmissions(ctx context.Context, request []ReleaseInfo) (res *ReleaseSubmissionsCreated, err error) {
func (c *Client) sendReleaseSubmissions(ctx context.Context, request []ReleaseInfo) (res *OperationID, err error) {
otelAttrs := []attribute.KeyValue{
otelogen.OperationID("releaseSubmissions"),
semconv.HTTPRequestMethodKey.String("POST"),

View File

@@ -8968,7 +8968,7 @@ func (s *Server) handleReleaseSubmissionsRequest(args [0]string, argsEscaped boo
}
}()
var response *ReleaseSubmissionsCreated
var response *OperationID
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
@@ -8983,7 +8983,7 @@ func (s *Server) handleReleaseSubmissionsRequest(args [0]string, argsEscaped boo
type (
Request = []ReleaseInfo
Params = struct{}
Response = *ReleaseSubmissionsCreated
Response = *OperationID
)
response, err = middleware.HookMiddleware[
Request,
@@ -8994,12 +8994,12 @@ func (s *Server) handleReleaseSubmissionsRequest(args [0]string, argsEscaped boo
mreq,
nil,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
err = s.h.ReleaseSubmissions(ctx, request)
response, err = s.h.ReleaseSubmissions(ctx, request)
return response, err
},
)
} else {
err = s.h.ReleaseSubmissions(ctx, request)
response, err = s.h.ReleaseSubmissions(ctx, request)
}
if err != nil {
if errRes, ok := errors.Into[*ErrorStatusCode](err); ok {

View File

@@ -3715,11 +3715,52 @@ func decodeListSubmissionsResponse(resp *http.Response) (res *Submissions, _ err
return res, errors.Wrap(defRes, "error")
}
func decodeReleaseSubmissionsResponse(resp *http.Response) (res *ReleaseSubmissionsCreated, _ error) {
func decodeReleaseSubmissionsResponse(resp *http.Response) (res *OperationID, _ error) {
switch resp.StatusCode {
case 201:
// Code 201.
return &ReleaseSubmissionsCreated{}, nil
ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
if err != nil {
return res, errors.Wrap(err, "parse media type")
}
switch {
case ct == "application/json":
buf, err := io.ReadAll(resp.Body)
if err != nil {
return res, err
}
d := jx.DecodeBytes(buf)
var response OperationID
if err := func() error {
if err := response.Decode(d); err != nil {
return err
}
if err := d.Skip(); err != io.EOF {
return errors.New("unexpected trailing data")
}
return nil
}(); err != nil {
err = &ogenerrors.DecodeBodyError{
ContentType: ct,
Body: buf,
Err: err,
}
return res, err
}
// Validate response.
if err := func() error {
if err := response.Validate(); err != nil {
return err
}
return nil
}(); err != nil {
return res, errors.Wrap(err, "validate")
}
return &response, nil
default:
return res, validate.InvalidContentType(ct)
}
}
// Convenient error response.
defRes, err := func() (res *ErrorStatusCode, err error) {

View File

@@ -498,10 +498,17 @@ func encodeListSubmissionsResponse(response *Submissions, w http.ResponseWriter,
return nil
}
func encodeReleaseSubmissionsResponse(response *ReleaseSubmissionsCreated, w http.ResponseWriter, span trace.Span) error {
func encodeReleaseSubmissionsResponse(response *OperationID, w http.ResponseWriter, span trace.Span) error {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(201)
span.SetStatus(codes.Ok, http.StatusText(201))
e := new(jx.Encoder)
response.Encode(e)
if _, err := e.WriteTo(w); err != nil {
return errors.Wrap(err, "write")
}
return nil
}

View File

@@ -941,9 +941,6 @@ func (s *ReleaseInfo) SetDate(val time.Time) {
s.Date = val
}
// ReleaseSubmissionsCreated is response for ReleaseSubmissions operation.
type ReleaseSubmissionsCreated struct{}
// Ref: #/components/schemas/Roles
type Roles struct {
Roles int32 `json:"Roles"`

View File

@@ -298,7 +298,7 @@ type Handler interface {
// Release a set of uploaded maps. Role SubmissionRelease.
//
// POST /release-submissions
ReleaseSubmissions(ctx context.Context, req []ReleaseInfo) error
ReleaseSubmissions(ctx context.Context, req []ReleaseInfo) (*OperationID, error)
// SessionRoles implements sessionRoles operation.
//
// Get list of roles for the current session.

View File

@@ -444,8 +444,8 @@ func (UnimplementedHandler) ListSubmissions(ctx context.Context, params ListSubm
// Release a set of uploaded maps. Role SubmissionRelease.
//
// POST /release-submissions
func (UnimplementedHandler) ReleaseSubmissions(ctx context.Context, req []ReleaseInfo) error {
return ht.ErrNotImplemented
func (UnimplementedHandler) ReleaseSubmissions(ctx context.Context, req []ReleaseInfo) (r *OperationID, _ error) {
return r, ht.ErrNotImplemented
}
// SessionRoles implements sessionRoles operation.

View File

@@ -1034,24 +1034,24 @@ func (svc *Service) ActionSubmissionAccepted(ctx context.Context, params api.Act
// Release a set of uploaded maps.
//
// POST /release-submissions
func (svc *Service) ReleaseSubmissions(ctx context.Context, request []api.ReleaseInfo) error {
func (svc *Service) ReleaseSubmissions(ctx context.Context, request []api.ReleaseInfo) (*api.OperationID, error) {
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
if !ok {
return ErrUserInfo
return nil, ErrUserInfo
}
has_role, err := userInfo.HasRoleSubmissionRelease()
if err != nil {
return err
return nil, err
}
// check if caller has required role
if !has_role {
return ErrPermissionDeniedNeedRoleSubmissionRelease
return nil, ErrPermissionDeniedNeedRoleSubmissionRelease
}
userId, err := userInfo.GetUserID()
if err != nil {
return err
return nil, err
}
idList := make([]int64, len(request))
@@ -1062,16 +1062,16 @@ func (svc *Service) ReleaseSubmissions(ctx context.Context, request []api.Releas
// fetch submissions
submissions, err := svc.inner.GetSubmissionList(ctx, idList)
if err != nil {
return err
return nil, err
}
// check each submission to make sure it is ready to release
for _,submission := range submissions{
if submission.StatusID != model.SubmissionStatusUploaded{
return ErrReleaseInvalidStatus
return nil, ErrReleaseInvalidStatus
}
if submission.UploadedAssetID == 0{
return ErrReleaseNoUploadedAssetID
return nil, ErrReleaseNoUploadedAssetID
}
}
@@ -1098,7 +1098,7 @@ func (svc *Service) ReleaseSubmissions(ctx context.Context, request []api.Releas
StatusID: model.OperationStatusCreated,
})
if err != nil {
return err
return nil, err
}
// this is a map fix
@@ -1107,10 +1107,12 @@ func (svc *Service) ReleaseSubmissions(ctx context.Context, request []api.Releas
operation.ID,
)
if err != nil {
return err
return nil, err
}
return nil
return &api.OperationID{
OperationID: operation.ID,
}, nil
}
// CreateSubmissionAuditComment implements createSubmissionAuditComment operation.

View File

@@ -1,6 +1,6 @@
[package]
name = "submissions-api"
version = "0.9.1"
version = "0.10.0"
edition = "2024"
publish = ["strafesnet"]
repository = "https://git.itzana.me/StrafesNET/maps-service"

View File

@@ -263,7 +263,7 @@ impl Context{
).await.map_err(Error::Response)?
.json().await.map_err(Error::ReqwestJson)
}
pub async fn release_submissions(&self,config:ReleaseRequest<'_>)->Result<(),Error>{
pub async fn release_submissions(&self,config:ReleaseRequest<'_>)->Result<OperationIDResponse,Error>{
let url_raw=format!("{}/release-submissions",self.0.base_url);
let url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
@@ -271,8 +271,7 @@ impl Context{
response_ok(
self.0.post(url,body).await.map_err(Error::Reqwest)?
).await.map_err(Error::Response)?;
Ok(())
).await.map_err(Error::Response)?
.json().await.map_err(Error::ReqwestJson)
}
}

View File

@@ -548,3 +548,8 @@ pub struct ReleaseInfo{
pub struct ReleaseRequest<'a>{
pub schedule:&'a [ReleaseInfo],
}
#[allow(nonstandard_style)]
#[derive(Clone,Debug,serde::Deserialize)]
pub struct OperationIDResponse{
pub OperationID:OperationID,
}