From aa161a5365de37995f84db6f9417f82dad2f1e70 Mon Sep 17 00:00:00 2001 From: Alex <33497058+bexsoft@users.noreply.github.com> Date: Mon, 6 May 2024 15:38:53 -0600 Subject: [PATCH] Added VersionID support to Metadata Details (#3332) Signed-off-by: Benjamin Perez --- api/embedded_spec.go | 10 +++++++ .../object/get_object_metadata_parameters.go | 27 +++++++++++++++++++ .../object/get_object_metadata_urlbuilder.go | 11 +++++++- api/user_objects.go | 11 +++++--- api/user_objects_test.go | 5 +++- swagger.yml | 3 +++ web-app/src/api/consoleApi.ts | 1 + .../Objects/ListObjects/ObjectDetailPanel.tsx | 3 ++- .../Objects/Preview/PreviewFileContent.tsx | 3 ++- 9 files changed, 67 insertions(+), 7 deletions(-) diff --git a/api/embedded_spec.go b/api/embedded_spec.go index a10c80d41..245a943ca 100644 --- a/api/embedded_spec.go +++ b/api/embedded_spec.go @@ -1762,6 +1762,11 @@ func init() { "name": "prefix", "in": "query", "required": true + }, + { + "type": "string", + "name": "versionID", + "in": "query" } ], "responses": { @@ -10974,6 +10979,11 @@ func init() { "name": "prefix", "in": "query", "required": true + }, + { + "type": "string", + "name": "versionID", + "in": "query" } ], "responses": { diff --git a/api/operations/object/get_object_metadata_parameters.go b/api/operations/object/get_object_metadata_parameters.go index a47b0439d..7a4e4c6a7 100644 --- a/api/operations/object/get_object_metadata_parameters.go +++ b/api/operations/object/get_object_metadata_parameters.go @@ -59,6 +59,10 @@ type GetObjectMetadataParams struct { In: query */ Prefix string + /* + In: query + */ + VersionID *string } // BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface @@ -81,6 +85,11 @@ func (o *GetObjectMetadataParams) BindRequest(r *http.Request, route *middleware if err := o.bindPrefix(qPrefix, qhkPrefix, route.Formats); err != nil { res = append(res, err) } + + qVersionID, qhkVersionID, _ := qs.GetOK("versionID") + if err := o.bindVersionID(qVersionID, qhkVersionID, route.Formats); err != nil { + res = append(res, err) + } if len(res) > 0 { return errors.CompositeValidationError(res...) } @@ -121,3 +130,21 @@ func (o *GetObjectMetadataParams) bindPrefix(rawData []string, hasKey bool, form return nil } + +// bindVersionID binds and validates parameter VersionID from query. +func (o *GetObjectMetadataParams) bindVersionID(rawData []string, hasKey bool, formats strfmt.Registry) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + // Required: false + // AllowEmptyValue: false + + if raw == "" { // empty values pass all other validations + return nil + } + o.VersionID = &raw + + return nil +} diff --git a/api/operations/object/get_object_metadata_urlbuilder.go b/api/operations/object/get_object_metadata_urlbuilder.go index 1c28cebdd..fbdb1fd59 100644 --- a/api/operations/object/get_object_metadata_urlbuilder.go +++ b/api/operations/object/get_object_metadata_urlbuilder.go @@ -33,7 +33,8 @@ import ( type GetObjectMetadataURL struct { BucketName string - Prefix string + Prefix string + VersionID *string _basePath string // avoid unkeyed usage @@ -81,6 +82,14 @@ func (o *GetObjectMetadataURL) Build() (*url.URL, error) { qs.Set("prefix", prefixQ) } + var versionIDQ string + if o.VersionID != nil { + versionIDQ = *o.VersionID + } + if versionIDQ != "" { + qs.Set("versionID", versionIDQ) + } + _result.RawQuery = qs.Encode() return &_result, nil diff --git a/api/user_objects.go b/api/user_objects.go index f38ebba54..11929a584 100644 --- a/api/user_objects.go +++ b/api/user_objects.go @@ -1338,6 +1338,7 @@ func getObjectMetadataResponse(session *models.Principal, params objectApi.GetOb // defining the client to be used minioClient := minioClient{client: mClient} var prefix string + var versionID string if params.Prefix != "" { encodedPrefix := SanitizeEncodedPrefix(params.Prefix) @@ -1348,7 +1349,11 @@ func getObjectMetadataResponse(session *models.Principal, params objectApi.GetOb prefix = string(decodedPrefix) } - objectInfo, err := getObjectInfo(ctx, minioClient, params.BucketName, prefix) + if params.VersionID != nil { + versionID = *params.VersionID + } + + objectInfo, err := getObjectInfo(ctx, minioClient, params.BucketName, prefix, versionID) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -1358,8 +1363,8 @@ func getObjectMetadataResponse(session *models.Principal, params objectApi.GetOb return metadata, nil } -func getObjectInfo(ctx context.Context, client MinioClient, bucketName, prefix string) (minio.ObjectInfo, error) { - objectData, err := client.statObject(ctx, bucketName, prefix, minio.GetObjectOptions{}) +func getObjectInfo(ctx context.Context, client MinioClient, bucketName, prefix, versionID string) (minio.ObjectInfo, error) { + objectData, err := client.statObject(ctx, bucketName, prefix, minio.GetObjectOptions{VersionID: versionID}) if err != nil { return minio.ObjectInfo{}, err } diff --git a/api/user_objects_test.go b/api/user_objects_test.go index 2f98da8a1..a6368e6ca 100644 --- a/api/user_objects_test.go +++ b/api/user_objects_test.go @@ -1293,6 +1293,7 @@ func Test_getObjectInfo(t *testing.T) { type args struct { bucketName string prefix string + versionID string statFunc func(ctx context.Context, bucketName string, prefix string, opts minio.GetObjectOptions) (objectInfo minio.ObjectInfo, err error) } tests := []struct { @@ -1305,6 +1306,7 @@ func Test_getObjectInfo(t *testing.T) { args: args{ bucketName: "bucket1", prefix: "someprefix", + versionID: "version123", statFunc: func(_ context.Context, _ string, _ string, _ minio.GetObjectOptions) (minio.ObjectInfo, error) { return minio.ObjectInfo{}, nil }, @@ -1316,6 +1318,7 @@ func Test_getObjectInfo(t *testing.T) { args: args{ bucketName: "bucket2", prefix: "someprefi2", + versionID: "version456", statFunc: func(_ context.Context, _ string, _ string, _ minio.GetObjectOptions) (minio.ObjectInfo, error) { return minio.ObjectInfo{}, errors.New("new Error") }, @@ -1326,7 +1329,7 @@ func Test_getObjectInfo(t *testing.T) { for _, tt := range tests { t.Run(tt.test, func(_ *testing.T) { minioStatObjectMock = tt.args.statFunc - _, err := getObjectInfo(ctx, client, tt.args.bucketName, tt.args.prefix) + _, err := getObjectInfo(ctx, client, tt.args.bucketName, tt.args.prefix, tt.args.versionID) if tt.wantError != nil { fmt.Println(t.Name()) tAssert.Equal(tt.wantError.Error(), err.Error(), fmt.Sprintf("getObjectInfo() error: `%s`, wantErr: `%s`", err, tt.wantError)) diff --git a/swagger.yml b/swagger.yml index e9c0e1355..f217a1e26 100644 --- a/swagger.yml +++ b/swagger.yml @@ -703,6 +703,9 @@ paths: in: query required: true type: string + - name: versionID + in: query + type: string responses: 200: description: A successful response. diff --git a/web-app/src/api/consoleApi.ts b/web-app/src/api/consoleApi.ts index 162d46837..b1f705e6f 100644 --- a/web-app/src/api/consoleApi.ts +++ b/web-app/src/api/consoleApi.ts @@ -2397,6 +2397,7 @@ export class Api< bucketName: string, query: { prefix: string; + versionID?: string; }, params: RequestParams = {}, ) => diff --git a/web-app/src/screens/Console/Buckets/ListBuckets/Objects/ListObjects/ObjectDetailPanel.tsx b/web-app/src/screens/Console/Buckets/ListBuckets/Objects/ListObjects/ObjectDetailPanel.tsx index 20ae77dbe..2079058fa 100644 --- a/web-app/src/screens/Console/Buckets/ListBuckets/Objects/ListObjects/ObjectDetailPanel.tsx +++ b/web-app/src/screens/Console/Buckets/ListBuckets/Objects/ListObjects/ObjectDetailPanel.tsx @@ -216,6 +216,7 @@ const ObjectDetailPanel = ({ api.buckets .getObjectMetadata(bucketName, { prefix: internalPaths, + versionID: actualInfo?.version_id || "", }) .then((res) => { let metadata = get(res.data, "objectMetadata", {}); @@ -228,7 +229,7 @@ const ObjectDetailPanel = ({ setLoadingMetadata(false); }); } - }, [bucketName, internalPaths, loadMetadata]); + }, [bucketName, internalPaths, loadMetadata, actualInfo?.version_id]); let tagKeys: string[] = []; diff --git a/web-app/src/screens/Console/Buckets/ListBuckets/Objects/Preview/PreviewFileContent.tsx b/web-app/src/screens/Console/Buckets/ListBuckets/Objects/Preview/PreviewFileContent.tsx index fbd25d478..72c1546a6 100644 --- a/web-app/src/screens/Console/Buckets/ListBuckets/Objects/Preview/PreviewFileContent.tsx +++ b/web-app/src/screens/Console/Buckets/ListBuckets/Objects/Preview/PreviewFileContent.tsx @@ -51,6 +51,7 @@ const PreviewFile = ({ api.buckets .getObjectMetadata(bucketName, { prefix: encodedPath, + versionID: actualInfo.version_id || "", }) .then((res) => { let metadata = get(res.data, "objectMetadata", {}); @@ -66,7 +67,7 @@ const PreviewFile = ({ setIsMetaDataLoaded(true); }); } - }, [bucketName, objectName, isMetaDataLoaded]); + }, [bucketName, objectName, isMetaDataLoaded, actualInfo.version_id]); useEffect(() => { if (bucketName && objectName) {