From fc2b3183a43b8753d8166b6fa407dc9f2b19ba7e Mon Sep 17 00:00:00 2001 From: Nir Ozery Date: Tue, 20 Feb 2024 14:01:43 +0200 Subject: [PATCH] CR Fixes --- api/swagger.yml | 30 ++++++----- clients/java-legacy/api/openapi.yaml | 49 ++++++++++++------ clients/java-legacy/docs/ObjectsApi.md | 8 +-- clients/java-legacy/docs/StagingApi.md | 6 ++- clients/java-legacy/docs/StagingMetadata.md | 1 - .../io/lakefs/clients/api/ObjectsApi.java | 26 +++++----- .../io/lakefs/clients/api/StagingApi.java | 26 ++++++---- .../clients/api/model/StagingMetadata.java | 33 +----------- .../io/lakefs/clients/api/ObjectsApiTest.java | 4 +- .../io/lakefs/clients/api/StagingApiTest.java | 3 +- .../api/model/StagingMetadataTest.java | 8 --- clients/java/api/openapi.yaml | 51 ++++++++++++------- clients/java/docs/ObjectsApi.md | 8 +-- clients/java/docs/StagingApi.md | 5 +- clients/java/docs/StagingMetadata.md | 1 - .../io/lakefs/clients/sdk/ObjectsApi.java | 40 +++++++-------- .../io/lakefs/clients/sdk/StagingApi.java | 37 ++++++++++---- .../clients/sdk/model/StagingMetadata.java | 32 +----------- .../io/lakefs/clients/sdk/ObjectsApiTest.java | 4 +- .../io/lakefs/clients/sdk/StagingApiTest.java | 2 + .../sdk/model/StagingMetadataTest.java | 8 --- clients/python-legacy/docs/ObjectsApi.md | 6 +-- clients/python-legacy/docs/StagingApi.md | 12 ++++- clients/python-legacy/docs/StagingMetadata.md | 1 - .../lakefs_client/api/objects_api.py | 12 ++--- .../lakefs_client/api/staging_api.py | 13 +++++ .../lakefs_client/model/staging_metadata.py | 4 -- clients/python/docs/ObjectsApi.md | 8 +-- clients/python/docs/StagingApi.md | 6 ++- clients/python/docs/StagingMetadata.md | 1 - clients/python/lakefs_sdk/api/objects_api.py | 20 ++++---- clients/python/lakefs_sdk/api/staging_api.py | 22 +++++--- .../lakefs_sdk/models/staging_metadata.py | 6 +-- clients/python/test/test_staging_metadata.py | 3 +- docs/assets/js/swagger.yml | 30 ++++++----- pkg/api/controller.go | 7 +-- pkg/api/controller_test.go | 16 +++--- pkg/graveler/graveler_test.go | 2 + 38 files changed, 283 insertions(+), 268 deletions(-) diff --git a/api/swagger.yml b/api/swagger.yml index 6c17051cff6..5e7ac0330e8 100644 --- a/api/swagger.yml +++ b/api/swagger.yml @@ -69,6 +69,17 @@ components: description: delimiter used to group common prefixes by schema: type: string + + IfNonMatch: + in: header + name: If-None-Match + description: | + Currently supports only "*" to allow uploading an object only if one doesn't exist yet. + example: "*" + required: false + schema: + type: string + pattern: '^\*$' # Currently, only "*" is supported responses: NotFoundOrNoACL: @@ -1299,9 +1310,6 @@ components: force: type: boolean default: false - if_absent: - type: boolean - default: false required: - staging - checksum @@ -4167,6 +4175,10 @@ paths: application/json: schema: $ref: "#/components/schemas/StagingMetadata" + + parameters: + - $ref: "#/components/parameters/IfNonMatch" + responses: 200: # This actually violates HTTP, which requires returning 201 if a new object was @@ -4400,6 +4412,7 @@ paths: format: binary parameters: + - $ref: "#/components/parameters/IfNonMatch" - in: query name: storageClass description: Deprecated, this capability will not be supported in future releases. @@ -4407,17 +4420,6 @@ paths: deprecated: true schema: type: string - - in: header - name: If-None-Match - description: | - Currently supports only "*" to allow uploading an object only if one doesn't exist yet. - Deprecated, this capability will not be supported in future releases. - example: "*" - required: false - deprecated: true - schema: - type: string - pattern: '^\*$' # Currently, only "*" is supported - in: query name: force required: false diff --git a/clients/java-legacy/api/openapi.yaml b/clients/java-legacy/api/openapi.yaml index 180170845e3..30d5ee0c088 100644 --- a/clients/java-legacy/api/openapi.yaml +++ b/clients/java-legacy/api/openapi.yaml @@ -4516,6 +4516,17 @@ paths: schema: type: string style: form + - description: | + Currently supports only "*" to allow uploading an object only if one doesn't exist yet. + example: '*' + explode: false + in: header + name: If-None-Match + required: false + schema: + pattern: ^\*$ + type: string + style: simple requestBody: content: application/json: @@ -4912,19 +4923,8 @@ paths: schema: type: string style: form - - deprecated: true - description: Deprecated, this capability will not be supported in future releases. - explode: true - in: query - name: storageClass - required: false - schema: - type: string - style: form - - deprecated: true - description: | + - description: | Currently supports only "*" to allow uploading an object only if one doesn't exist yet. - Deprecated, this capability will not be supported in future releases. example: '*' explode: false in: header @@ -4934,6 +4934,15 @@ paths: pattern: ^\*$ type: string style: simple + - deprecated: true + description: Deprecated, this capability will not be supported in future releases. + explode: true + in: query + name: storageClass + required: false + schema: + type: string + style: form - explode: true in: query name: force @@ -6553,6 +6562,18 @@ components: schema: type: string style: form + IfNonMatch: + description: | + Currently supports only "*" to allow uploading an object only if one doesn't exist yet. + example: '*' + explode: false + in: header + name: If-None-Match + required: false + schema: + pattern: ^\*$ + type: string + style: simple requestBodies: inline_object_1: content: @@ -8269,7 +8290,6 @@ components: StagingMetadata: description: information about uploaded object example: - if_absent: false size_bytes: 0 user_metadata: key: user_metadata @@ -8300,9 +8320,6 @@ components: force: default: false type: boolean - if_absent: - default: false - type: boolean required: - checksum - size_bytes diff --git a/clients/java-legacy/docs/ObjectsApi.md b/clients/java-legacy/docs/ObjectsApi.md index dd8ddce0eba..d05b583a999 100644 --- a/clients/java-legacy/docs/ObjectsApi.md +++ b/clients/java-legacy/docs/ObjectsApi.md @@ -822,7 +822,7 @@ Name | Type | Description | Notes # **uploadObject** -> ObjectStats uploadObject(repository, branch, path, storageClass, ifNoneMatch, force, content) +> ObjectStats uploadObject(repository, branch, path, ifNoneMatch, storageClass, force, content) @@ -872,12 +872,12 @@ public class Example { String repository = "repository_example"; // String | String branch = "branch_example"; // String | String path = "path_example"; // String | relative to the branch + String ifNoneMatch = "*"; // String | Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. String storageClass = "storageClass_example"; // String | Deprecated, this capability will not be supported in future releases. - String ifNoneMatch = "*"; // String | Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. Deprecated, this capability will not be supported in future releases. Boolean force = false; // Boolean | File content = new File("/path/to/file"); // File | Only a single file per upload which must be named \\\"content\\\". try { - ObjectStats result = apiInstance.uploadObject(repository, branch, path, storageClass, ifNoneMatch, force, content); + ObjectStats result = apiInstance.uploadObject(repository, branch, path, ifNoneMatch, storageClass, force, content); System.out.println(result); } catch (ApiException e) { System.err.println("Exception when calling ObjectsApi#uploadObject"); @@ -897,8 +897,8 @@ Name | Type | Description | Notes **repository** | **String**| | **branch** | **String**| | **path** | **String**| relative to the branch | + **ifNoneMatch** | **String**| Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. | [optional] **storageClass** | **String**| Deprecated, this capability will not be supported in future releases. | [optional] - **ifNoneMatch** | **String**| Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. Deprecated, this capability will not be supported in future releases. | [optional] **force** | **Boolean**| | [optional] [default to false] **content** | **File**| Only a single file per upload which must be named \\\"content\\\". | [optional] diff --git a/clients/java-legacy/docs/StagingApi.md b/clients/java-legacy/docs/StagingApi.md index 05ff284a7bd..185651c41e9 100644 --- a/clients/java-legacy/docs/StagingApi.md +++ b/clients/java-legacy/docs/StagingApi.md @@ -108,7 +108,7 @@ Name | Type | Description | Notes # **linkPhysicalAddress** -> ObjectStats linkPhysicalAddress(repository, branch, path, stagingMetadata) +> ObjectStats linkPhysicalAddress(repository, branch, path, stagingMetadata, ifNoneMatch) associate staging on this physical address with a path @@ -161,8 +161,9 @@ public class Example { String branch = "branch_example"; // String | String path = "path_example"; // String | relative to the branch StagingMetadata stagingMetadata = new StagingMetadata(); // StagingMetadata | + String ifNoneMatch = "*"; // String | Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. try { - ObjectStats result = apiInstance.linkPhysicalAddress(repository, branch, path, stagingMetadata); + ObjectStats result = apiInstance.linkPhysicalAddress(repository, branch, path, stagingMetadata, ifNoneMatch); System.out.println(result); } catch (ApiException e) { System.err.println("Exception when calling StagingApi#linkPhysicalAddress"); @@ -183,6 +184,7 @@ Name | Type | Description | Notes **branch** | **String**| | **path** | **String**| relative to the branch | **stagingMetadata** | [**StagingMetadata**](StagingMetadata.md)| | + **ifNoneMatch** | **String**| Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. | [optional] ### Return type diff --git a/clients/java-legacy/docs/StagingMetadata.md b/clients/java-legacy/docs/StagingMetadata.md index 13f67097c93..4228387befd 100644 --- a/clients/java-legacy/docs/StagingMetadata.md +++ b/clients/java-legacy/docs/StagingMetadata.md @@ -14,7 +14,6 @@ Name | Type | Description | Notes **userMetadata** | **Map<String, String>** | | [optional] **contentType** | **String** | Object media type | [optional] **force** | **Boolean** | | [optional] -**ifAbsent** | **Boolean** | | [optional] diff --git a/clients/java-legacy/src/main/java/io/lakefs/clients/api/ObjectsApi.java b/clients/java-legacy/src/main/java/io/lakefs/clients/api/ObjectsApi.java index 7b1c83c3165..502d295a30a 100644 --- a/clients/java-legacy/src/main/java/io/lakefs/clients/api/ObjectsApi.java +++ b/clients/java-legacy/src/main/java/io/lakefs/clients/api/ObjectsApi.java @@ -1414,8 +1414,8 @@ public okhttp3.Call statObjectAsync(String repository, String ref, String path, * @param repository (required) * @param branch (required) * @param path relative to the branch (required) + * @param ifNoneMatch Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. (optional) * @param storageClass Deprecated, this capability will not be supported in future releases. (optional) - * @param ifNoneMatch Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. Deprecated, this capability will not be supported in future releases. (optional) * @param force (optional, default to false) * @param content Only a single file per upload which must be named \\\"content\\\". (optional) * @param _callback Callback for upload/download progress @@ -1434,7 +1434,7 @@ public okhttp3.Call statObjectAsync(String repository, String ref, String path, 0 Internal Server Error - */ - public okhttp3.Call uploadObjectCall(String repository, String branch, String path, String storageClass, String ifNoneMatch, Boolean force, File content, final ApiCallback _callback) throws ApiException { + public okhttp3.Call uploadObjectCall(String repository, String branch, String path, String ifNoneMatch, String storageClass, Boolean force, File content, final ApiCallback _callback) throws ApiException { Object localVarPostBody = null; // create path and map variables @@ -1487,7 +1487,7 @@ public okhttp3.Call uploadObjectCall(String repository, String branch, String pa } @SuppressWarnings("rawtypes") - private okhttp3.Call uploadObjectValidateBeforeCall(String repository, String branch, String path, String storageClass, String ifNoneMatch, Boolean force, File content, final ApiCallback _callback) throws ApiException { + private okhttp3.Call uploadObjectValidateBeforeCall(String repository, String branch, String path, String ifNoneMatch, String storageClass, Boolean force, File content, final ApiCallback _callback) throws ApiException { // verify the required parameter 'repository' is set if (repository == null) { @@ -1505,7 +1505,7 @@ private okhttp3.Call uploadObjectValidateBeforeCall(String repository, String br } - okhttp3.Call localVarCall = uploadObjectCall(repository, branch, path, storageClass, ifNoneMatch, force, content, _callback); + okhttp3.Call localVarCall = uploadObjectCall(repository, branch, path, ifNoneMatch, storageClass, force, content, _callback); return localVarCall; } @@ -1516,8 +1516,8 @@ private okhttp3.Call uploadObjectValidateBeforeCall(String repository, String br * @param repository (required) * @param branch (required) * @param path relative to the branch (required) + * @param ifNoneMatch Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. (optional) * @param storageClass Deprecated, this capability will not be supported in future releases. (optional) - * @param ifNoneMatch Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. Deprecated, this capability will not be supported in future releases. (optional) * @param force (optional, default to false) * @param content Only a single file per upload which must be named \\\"content\\\". (optional) * @return ObjectStats @@ -1535,8 +1535,8 @@ private okhttp3.Call uploadObjectValidateBeforeCall(String repository, String br 0 Internal Server Error - */ - public ObjectStats uploadObject(String repository, String branch, String path, String storageClass, String ifNoneMatch, Boolean force, File content) throws ApiException { - ApiResponse localVarResp = uploadObjectWithHttpInfo(repository, branch, path, storageClass, ifNoneMatch, force, content); + public ObjectStats uploadObject(String repository, String branch, String path, String ifNoneMatch, String storageClass, Boolean force, File content) throws ApiException { + ApiResponse localVarResp = uploadObjectWithHttpInfo(repository, branch, path, ifNoneMatch, storageClass, force, content); return localVarResp.getData(); } @@ -1546,8 +1546,8 @@ public ObjectStats uploadObject(String repository, String branch, String path, S * @param repository (required) * @param branch (required) * @param path relative to the branch (required) + * @param ifNoneMatch Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. (optional) * @param storageClass Deprecated, this capability will not be supported in future releases. (optional) - * @param ifNoneMatch Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. Deprecated, this capability will not be supported in future releases. (optional) * @param force (optional, default to false) * @param content Only a single file per upload which must be named \\\"content\\\". (optional) * @return ApiResponse<ObjectStats> @@ -1565,8 +1565,8 @@ public ObjectStats uploadObject(String repository, String branch, String path, S 0 Internal Server Error - */ - public ApiResponse uploadObjectWithHttpInfo(String repository, String branch, String path, String storageClass, String ifNoneMatch, Boolean force, File content) throws ApiException { - okhttp3.Call localVarCall = uploadObjectValidateBeforeCall(repository, branch, path, storageClass, ifNoneMatch, force, content, null); + public ApiResponse uploadObjectWithHttpInfo(String repository, String branch, String path, String ifNoneMatch, String storageClass, Boolean force, File content) throws ApiException { + okhttp3.Call localVarCall = uploadObjectValidateBeforeCall(repository, branch, path, ifNoneMatch, storageClass, force, content, null); Type localVarReturnType = new TypeToken(){}.getType(); return localVarApiClient.execute(localVarCall, localVarReturnType); } @@ -1577,8 +1577,8 @@ public ApiResponse uploadObjectWithHttpInfo(String repository, Stri * @param repository (required) * @param branch (required) * @param path relative to the branch (required) + * @param ifNoneMatch Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. (optional) * @param storageClass Deprecated, this capability will not be supported in future releases. (optional) - * @param ifNoneMatch Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. Deprecated, this capability will not be supported in future releases. (optional) * @param force (optional, default to false) * @param content Only a single file per upload which must be named \\\"content\\\". (optional) * @param _callback The callback to be executed when the API call finishes @@ -1597,9 +1597,9 @@ public ApiResponse uploadObjectWithHttpInfo(String repository, Stri 0 Internal Server Error - */ - public okhttp3.Call uploadObjectAsync(String repository, String branch, String path, String storageClass, String ifNoneMatch, Boolean force, File content, final ApiCallback _callback) throws ApiException { + public okhttp3.Call uploadObjectAsync(String repository, String branch, String path, String ifNoneMatch, String storageClass, Boolean force, File content, final ApiCallback _callback) throws ApiException { - okhttp3.Call localVarCall = uploadObjectValidateBeforeCall(repository, branch, path, storageClass, ifNoneMatch, force, content, _callback); + okhttp3.Call localVarCall = uploadObjectValidateBeforeCall(repository, branch, path, ifNoneMatch, storageClass, force, content, _callback); Type localVarReturnType = new TypeToken(){}.getType(); localVarApiClient.executeAsync(localVarCall, localVarReturnType, _callback); return localVarCall; diff --git a/clients/java-legacy/src/main/java/io/lakefs/clients/api/StagingApi.java b/clients/java-legacy/src/main/java/io/lakefs/clients/api/StagingApi.java index 023c31730c3..119ce2faf88 100644 --- a/clients/java-legacy/src/main/java/io/lakefs/clients/api/StagingApi.java +++ b/clients/java-legacy/src/main/java/io/lakefs/clients/api/StagingApi.java @@ -222,6 +222,7 @@ public okhttp3.Call getPhysicalAddressAsync(String repository, String branch, St * @param branch (required) * @param path relative to the branch (required) * @param stagingMetadata (required) + * @param ifNoneMatch Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. (optional) * @param _callback Callback for upload/download progress * @return Call to execute * @throws ApiException If fail to serialize the request body object @@ -238,7 +239,7 @@ public okhttp3.Call getPhysicalAddressAsync(String repository, String branch, St 0 Internal Server Error - */ - public okhttp3.Call linkPhysicalAddressCall(String repository, String branch, String path, StagingMetadata stagingMetadata, final ApiCallback _callback) throws ApiException { + public okhttp3.Call linkPhysicalAddressCall(String repository, String branch, String path, StagingMetadata stagingMetadata, String ifNoneMatch, final ApiCallback _callback) throws ApiException { Object localVarPostBody = stagingMetadata; // create path and map variables @@ -256,6 +257,10 @@ public okhttp3.Call linkPhysicalAddressCall(String repository, String branch, St localVarQueryParams.addAll(localVarApiClient.parameterToPair("path", path)); } + if (ifNoneMatch != null) { + localVarHeaderParams.put("If-None-Match", localVarApiClient.parameterToString(ifNoneMatch)); + } + final String[] localVarAccepts = { "application/json" }; @@ -275,7 +280,7 @@ public okhttp3.Call linkPhysicalAddressCall(String repository, String branch, St } @SuppressWarnings("rawtypes") - private okhttp3.Call linkPhysicalAddressValidateBeforeCall(String repository, String branch, String path, StagingMetadata stagingMetadata, final ApiCallback _callback) throws ApiException { + private okhttp3.Call linkPhysicalAddressValidateBeforeCall(String repository, String branch, String path, StagingMetadata stagingMetadata, String ifNoneMatch, final ApiCallback _callback) throws ApiException { // verify the required parameter 'repository' is set if (repository == null) { @@ -298,7 +303,7 @@ private okhttp3.Call linkPhysicalAddressValidateBeforeCall(String repository, St } - okhttp3.Call localVarCall = linkPhysicalAddressCall(repository, branch, path, stagingMetadata, _callback); + okhttp3.Call localVarCall = linkPhysicalAddressCall(repository, branch, path, stagingMetadata, ifNoneMatch, _callback); return localVarCall; } @@ -310,6 +315,7 @@ private okhttp3.Call linkPhysicalAddressValidateBeforeCall(String repository, St * @param branch (required) * @param path relative to the branch (required) * @param stagingMetadata (required) + * @param ifNoneMatch Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. (optional) * @return ObjectStats * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body * @http.response.details @@ -325,8 +331,8 @@ private okhttp3.Call linkPhysicalAddressValidateBeforeCall(String repository, St 0 Internal Server Error - */ - public ObjectStats linkPhysicalAddress(String repository, String branch, String path, StagingMetadata stagingMetadata) throws ApiException { - ApiResponse localVarResp = linkPhysicalAddressWithHttpInfo(repository, branch, path, stagingMetadata); + public ObjectStats linkPhysicalAddress(String repository, String branch, String path, StagingMetadata stagingMetadata, String ifNoneMatch) throws ApiException { + ApiResponse localVarResp = linkPhysicalAddressWithHttpInfo(repository, branch, path, stagingMetadata, ifNoneMatch); return localVarResp.getData(); } @@ -337,6 +343,7 @@ public ObjectStats linkPhysicalAddress(String repository, String branch, String * @param branch (required) * @param path relative to the branch (required) * @param stagingMetadata (required) + * @param ifNoneMatch Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. (optional) * @return ApiResponse<ObjectStats> * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body * @http.response.details @@ -352,8 +359,8 @@ public ObjectStats linkPhysicalAddress(String repository, String branch, String 0 Internal Server Error - */ - public ApiResponse linkPhysicalAddressWithHttpInfo(String repository, String branch, String path, StagingMetadata stagingMetadata) throws ApiException { - okhttp3.Call localVarCall = linkPhysicalAddressValidateBeforeCall(repository, branch, path, stagingMetadata, null); + public ApiResponse linkPhysicalAddressWithHttpInfo(String repository, String branch, String path, StagingMetadata stagingMetadata, String ifNoneMatch) throws ApiException { + okhttp3.Call localVarCall = linkPhysicalAddressValidateBeforeCall(repository, branch, path, stagingMetadata, ifNoneMatch, null); Type localVarReturnType = new TypeToken(){}.getType(); return localVarApiClient.execute(localVarCall, localVarReturnType); } @@ -365,6 +372,7 @@ public ApiResponse linkPhysicalAddressWithHttpInfo(String repositor * @param branch (required) * @param path relative to the branch (required) * @param stagingMetadata (required) + * @param ifNoneMatch Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. (optional) * @param _callback The callback to be executed when the API call finishes * @return The request call * @throws ApiException If fail to process the API call, e.g. serializing the request body object @@ -381,9 +389,9 @@ public ApiResponse linkPhysicalAddressWithHttpInfo(String repositor 0 Internal Server Error - */ - public okhttp3.Call linkPhysicalAddressAsync(String repository, String branch, String path, StagingMetadata stagingMetadata, final ApiCallback _callback) throws ApiException { + public okhttp3.Call linkPhysicalAddressAsync(String repository, String branch, String path, StagingMetadata stagingMetadata, String ifNoneMatch, final ApiCallback _callback) throws ApiException { - okhttp3.Call localVarCall = linkPhysicalAddressValidateBeforeCall(repository, branch, path, stagingMetadata, _callback); + okhttp3.Call localVarCall = linkPhysicalAddressValidateBeforeCall(repository, branch, path, stagingMetadata, ifNoneMatch, _callback); Type localVarReturnType = new TypeToken(){}.getType(); localVarApiClient.executeAsync(localVarCall, localVarReturnType, _callback); return localVarCall; diff --git a/clients/java-legacy/src/main/java/io/lakefs/clients/api/model/StagingMetadata.java b/clients/java-legacy/src/main/java/io/lakefs/clients/api/model/StagingMetadata.java index 88d375b45b5..c8fedda6a6e 100644 --- a/clients/java-legacy/src/main/java/io/lakefs/clients/api/model/StagingMetadata.java +++ b/clients/java-legacy/src/main/java/io/lakefs/clients/api/model/StagingMetadata.java @@ -58,10 +58,6 @@ public class StagingMetadata { @SerializedName(SERIALIZED_NAME_FORCE) private Boolean force = false; - public static final String SERIALIZED_NAME_IF_ABSENT = "if_absent"; - @SerializedName(SERIALIZED_NAME_IF_ABSENT) - private Boolean ifAbsent = false; - public StagingMetadata staging(StagingLocation staging) { @@ -209,29 +205,6 @@ public void setForce(Boolean force) { } - public StagingMetadata ifAbsent(Boolean ifAbsent) { - - this.ifAbsent = ifAbsent; - return this; - } - - /** - * Get ifAbsent - * @return ifAbsent - **/ - @javax.annotation.Nullable - @ApiModelProperty(value = "") - - public Boolean getIfAbsent() { - return ifAbsent; - } - - - public void setIfAbsent(Boolean ifAbsent) { - this.ifAbsent = ifAbsent; - } - - @Override public boolean equals(Object o) { if (this == o) { @@ -246,13 +219,12 @@ public boolean equals(Object o) { Objects.equals(this.sizeBytes, stagingMetadata.sizeBytes) && Objects.equals(this.userMetadata, stagingMetadata.userMetadata) && Objects.equals(this.contentType, stagingMetadata.contentType) && - Objects.equals(this.force, stagingMetadata.force) && - Objects.equals(this.ifAbsent, stagingMetadata.ifAbsent); + Objects.equals(this.force, stagingMetadata.force); } @Override public int hashCode() { - return Objects.hash(staging, checksum, sizeBytes, userMetadata, contentType, force, ifAbsent); + return Objects.hash(staging, checksum, sizeBytes, userMetadata, contentType, force); } @Override @@ -265,7 +237,6 @@ public String toString() { sb.append(" userMetadata: ").append(toIndentedString(userMetadata)).append("\n"); sb.append(" contentType: ").append(toIndentedString(contentType)).append("\n"); sb.append(" force: ").append(toIndentedString(force)).append("\n"); - sb.append(" ifAbsent: ").append(toIndentedString(ifAbsent)).append("\n"); sb.append("}"); return sb.toString(); } diff --git a/clients/java-legacy/src/test/java/io/lakefs/clients/api/ObjectsApiTest.java b/clients/java-legacy/src/test/java/io/lakefs/clients/api/ObjectsApiTest.java index 9693a70393c..1ddf9b32ae0 100644 --- a/clients/java-legacy/src/test/java/io/lakefs/clients/api/ObjectsApiTest.java +++ b/clients/java-legacy/src/test/java/io/lakefs/clients/api/ObjectsApiTest.java @@ -201,11 +201,11 @@ public void uploadObjectTest() throws ApiException { String repository = null; String branch = null; String path = null; - String storageClass = null; String ifNoneMatch = null; + String storageClass = null; Boolean force = null; File content = null; - ObjectStats response = api.uploadObject(repository, branch, path, storageClass, ifNoneMatch, force, content); + ObjectStats response = api.uploadObject(repository, branch, path, ifNoneMatch, storageClass, force, content); // TODO: test validations } diff --git a/clients/java-legacy/src/test/java/io/lakefs/clients/api/StagingApiTest.java b/clients/java-legacy/src/test/java/io/lakefs/clients/api/StagingApiTest.java index f24e6e52155..7330716895e 100644 --- a/clients/java-legacy/src/test/java/io/lakefs/clients/api/StagingApiTest.java +++ b/clients/java-legacy/src/test/java/io/lakefs/clients/api/StagingApiTest.java @@ -67,7 +67,8 @@ public void linkPhysicalAddressTest() throws ApiException { String branch = null; String path = null; StagingMetadata stagingMetadata = null; - ObjectStats response = api.linkPhysicalAddress(repository, branch, path, stagingMetadata); + String ifNoneMatch = null; + ObjectStats response = api.linkPhysicalAddress(repository, branch, path, stagingMetadata, ifNoneMatch); // TODO: test validations } diff --git a/clients/java-legacy/src/test/java/io/lakefs/clients/api/model/StagingMetadataTest.java b/clients/java-legacy/src/test/java/io/lakefs/clients/api/model/StagingMetadataTest.java index 2ce9c650219..c6f0d0e5b17 100644 --- a/clients/java-legacy/src/test/java/io/lakefs/clients/api/model/StagingMetadataTest.java +++ b/clients/java-legacy/src/test/java/io/lakefs/clients/api/model/StagingMetadataTest.java @@ -92,12 +92,4 @@ public void forceTest() { // TODO: test force } - /** - * Test the property 'ifAbsent' - */ - @Test - public void ifAbsentTest() { - // TODO: test ifAbsent - } - } diff --git a/clients/java/api/openapi.yaml b/clients/java/api/openapi.yaml index af2e9f9715e..f0139ecc7e4 100644 --- a/clients/java/api/openapi.yaml +++ b/clients/java/api/openapi.yaml @@ -4516,6 +4516,17 @@ paths: schema: type: string style: form + - description: | + Currently supports only "*" to allow uploading an object only if one doesn't exist yet. + example: '*' + explode: false + in: header + name: If-None-Match + required: false + schema: + pattern: ^\*$ + type: string + style: simple requestBody: content: application/json: @@ -4912,20 +4923,8 @@ paths: schema: type: string style: form - - deprecated: true - description: "Deprecated, this capability will not be supported in future\ - \ releases." - explode: true - in: query - name: storageClass - required: false - schema: - type: string - style: form - - deprecated: true - description: | + - description: | Currently supports only "*" to allow uploading an object only if one doesn't exist yet. - Deprecated, this capability will not be supported in future releases. example: '*' explode: false in: header @@ -4935,6 +4934,16 @@ paths: pattern: ^\*$ type: string style: simple + - deprecated: true + description: "Deprecated, this capability will not be supported in future\ + \ releases." + explode: true + in: query + name: storageClass + required: false + schema: + type: string + style: form - explode: true in: query name: force @@ -6542,6 +6551,18 @@ components: schema: type: string style: form + IfNonMatch: + description: | + Currently supports only "*" to allow uploading an object only if one doesn't exist yet. + example: '*' + explode: false + in: header + name: If-None-Match + required: false + schema: + pattern: ^\*$ + type: string + style: simple responses: NotFoundOrNoACL: content: @@ -8243,7 +8264,6 @@ components: StagingMetadata: description: information about uploaded object example: - if_absent: false size_bytes: 0 user_metadata: key: user_metadata @@ -8274,9 +8294,6 @@ components: force: default: false type: boolean - if_absent: - default: false - type: boolean required: - checksum - size_bytes diff --git a/clients/java/docs/ObjectsApi.md b/clients/java/docs/ObjectsApi.md index 2cbf200dffb..dfb49615d1f 100644 --- a/clients/java/docs/ObjectsApi.md +++ b/clients/java/docs/ObjectsApi.md @@ -843,7 +843,7 @@ public class Example { # **uploadObject** -> ObjectStats uploadObject(repository, branch, path).storageClass(storageClass).ifNoneMatch(ifNoneMatch).force(force).content(content).execute(); +> ObjectStats uploadObject(repository, branch, path).ifNoneMatch(ifNoneMatch).storageClass(storageClass).force(force).content(content).execute(); @@ -893,14 +893,14 @@ public class Example { String repository = "repository_example"; // String | String branch = "branch_example"; // String | String path = "path_example"; // String | relative to the branch + String ifNoneMatch = "*"; // String | Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. String storageClass = "storageClass_example"; // String | Deprecated, this capability will not be supported in future releases. - String ifNoneMatch = "*"; // String | Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. Deprecated, this capability will not be supported in future releases. Boolean force = false; // Boolean | File content = new File("/path/to/file"); // File | Only a single file per upload which must be named \\\"content\\\". try { ObjectStats result = apiInstance.uploadObject(repository, branch, path) - .storageClass(storageClass) .ifNoneMatch(ifNoneMatch) + .storageClass(storageClass) .force(force) .content(content) .execute(); @@ -923,8 +923,8 @@ public class Example { | **repository** | **String**| | | | **branch** | **String**| | | | **path** | **String**| relative to the branch | | +| **ifNoneMatch** | **String**| Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. | [optional] | | **storageClass** | **String**| Deprecated, this capability will not be supported in future releases. | [optional] | -| **ifNoneMatch** | **String**| Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. Deprecated, this capability will not be supported in future releases. | [optional] | | **force** | **Boolean**| | [optional] [default to false] | | **content** | **File**| Only a single file per upload which must be named \\\"content\\\". | [optional] | diff --git a/clients/java/docs/StagingApi.md b/clients/java/docs/StagingApi.md index b97ad2e4486..00fc833c0c8 100644 --- a/clients/java/docs/StagingApi.md +++ b/clients/java/docs/StagingApi.md @@ -110,7 +110,7 @@ public class Example { # **linkPhysicalAddress** -> ObjectStats linkPhysicalAddress(repository, branch, path, stagingMetadata).execute(); +> ObjectStats linkPhysicalAddress(repository, branch, path, stagingMetadata).ifNoneMatch(ifNoneMatch).execute(); associate staging on this physical address with a path @@ -163,8 +163,10 @@ public class Example { String branch = "branch_example"; // String | String path = "path_example"; // String | relative to the branch StagingMetadata stagingMetadata = new StagingMetadata(); // StagingMetadata | + String ifNoneMatch = "*"; // String | Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. try { ObjectStats result = apiInstance.linkPhysicalAddress(repository, branch, path, stagingMetadata) + .ifNoneMatch(ifNoneMatch) .execute(); System.out.println(result); } catch (ApiException e) { @@ -186,6 +188,7 @@ public class Example { | **branch** | **String**| | | | **path** | **String**| relative to the branch | | | **stagingMetadata** | [**StagingMetadata**](StagingMetadata.md)| | | +| **ifNoneMatch** | **String**| Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. | [optional] | ### Return type diff --git a/clients/java/docs/StagingMetadata.md b/clients/java/docs/StagingMetadata.md index 76c5649896a..f80987757bc 100644 --- a/clients/java/docs/StagingMetadata.md +++ b/clients/java/docs/StagingMetadata.md @@ -14,7 +14,6 @@ information about uploaded object |**userMetadata** | **Map<String, String>** | | [optional] | |**contentType** | **String** | Object media type | [optional] | |**force** | **Boolean** | | [optional] | -|**ifAbsent** | **Boolean** | | [optional] | diff --git a/clients/java/src/main/java/io/lakefs/clients/sdk/ObjectsApi.java b/clients/java/src/main/java/io/lakefs/clients/sdk/ObjectsApi.java index 9fce771b183..323e20a7084 100644 --- a/clients/java/src/main/java/io/lakefs/clients/sdk/ObjectsApi.java +++ b/clients/java/src/main/java/io/lakefs/clients/sdk/ObjectsApi.java @@ -1869,7 +1869,7 @@ public okhttp3.Call executeAsync(final ApiCallback _callback) throw public APIstatObjectRequest statObject(String repository, String ref, String path) { return new APIstatObjectRequest(repository, ref, path); } - private okhttp3.Call uploadObjectCall(String repository, String branch, String path, String storageClass, String ifNoneMatch, Boolean force, File content, final ApiCallback _callback) throws ApiException { + private okhttp3.Call uploadObjectCall(String repository, String branch, String path, String ifNoneMatch, String storageClass, Boolean force, File content, final ApiCallback _callback) throws ApiException { String basePath = null; // Operation Servers String[] localBasePaths = new String[] { }; @@ -1938,7 +1938,7 @@ private okhttp3.Call uploadObjectCall(String repository, String branch, String p } @SuppressWarnings("rawtypes") - private okhttp3.Call uploadObjectValidateBeforeCall(String repository, String branch, String path, String storageClass, String ifNoneMatch, Boolean force, File content, final ApiCallback _callback) throws ApiException { + private okhttp3.Call uploadObjectValidateBeforeCall(String repository, String branch, String path, String ifNoneMatch, String storageClass, Boolean force, File content, final ApiCallback _callback) throws ApiException { // verify the required parameter 'repository' is set if (repository == null) { throw new ApiException("Missing the required parameter 'repository' when calling uploadObject(Async)"); @@ -1954,20 +1954,20 @@ private okhttp3.Call uploadObjectValidateBeforeCall(String repository, String br throw new ApiException("Missing the required parameter 'path' when calling uploadObject(Async)"); } - return uploadObjectCall(repository, branch, path, storageClass, ifNoneMatch, force, content, _callback); + return uploadObjectCall(repository, branch, path, ifNoneMatch, storageClass, force, content, _callback); } - private ApiResponse uploadObjectWithHttpInfo(String repository, String branch, String path, String storageClass, String ifNoneMatch, Boolean force, File content) throws ApiException { - okhttp3.Call localVarCall = uploadObjectValidateBeforeCall(repository, branch, path, storageClass, ifNoneMatch, force, content, null); + private ApiResponse uploadObjectWithHttpInfo(String repository, String branch, String path, String ifNoneMatch, String storageClass, Boolean force, File content) throws ApiException { + okhttp3.Call localVarCall = uploadObjectValidateBeforeCall(repository, branch, path, ifNoneMatch, storageClass, force, content, null); Type localVarReturnType = new TypeToken(){}.getType(); return localVarApiClient.execute(localVarCall, localVarReturnType); } - private okhttp3.Call uploadObjectAsync(String repository, String branch, String path, String storageClass, String ifNoneMatch, Boolean force, File content, final ApiCallback _callback) throws ApiException { + private okhttp3.Call uploadObjectAsync(String repository, String branch, String path, String ifNoneMatch, String storageClass, Boolean force, File content, final ApiCallback _callback) throws ApiException { - okhttp3.Call localVarCall = uploadObjectValidateBeforeCall(repository, branch, path, storageClass, ifNoneMatch, force, content, _callback); + okhttp3.Call localVarCall = uploadObjectValidateBeforeCall(repository, branch, path, ifNoneMatch, storageClass, force, content, _callback); Type localVarReturnType = new TypeToken(){}.getType(); localVarApiClient.executeAsync(localVarCall, localVarReturnType, _callback); return localVarCall; @@ -1977,8 +1977,8 @@ public class APIuploadObjectRequest { private final String repository; private final String branch; private final String path; - private String storageClass; private String ifNoneMatch; + private String storageClass; private Boolean force; private File content; @@ -1989,22 +1989,22 @@ private APIuploadObjectRequest(String repository, String branch, String path) { } /** - * Set storageClass - * @param storageClass Deprecated, this capability will not be supported in future releases. (optional) + * Set ifNoneMatch + * @param ifNoneMatch Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. (optional) * @return APIuploadObjectRequest */ - public APIuploadObjectRequest storageClass(String storageClass) { - this.storageClass = storageClass; + public APIuploadObjectRequest ifNoneMatch(String ifNoneMatch) { + this.ifNoneMatch = ifNoneMatch; return this; } /** - * Set ifNoneMatch - * @param ifNoneMatch Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. Deprecated, this capability will not be supported in future releases. (optional) + * Set storageClass + * @param storageClass Deprecated, this capability will not be supported in future releases. (optional) * @return APIuploadObjectRequest */ - public APIuploadObjectRequest ifNoneMatch(String ifNoneMatch) { - this.ifNoneMatch = ifNoneMatch; + public APIuploadObjectRequest storageClass(String storageClass) { + this.storageClass = storageClass; return this; } @@ -2047,7 +2047,7 @@ public APIuploadObjectRequest content(File content) { */ public okhttp3.Call buildCall(final ApiCallback _callback) throws ApiException { - return uploadObjectCall(repository, branch, path, storageClass, ifNoneMatch, force, content, _callback); + return uploadObjectCall(repository, branch, path, ifNoneMatch, storageClass, force, content, _callback); } /** @@ -2068,7 +2068,7 @@ public okhttp3.Call buildCall(final ApiCallback _callback) throws ApiException { */ public ObjectStats execute() throws ApiException { - ApiResponse localVarResp = uploadObjectWithHttpInfo(repository, branch, path, storageClass, ifNoneMatch, force, content); + ApiResponse localVarResp = uploadObjectWithHttpInfo(repository, branch, path, ifNoneMatch, storageClass, force, content); return localVarResp.getData(); } @@ -2090,7 +2090,7 @@ public ObjectStats execute() throws ApiException { */ public ApiResponse executeWithHttpInfo() throws ApiException { - return uploadObjectWithHttpInfo(repository, branch, path, storageClass, ifNoneMatch, force, content); + return uploadObjectWithHttpInfo(repository, branch, path, ifNoneMatch, storageClass, force, content); } /** @@ -2112,7 +2112,7 @@ public ApiResponse executeWithHttpInfo() throws ApiException { */ public okhttp3.Call executeAsync(final ApiCallback _callback) throws ApiException { - return uploadObjectAsync(repository, branch, path, storageClass, ifNoneMatch, force, content, _callback); + return uploadObjectAsync(repository, branch, path, ifNoneMatch, storageClass, force, content, _callback); } } diff --git a/clients/java/src/main/java/io/lakefs/clients/sdk/StagingApi.java b/clients/java/src/main/java/io/lakefs/clients/sdk/StagingApi.java index 2a8e4ab294d..1bc27bb8955 100644 --- a/clients/java/src/main/java/io/lakefs/clients/sdk/StagingApi.java +++ b/clients/java/src/main/java/io/lakefs/clients/sdk/StagingApi.java @@ -283,7 +283,7 @@ public okhttp3.Call executeAsync(final ApiCallback _callback) t public APIgetPhysicalAddressRequest getPhysicalAddress(String repository, String branch, String path) { return new APIgetPhysicalAddressRequest(repository, branch, path); } - private okhttp3.Call linkPhysicalAddressCall(String repository, String branch, String path, StagingMetadata stagingMetadata, final ApiCallback _callback) throws ApiException { + private okhttp3.Call linkPhysicalAddressCall(String repository, String branch, String path, StagingMetadata stagingMetadata, String ifNoneMatch, final ApiCallback _callback) throws ApiException { String basePath = null; // Operation Servers String[] localBasePaths = new String[] { }; @@ -314,6 +314,10 @@ private okhttp3.Call linkPhysicalAddressCall(String repository, String branch, S localVarQueryParams.addAll(localVarApiClient.parameterToPair("path", path)); } + if (ifNoneMatch != null) { + localVarHeaderParams.put("If-None-Match", localVarApiClient.parameterToString(ifNoneMatch)); + } + final String[] localVarAccepts = { "application/json" }; @@ -335,7 +339,7 @@ private okhttp3.Call linkPhysicalAddressCall(String repository, String branch, S } @SuppressWarnings("rawtypes") - private okhttp3.Call linkPhysicalAddressValidateBeforeCall(String repository, String branch, String path, StagingMetadata stagingMetadata, final ApiCallback _callback) throws ApiException { + private okhttp3.Call linkPhysicalAddressValidateBeforeCall(String repository, String branch, String path, StagingMetadata stagingMetadata, String ifNoneMatch, final ApiCallback _callback) throws ApiException { // verify the required parameter 'repository' is set if (repository == null) { throw new ApiException("Missing the required parameter 'repository' when calling linkPhysicalAddress(Async)"); @@ -356,20 +360,20 @@ private okhttp3.Call linkPhysicalAddressValidateBeforeCall(String repository, St throw new ApiException("Missing the required parameter 'stagingMetadata' when calling linkPhysicalAddress(Async)"); } - return linkPhysicalAddressCall(repository, branch, path, stagingMetadata, _callback); + return linkPhysicalAddressCall(repository, branch, path, stagingMetadata, ifNoneMatch, _callback); } - private ApiResponse linkPhysicalAddressWithHttpInfo(String repository, String branch, String path, StagingMetadata stagingMetadata) throws ApiException { - okhttp3.Call localVarCall = linkPhysicalAddressValidateBeforeCall(repository, branch, path, stagingMetadata, null); + private ApiResponse linkPhysicalAddressWithHttpInfo(String repository, String branch, String path, StagingMetadata stagingMetadata, String ifNoneMatch) throws ApiException { + okhttp3.Call localVarCall = linkPhysicalAddressValidateBeforeCall(repository, branch, path, stagingMetadata, ifNoneMatch, null); Type localVarReturnType = new TypeToken(){}.getType(); return localVarApiClient.execute(localVarCall, localVarReturnType); } - private okhttp3.Call linkPhysicalAddressAsync(String repository, String branch, String path, StagingMetadata stagingMetadata, final ApiCallback _callback) throws ApiException { + private okhttp3.Call linkPhysicalAddressAsync(String repository, String branch, String path, StagingMetadata stagingMetadata, String ifNoneMatch, final ApiCallback _callback) throws ApiException { - okhttp3.Call localVarCall = linkPhysicalAddressValidateBeforeCall(repository, branch, path, stagingMetadata, _callback); + okhttp3.Call localVarCall = linkPhysicalAddressValidateBeforeCall(repository, branch, path, stagingMetadata, ifNoneMatch, _callback); Type localVarReturnType = new TypeToken(){}.getType(); localVarApiClient.executeAsync(localVarCall, localVarReturnType, _callback); return localVarCall; @@ -380,6 +384,7 @@ public class APIlinkPhysicalAddressRequest { private final String branch; private final String path; private final StagingMetadata stagingMetadata; + private String ifNoneMatch; private APIlinkPhysicalAddressRequest(String repository, String branch, String path, StagingMetadata stagingMetadata) { this.repository = repository; @@ -388,6 +393,16 @@ private APIlinkPhysicalAddressRequest(String repository, String branch, String p this.stagingMetadata = stagingMetadata; } + /** + * Set ifNoneMatch + * @param ifNoneMatch Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. (optional) + * @return APIlinkPhysicalAddressRequest + */ + public APIlinkPhysicalAddressRequest ifNoneMatch(String ifNoneMatch) { + this.ifNoneMatch = ifNoneMatch; + return this; + } + /** * Build call for linkPhysicalAddress * @param _callback ApiCallback API callback @@ -407,7 +422,7 @@ private APIlinkPhysicalAddressRequest(String repository, String branch, String p */ public okhttp3.Call buildCall(final ApiCallback _callback) throws ApiException { - return linkPhysicalAddressCall(repository, branch, path, stagingMetadata, _callback); + return linkPhysicalAddressCall(repository, branch, path, stagingMetadata, ifNoneMatch, _callback); } /** @@ -428,7 +443,7 @@ public okhttp3.Call buildCall(final ApiCallback _callback) throws ApiException { */ public ObjectStats execute() throws ApiException { - ApiResponse localVarResp = linkPhysicalAddressWithHttpInfo(repository, branch, path, stagingMetadata); + ApiResponse localVarResp = linkPhysicalAddressWithHttpInfo(repository, branch, path, stagingMetadata, ifNoneMatch); return localVarResp.getData(); } @@ -450,7 +465,7 @@ public ObjectStats execute() throws ApiException { */ public ApiResponse executeWithHttpInfo() throws ApiException { - return linkPhysicalAddressWithHttpInfo(repository, branch, path, stagingMetadata); + return linkPhysicalAddressWithHttpInfo(repository, branch, path, stagingMetadata, ifNoneMatch); } /** @@ -472,7 +487,7 @@ public ApiResponse executeWithHttpInfo() throws ApiException { */ public okhttp3.Call executeAsync(final ApiCallback _callback) throws ApiException { - return linkPhysicalAddressAsync(repository, branch, path, stagingMetadata, _callback); + return linkPhysicalAddressAsync(repository, branch, path, stagingMetadata, ifNoneMatch, _callback); } } diff --git a/clients/java/src/main/java/io/lakefs/clients/sdk/model/StagingMetadata.java b/clients/java/src/main/java/io/lakefs/clients/sdk/model/StagingMetadata.java index 10a93fd3364..0e6ad6001c4 100644 --- a/clients/java/src/main/java/io/lakefs/clients/sdk/model/StagingMetadata.java +++ b/clients/java/src/main/java/io/lakefs/clients/sdk/model/StagingMetadata.java @@ -79,10 +79,6 @@ public class StagingMetadata { @SerializedName(SERIALIZED_NAME_FORCE) private Boolean force = false; - public static final String SERIALIZED_NAME_IF_ABSENT = "if_absent"; - @SerializedName(SERIALIZED_NAME_IF_ABSENT) - private Boolean ifAbsent = false; - public StagingMetadata() { } @@ -219,27 +215,6 @@ public void setForce(Boolean force) { this.force = force; } - - public StagingMetadata ifAbsent(Boolean ifAbsent) { - - this.ifAbsent = ifAbsent; - return this; - } - - /** - * Get ifAbsent - * @return ifAbsent - **/ - @javax.annotation.Nullable - public Boolean getIfAbsent() { - return ifAbsent; - } - - - public void setIfAbsent(Boolean ifAbsent) { - this.ifAbsent = ifAbsent; - } - /** * A container for additional, undeclared properties. * This is a holder for any undeclared properties as specified with @@ -300,14 +275,13 @@ public boolean equals(Object o) { Objects.equals(this.sizeBytes, stagingMetadata.sizeBytes) && Objects.equals(this.userMetadata, stagingMetadata.userMetadata) && Objects.equals(this.contentType, stagingMetadata.contentType) && - Objects.equals(this.force, stagingMetadata.force) && - Objects.equals(this.ifAbsent, stagingMetadata.ifAbsent)&& + Objects.equals(this.force, stagingMetadata.force)&& Objects.equals(this.additionalProperties, stagingMetadata.additionalProperties); } @Override public int hashCode() { - return Objects.hash(staging, checksum, sizeBytes, userMetadata, contentType, force, ifAbsent, additionalProperties); + return Objects.hash(staging, checksum, sizeBytes, userMetadata, contentType, force, additionalProperties); } @Override @@ -320,7 +294,6 @@ public String toString() { sb.append(" userMetadata: ").append(toIndentedString(userMetadata)).append("\n"); sb.append(" contentType: ").append(toIndentedString(contentType)).append("\n"); sb.append(" force: ").append(toIndentedString(force)).append("\n"); - sb.append(" ifAbsent: ").append(toIndentedString(ifAbsent)).append("\n"); sb.append(" additionalProperties: ").append(toIndentedString(additionalProperties)).append("\n"); sb.append("}"); return sb.toString(); @@ -350,7 +323,6 @@ private String toIndentedString(Object o) { openapiFields.add("user_metadata"); openapiFields.add("content_type"); openapiFields.add("force"); - openapiFields.add("if_absent"); // a set of required properties/fields (JSON key names) openapiRequiredFields = new HashSet(); diff --git a/clients/java/src/test/java/io/lakefs/clients/sdk/ObjectsApiTest.java b/clients/java/src/test/java/io/lakefs/clients/sdk/ObjectsApiTest.java index da320cdd7d4..54c9e54f93f 100644 --- a/clients/java/src/test/java/io/lakefs/clients/sdk/ObjectsApiTest.java +++ b/clients/java/src/test/java/io/lakefs/clients/sdk/ObjectsApiTest.java @@ -192,13 +192,13 @@ public void uploadObjectTest() throws ApiException { String repository = null; String branch = null; String path = null; - String storageClass = null; String ifNoneMatch = null; + String storageClass = null; Boolean force = null; File content = null; ObjectStats response = api.uploadObject(repository, branch, path) - .storageClass(storageClass) .ifNoneMatch(ifNoneMatch) + .storageClass(storageClass) .force(force) .content(content) .execute(); diff --git a/clients/java/src/test/java/io/lakefs/clients/sdk/StagingApiTest.java b/clients/java/src/test/java/io/lakefs/clients/sdk/StagingApiTest.java index 160ef02b875..073a9336b88 100644 --- a/clients/java/src/test/java/io/lakefs/clients/sdk/StagingApiTest.java +++ b/clients/java/src/test/java/io/lakefs/clients/sdk/StagingApiTest.java @@ -64,7 +64,9 @@ public void linkPhysicalAddressTest() throws ApiException { String branch = null; String path = null; StagingMetadata stagingMetadata = null; + String ifNoneMatch = null; ObjectStats response = api.linkPhysicalAddress(repository, branch, path, stagingMetadata) + .ifNoneMatch(ifNoneMatch) .execute(); // TODO: test validations } diff --git a/clients/java/src/test/java/io/lakefs/clients/sdk/model/StagingMetadataTest.java b/clients/java/src/test/java/io/lakefs/clients/sdk/model/StagingMetadataTest.java index acf01e2e396..d11a7d6b96e 100644 --- a/clients/java/src/test/java/io/lakefs/clients/sdk/model/StagingMetadataTest.java +++ b/clients/java/src/test/java/io/lakefs/clients/sdk/model/StagingMetadataTest.java @@ -88,12 +88,4 @@ public void forceTest() { // TODO: test force } - /** - * Test the property 'ifAbsent' - */ - @Test - public void ifAbsentTest() { - // TODO: test ifAbsent - } - } diff --git a/clients/python-legacy/docs/ObjectsApi.md b/clients/python-legacy/docs/ObjectsApi.md index 8475c8503da..22060c9759c 100644 --- a/clients/python-legacy/docs/ObjectsApi.md +++ b/clients/python-legacy/docs/ObjectsApi.md @@ -1073,8 +1073,8 @@ with lakefs_client.ApiClient(configuration) as api_client: repository = "repository_example" # str | branch = "branch_example" # str | path = "path_example" # str | relative to the branch + if_none_match = "*" # str | Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. (optional) storage_class = "storageClass_example" # str | Deprecated, this capability will not be supported in future releases. (optional) - if_none_match = "*" # str | Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. Deprecated, this capability will not be supported in future releases. (optional) force = False # bool | (optional) if omitted the server will use the default value of False content = open('/path/to/file', 'rb') # file_type | Only a single file per upload which must be named \\\"content\\\". (optional) @@ -1088,7 +1088,7 @@ with lakefs_client.ApiClient(configuration) as api_client: # example passing only required values which don't have defaults set # and optional values try: - api_response = api_instance.upload_object(repository, branch, path, storage_class=storage_class, if_none_match=if_none_match, force=force, content=content) + api_response = api_instance.upload_object(repository, branch, path, if_none_match=if_none_match, storage_class=storage_class, force=force, content=content) pprint(api_response) except lakefs_client.ApiException as e: print("Exception when calling ObjectsApi->upload_object: %s\n" % e) @@ -1102,8 +1102,8 @@ Name | Type | Description | Notes **repository** | **str**| | **branch** | **str**| | **path** | **str**| relative to the branch | + **if_none_match** | **str**| Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. | [optional] **storage_class** | **str**| Deprecated, this capability will not be supported in future releases. | [optional] - **if_none_match** | **str**| Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. Deprecated, this capability will not be supported in future releases. | [optional] **force** | **bool**| | [optional] if omitted the server will use the default value of False **content** | **file_type**| Only a single file per upload which must be named \\\"content\\\". | [optional] diff --git a/clients/python-legacy/docs/StagingApi.md b/clients/python-legacy/docs/StagingApi.md index 3d7b973ee95..8a209aaf6dd 100644 --- a/clients/python-legacy/docs/StagingApi.md +++ b/clients/python-legacy/docs/StagingApi.md @@ -215,8 +215,8 @@ with lakefs_client.ApiClient(configuration) as api_client: }, content_type="content_type_example", force=False, - if_absent=False, ) # StagingMetadata | + if_none_match = "*" # str | Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. (optional) # example passing only required values which don't have defaults set try: @@ -225,6 +225,15 @@ with lakefs_client.ApiClient(configuration) as api_client: pprint(api_response) except lakefs_client.ApiException as e: print("Exception when calling StagingApi->link_physical_address: %s\n" % e) + + # example passing only required values which don't have defaults set + # and optional values + try: + # associate staging on this physical address with a path + api_response = api_instance.link_physical_address(repository, branch, path, staging_metadata, if_none_match=if_none_match) + pprint(api_response) + except lakefs_client.ApiException as e: + print("Exception when calling StagingApi->link_physical_address: %s\n" % e) ``` @@ -236,6 +245,7 @@ Name | Type | Description | Notes **branch** | **str**| | **path** | **str**| relative to the branch | **staging_metadata** | [**StagingMetadata**](StagingMetadata.md)| | + **if_none_match** | **str**| Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. | [optional] ### Return type diff --git a/clients/python-legacy/docs/StagingMetadata.md b/clients/python-legacy/docs/StagingMetadata.md index f8e4f82bdf1..21cca48909a 100644 --- a/clients/python-legacy/docs/StagingMetadata.md +++ b/clients/python-legacy/docs/StagingMetadata.md @@ -11,7 +11,6 @@ Name | Type | Description | Notes **user_metadata** | **{str: (str,)}** | | [optional] **content_type** | **str** | Object media type | [optional] **force** | **bool** | | [optional] if omitted the server will use the default value of False -**if_absent** | **bool** | | [optional] if omitted the server will use the default value of False **any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/clients/python-legacy/lakefs_client/api/objects_api.py b/clients/python-legacy/lakefs_client/api/objects_api.py index f9b965bbdeb..de70e8eb0f8 100644 --- a/clients/python-legacy/lakefs_client/api/objects_api.py +++ b/clients/python-legacy/lakefs_client/api/objects_api.py @@ -684,8 +684,8 @@ def __init__(self, api_client=None): 'repository', 'branch', 'path', - 'storage_class', 'if_none_match', + 'storage_class', 'force', 'content', ], @@ -720,10 +720,10 @@ def __init__(self, api_client=None): (str,), 'path': (str,), - 'storage_class': - (str,), 'if_none_match': (str,), + 'storage_class': + (str,), 'force': (bool,), 'content': @@ -733,8 +733,8 @@ def __init__(self, api_client=None): 'repository': 'repository', 'branch': 'branch', 'path': 'path', - 'storage_class': 'storageClass', 'if_none_match': 'If-None-Match', + 'storage_class': 'storageClass', 'force': 'force', 'content': 'content', }, @@ -742,8 +742,8 @@ def __init__(self, api_client=None): 'repository': 'path', 'branch': 'path', 'path': 'query', - 'storage_class': 'query', 'if_none_match': 'header', + 'storage_class': 'query', 'force': 'query', 'content': 'form', }, @@ -1380,8 +1380,8 @@ def upload_object( path (str): relative to the branch Keyword Args: + if_none_match (str): Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. . [optional] storage_class (str): Deprecated, this capability will not be supported in future releases.. [optional] - if_none_match (str): Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. Deprecated, this capability will not be supported in future releases. . [optional] force (bool): [optional] if omitted the server will use the default value of False content (file_type): Only a single file per upload which must be named \\\"content\\\".. [optional] _return_http_data_only (bool): response data without head status diff --git a/clients/python-legacy/lakefs_client/api/staging_api.py b/clients/python-legacy/lakefs_client/api/staging_api.py index 73d9fd13dfe..348c9fa2166 100644 --- a/clients/python-legacy/lakefs_client/api/staging_api.py +++ b/clients/python-legacy/lakefs_client/api/staging_api.py @@ -132,6 +132,7 @@ def __init__(self, api_client=None): 'branch', 'path', 'staging_metadata', + 'if_none_match', ], 'required': [ 'repository', @@ -144,10 +145,17 @@ def __init__(self, api_client=None): 'enum': [ ], 'validation': [ + 'if_none_match', ] }, root_map={ 'validations': { + ('if_none_match',): { + + 'regex': { + 'pattern': r'^\*$', # noqa: E501 + }, + }, }, 'allowed_values': { }, @@ -160,17 +168,21 @@ def __init__(self, api_client=None): (str,), 'staging_metadata': (StagingMetadata,), + 'if_none_match': + (str,), }, 'attribute_map': { 'repository': 'repository', 'branch': 'branch', 'path': 'path', + 'if_none_match': 'If-None-Match', }, 'location_map': { 'repository': 'path', 'branch': 'path', 'path': 'query', 'staging_metadata': 'body', + 'if_none_match': 'header', }, 'collection_format_map': { } @@ -284,6 +296,7 @@ def link_physical_address( staging_metadata (StagingMetadata): Keyword Args: + if_none_match (str): Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. . [optional] _return_http_data_only (bool): response data without head status code and headers. Default is True. _preload_content (bool): if False, the urllib3.HTTPResponse object diff --git a/clients/python-legacy/lakefs_client/model/staging_metadata.py b/clients/python-legacy/lakefs_client/model/staging_metadata.py index 94e6eb60e00..4e6414fc15c 100644 --- a/clients/python-legacy/lakefs_client/model/staging_metadata.py +++ b/clients/python-legacy/lakefs_client/model/staging_metadata.py @@ -94,7 +94,6 @@ def openapi_types(): 'user_metadata': ({str: (str,)},), # noqa: E501 'content_type': (str,), # noqa: E501 'force': (bool,), # noqa: E501 - 'if_absent': (bool,), # noqa: E501 } @cached_property @@ -109,7 +108,6 @@ def discriminator(): 'user_metadata': 'user_metadata', # noqa: E501 'content_type': 'content_type', # noqa: E501 'force': 'force', # noqa: E501 - 'if_absent': 'if_absent', # noqa: E501 } read_only_vars = { @@ -161,7 +159,6 @@ def _from_openapi_data(cls, staging, checksum, size_bytes, *args, **kwargs): # user_metadata ({str: (str,)}): [optional] # noqa: E501 content_type (str): Object media type. [optional] # noqa: E501 force (bool): [optional] if omitted the server will use the default value of False # noqa: E501 - if_absent (bool): [optional] if omitted the server will use the default value of False # noqa: E501 """ _check_type = kwargs.pop('_check_type', True) @@ -254,7 +251,6 @@ def __init__(self, staging, checksum, size_bytes, *args, **kwargs): # noqa: E50 user_metadata ({str: (str,)}): [optional] # noqa: E501 content_type (str): Object media type. [optional] # noqa: E501 force (bool): [optional] if omitted the server will use the default value of False # noqa: E501 - if_absent (bool): [optional] if omitted the server will use the default value of False # noqa: E501 """ _check_type = kwargs.pop('_check_type', True) diff --git a/clients/python/docs/ObjectsApi.md b/clients/python/docs/ObjectsApi.md index 86154b8635c..25cfb0e4427 100644 --- a/clients/python/docs/ObjectsApi.md +++ b/clients/python/docs/ObjectsApi.md @@ -962,7 +962,7 @@ Name | Type | Description | Notes [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) # **upload_object** -> ObjectStats upload_object(repository, branch, path, storage_class=storage_class, if_none_match=if_none_match, force=force, content=content) +> ObjectStats upload_object(repository, branch, path, if_none_match=if_none_match, storage_class=storage_class, force=force, content=content) @@ -1029,13 +1029,13 @@ with lakefs_sdk.ApiClient(configuration) as api_client: repository = 'repository_example' # str | branch = 'branch_example' # str | path = 'path_example' # str | relative to the branch + if_none_match = '*' # str | Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. (optional) storage_class = 'storage_class_example' # str | Deprecated, this capability will not be supported in future releases. (optional) - if_none_match = '*' # str | Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. Deprecated, this capability will not be supported in future releases. (optional) force = False # bool | (optional) (default to False) content = None # bytearray | Only a single file per upload which must be named \\\"content\\\". (optional) try: - api_response = api_instance.upload_object(repository, branch, path, storage_class=storage_class, if_none_match=if_none_match, force=force, content=content) + api_response = api_instance.upload_object(repository, branch, path, if_none_match=if_none_match, storage_class=storage_class, force=force, content=content) print("The response of ObjectsApi->upload_object:\n") pprint(api_response) except Exception as e: @@ -1052,8 +1052,8 @@ Name | Type | Description | Notes **repository** | **str**| | **branch** | **str**| | **path** | **str**| relative to the branch | + **if_none_match** | **str**| Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. | [optional] **storage_class** | **str**| Deprecated, this capability will not be supported in future releases. | [optional] - **if_none_match** | **str**| Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. Deprecated, this capability will not be supported in future releases. | [optional] **force** | **bool**| | [optional] [default to False] **content** | **bytearray**| Only a single file per upload which must be named \\\"content\\\". | [optional] diff --git a/clients/python/docs/StagingApi.md b/clients/python/docs/StagingApi.md index d2c5497eb6f..264a6021d5e 100644 --- a/clients/python/docs/StagingApi.md +++ b/clients/python/docs/StagingApi.md @@ -125,7 +125,7 @@ Name | Type | Description | Notes [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) # **link_physical_address** -> ObjectStats link_physical_address(repository, branch, path, staging_metadata) +> ObjectStats link_physical_address(repository, branch, path, staging_metadata, if_none_match=if_none_match) associate staging on this physical address with a path @@ -196,10 +196,11 @@ with lakefs_sdk.ApiClient(configuration) as api_client: branch = 'branch_example' # str | path = 'path_example' # str | relative to the branch staging_metadata = lakefs_sdk.StagingMetadata() # StagingMetadata | + if_none_match = '*' # str | Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. (optional) try: # associate staging on this physical address with a path - api_response = api_instance.link_physical_address(repository, branch, path, staging_metadata) + api_response = api_instance.link_physical_address(repository, branch, path, staging_metadata, if_none_match=if_none_match) print("The response of StagingApi->link_physical_address:\n") pprint(api_response) except Exception as e: @@ -217,6 +218,7 @@ Name | Type | Description | Notes **branch** | **str**| | **path** | **str**| relative to the branch | **staging_metadata** | [**StagingMetadata**](StagingMetadata.md)| | + **if_none_match** | **str**| Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. | [optional] ### Return type diff --git a/clients/python/docs/StagingMetadata.md b/clients/python/docs/StagingMetadata.md index ef52a21c1c8..7e52333ff9e 100644 --- a/clients/python/docs/StagingMetadata.md +++ b/clients/python/docs/StagingMetadata.md @@ -12,7 +12,6 @@ Name | Type | Description | Notes **user_metadata** | **Dict[str, str]** | | [optional] **content_type** | **str** | Object media type | [optional] **force** | **bool** | | [optional] [default to False] -**if_absent** | **bool** | | [optional] [default to False] ## Example diff --git a/clients/python/lakefs_sdk/api/objects_api.py b/clients/python/lakefs_sdk/api/objects_api.py index 2630e94c3cf..5cd99f2f047 100644 --- a/clients/python/lakefs_sdk/api/objects_api.py +++ b/clients/python/lakefs_sdk/api/objects_api.py @@ -1413,13 +1413,13 @@ def stat_object_with_http_info(self, repository : StrictStr, ref : Annotated[Str _request_auth=_params.get('_request_auth')) @validate_arguments - def upload_object(self, repository : StrictStr, branch : StrictStr, path : Annotated[StrictStr, Field(..., description="relative to the branch")], storage_class : Annotated[Optional[StrictStr], Field(description="Deprecated, this capability will not be supported in future releases.")] = None, if_none_match : Annotated[Optional[constr(strict=True)], Field(description="Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. Deprecated, this capability will not be supported in future releases. ")] = None, force : Optional[StrictBool] = None, content : Annotated[Optional[Union[StrictBytes, StrictStr]], Field(description="Only a single file per upload which must be named \\\"content\\\".")] = None, **kwargs) -> ObjectStats: # noqa: E501 + def upload_object(self, repository : StrictStr, branch : StrictStr, path : Annotated[StrictStr, Field(..., description="relative to the branch")], if_none_match : Annotated[Optional[constr(strict=True)], Field(description="Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. ")] = None, storage_class : Annotated[Optional[StrictStr], Field(description="Deprecated, this capability will not be supported in future releases.")] = None, force : Optional[StrictBool] = None, content : Annotated[Optional[Union[StrictBytes, StrictStr]], Field(description="Only a single file per upload which must be named \\\"content\\\".")] = None, **kwargs) -> ObjectStats: # noqa: E501 """upload_object # noqa: E501 This method makes a synchronous HTTP request by default. To make an asynchronous HTTP request, please pass async_req=True - >>> thread = api.upload_object(repository, branch, path, storage_class, if_none_match, force, content, async_req=True) + >>> thread = api.upload_object(repository, branch, path, if_none_match, storage_class, force, content, async_req=True) >>> result = thread.get() :param repository: (required) @@ -1428,10 +1428,10 @@ def upload_object(self, repository : StrictStr, branch : StrictStr, path : Annot :type branch: str :param path: relative to the branch (required) :type path: str + :param if_none_match: Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. + :type if_none_match: str :param storage_class: Deprecated, this capability will not be supported in future releases. :type storage_class: str - :param if_none_match: Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. Deprecated, this capability will not be supported in future releases. - :type if_none_match: str :param force: :type force: bool :param content: Only a single file per upload which must be named \\\"content\\\". @@ -1450,16 +1450,16 @@ def upload_object(self, repository : StrictStr, branch : StrictStr, path : Annot kwargs['_return_http_data_only'] = True if '_preload_content' in kwargs: raise ValueError("Error! Please call the upload_object_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data") - return self.upload_object_with_http_info(repository, branch, path, storage_class, if_none_match, force, content, **kwargs) # noqa: E501 + return self.upload_object_with_http_info(repository, branch, path, if_none_match, storage_class, force, content, **kwargs) # noqa: E501 @validate_arguments - def upload_object_with_http_info(self, repository : StrictStr, branch : StrictStr, path : Annotated[StrictStr, Field(..., description="relative to the branch")], storage_class : Annotated[Optional[StrictStr], Field(description="Deprecated, this capability will not be supported in future releases.")] = None, if_none_match : Annotated[Optional[constr(strict=True)], Field(description="Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. Deprecated, this capability will not be supported in future releases. ")] = None, force : Optional[StrictBool] = None, content : Annotated[Optional[Union[StrictBytes, StrictStr]], Field(description="Only a single file per upload which must be named \\\"content\\\".")] = None, **kwargs) -> ApiResponse: # noqa: E501 + def upload_object_with_http_info(self, repository : StrictStr, branch : StrictStr, path : Annotated[StrictStr, Field(..., description="relative to the branch")], if_none_match : Annotated[Optional[constr(strict=True)], Field(description="Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. ")] = None, storage_class : Annotated[Optional[StrictStr], Field(description="Deprecated, this capability will not be supported in future releases.")] = None, force : Optional[StrictBool] = None, content : Annotated[Optional[Union[StrictBytes, StrictStr]], Field(description="Only a single file per upload which must be named \\\"content\\\".")] = None, **kwargs) -> ApiResponse: # noqa: E501 """upload_object # noqa: E501 This method makes a synchronous HTTP request by default. To make an asynchronous HTTP request, please pass async_req=True - >>> thread = api.upload_object_with_http_info(repository, branch, path, storage_class, if_none_match, force, content, async_req=True) + >>> thread = api.upload_object_with_http_info(repository, branch, path, if_none_match, storage_class, force, content, async_req=True) >>> result = thread.get() :param repository: (required) @@ -1468,10 +1468,10 @@ def upload_object_with_http_info(self, repository : StrictStr, branch : StrictSt :type branch: str :param path: relative to the branch (required) :type path: str + :param if_none_match: Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. + :type if_none_match: str :param storage_class: Deprecated, this capability will not be supported in future releases. :type storage_class: str - :param if_none_match: Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. Deprecated, this capability will not be supported in future releases. - :type if_none_match: str :param force: :type force: bool :param content: Only a single file per upload which must be named \\\"content\\\". @@ -1507,8 +1507,8 @@ def upload_object_with_http_info(self, repository : StrictStr, branch : StrictSt 'repository', 'branch', 'path', - 'storage_class', 'if_none_match', + 'storage_class', 'force', 'content' ] diff --git a/clients/python/lakefs_sdk/api/staging_api.py b/clients/python/lakefs_sdk/api/staging_api.py index 7b97bff065b..f3cbaf7587a 100644 --- a/clients/python/lakefs_sdk/api/staging_api.py +++ b/clients/python/lakefs_sdk/api/staging_api.py @@ -20,7 +20,7 @@ from pydantic import validate_arguments, ValidationError from typing_extensions import Annotated -from pydantic import Field, StrictBool, StrictStr +from pydantic import Field, StrictBool, StrictStr, constr, validator from typing import Optional @@ -213,14 +213,14 @@ def get_physical_address_with_http_info(self, repository : StrictStr, branch : S _request_auth=_params.get('_request_auth')) @validate_arguments - def link_physical_address(self, repository : StrictStr, branch : StrictStr, path : Annotated[StrictStr, Field(..., description="relative to the branch")], staging_metadata : StagingMetadata, **kwargs) -> ObjectStats: # noqa: E501 + def link_physical_address(self, repository : StrictStr, branch : StrictStr, path : Annotated[StrictStr, Field(..., description="relative to the branch")], staging_metadata : StagingMetadata, if_none_match : Annotated[Optional[constr(strict=True)], Field(description="Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. ")] = None, **kwargs) -> ObjectStats: # noqa: E501 """associate staging on this physical address with a path # noqa: E501 Link the physical address with the path in lakeFS, creating an uncommitted change. The given address can be one generated by getPhysicalAddress, or an address outside the repository's storage namespace. # noqa: E501 This method makes a synchronous HTTP request by default. To make an asynchronous HTTP request, please pass async_req=True - >>> thread = api.link_physical_address(repository, branch, path, staging_metadata, async_req=True) + >>> thread = api.link_physical_address(repository, branch, path, staging_metadata, if_none_match, async_req=True) >>> result = thread.get() :param repository: (required) @@ -231,6 +231,8 @@ def link_physical_address(self, repository : StrictStr, branch : StrictStr, path :type path: str :param staging_metadata: (required) :type staging_metadata: StagingMetadata + :param if_none_match: Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. + :type if_none_match: str :param async_req: Whether to execute the request asynchronously. :type async_req: bool, optional :param _request_timeout: timeout setting for this request. If one @@ -245,17 +247,17 @@ def link_physical_address(self, repository : StrictStr, branch : StrictStr, path kwargs['_return_http_data_only'] = True if '_preload_content' in kwargs: raise ValueError("Error! Please call the link_physical_address_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data") - return self.link_physical_address_with_http_info(repository, branch, path, staging_metadata, **kwargs) # noqa: E501 + return self.link_physical_address_with_http_info(repository, branch, path, staging_metadata, if_none_match, **kwargs) # noqa: E501 @validate_arguments - def link_physical_address_with_http_info(self, repository : StrictStr, branch : StrictStr, path : Annotated[StrictStr, Field(..., description="relative to the branch")], staging_metadata : StagingMetadata, **kwargs) -> ApiResponse: # noqa: E501 + def link_physical_address_with_http_info(self, repository : StrictStr, branch : StrictStr, path : Annotated[StrictStr, Field(..., description="relative to the branch")], staging_metadata : StagingMetadata, if_none_match : Annotated[Optional[constr(strict=True)], Field(description="Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. ")] = None, **kwargs) -> ApiResponse: # noqa: E501 """associate staging on this physical address with a path # noqa: E501 Link the physical address with the path in lakeFS, creating an uncommitted change. The given address can be one generated by getPhysicalAddress, or an address outside the repository's storage namespace. # noqa: E501 This method makes a synchronous HTTP request by default. To make an asynchronous HTTP request, please pass async_req=True - >>> thread = api.link_physical_address_with_http_info(repository, branch, path, staging_metadata, async_req=True) + >>> thread = api.link_physical_address_with_http_info(repository, branch, path, staging_metadata, if_none_match, async_req=True) >>> result = thread.get() :param repository: (required) @@ -266,6 +268,8 @@ def link_physical_address_with_http_info(self, repository : StrictStr, branch : :type path: str :param staging_metadata: (required) :type staging_metadata: StagingMetadata + :param if_none_match: Currently supports only \"*\" to allow uploading an object only if one doesn't exist yet. + :type if_none_match: str :param async_req: Whether to execute the request asynchronously. :type async_req: bool, optional :param _preload_content: if False, the ApiResponse.data will @@ -297,7 +301,8 @@ def link_physical_address_with_http_info(self, repository : StrictStr, branch : 'repository', 'branch', 'path', - 'staging_metadata' + 'staging_metadata', + 'if_none_match' ] _all_params.extend( [ @@ -339,6 +344,9 @@ def link_physical_address_with_http_info(self, repository : StrictStr, branch : # process the header parameters _header_params = dict(_params.get('_headers', {})) + if _params['if_none_match']: + _header_params['If-None-Match'] = _params['if_none_match'] + # process the form parameters _form_params = [] _files = {} diff --git a/clients/python/lakefs_sdk/models/staging_metadata.py b/clients/python/lakefs_sdk/models/staging_metadata.py index 38647b3a9d0..6ae206d9d14 100644 --- a/clients/python/lakefs_sdk/models/staging_metadata.py +++ b/clients/python/lakefs_sdk/models/staging_metadata.py @@ -33,8 +33,7 @@ class StagingMetadata(BaseModel): user_metadata: Optional[Dict[str, StrictStr]] = None content_type: Optional[StrictStr] = Field(None, description="Object media type") force: Optional[StrictBool] = False - if_absent: Optional[StrictBool] = False - __properties = ["staging", "checksum", "size_bytes", "user_metadata", "content_type", "force", "if_absent"] + __properties = ["staging", "checksum", "size_bytes", "user_metadata", "content_type", "force"] class Config: """Pydantic configuration""" @@ -80,8 +79,7 @@ def from_dict(cls, obj: dict) -> StagingMetadata: "size_bytes": obj.get("size_bytes"), "user_metadata": obj.get("user_metadata"), "content_type": obj.get("content_type"), - "force": obj.get("force") if obj.get("force") is not None else False, - "if_absent": obj.get("if_absent") if obj.get("if_absent") is not None else False + "force": obj.get("force") if obj.get("force") is not None else False }) return _obj diff --git a/clients/python/test/test_staging_metadata.py b/clients/python/test/test_staging_metadata.py index 40624e79aa7..3623b7c8884 100644 --- a/clients/python/test/test_staging_metadata.py +++ b/clients/python/test/test_staging_metadata.py @@ -49,8 +49,7 @@ def make_instance(self, include_optional): 'key' : '' }, content_type = '', - force = True, - if_absent = True + force = True ) else : return StagingMetadata( diff --git a/docs/assets/js/swagger.yml b/docs/assets/js/swagger.yml index 6c17051cff6..5e7ac0330e8 100644 --- a/docs/assets/js/swagger.yml +++ b/docs/assets/js/swagger.yml @@ -69,6 +69,17 @@ components: description: delimiter used to group common prefixes by schema: type: string + + IfNonMatch: + in: header + name: If-None-Match + description: | + Currently supports only "*" to allow uploading an object only if one doesn't exist yet. + example: "*" + required: false + schema: + type: string + pattern: '^\*$' # Currently, only "*" is supported responses: NotFoundOrNoACL: @@ -1299,9 +1310,6 @@ components: force: type: boolean default: false - if_absent: - type: boolean - default: false required: - staging - checksum @@ -4167,6 +4175,10 @@ paths: application/json: schema: $ref: "#/components/schemas/StagingMetadata" + + parameters: + - $ref: "#/components/parameters/IfNonMatch" + responses: 200: # This actually violates HTTP, which requires returning 201 if a new object was @@ -4400,6 +4412,7 @@ paths: format: binary parameters: + - $ref: "#/components/parameters/IfNonMatch" - in: query name: storageClass description: Deprecated, this capability will not be supported in future releases. @@ -4407,17 +4420,6 @@ paths: deprecated: true schema: type: string - - in: header - name: If-None-Match - description: | - Currently supports only "*" to allow uploading an object only if one doesn't exist yet. - Deprecated, this capability will not be supported in future releases. - example: "*" - required: false - deprecated: true - schema: - type: string - pattern: '^\*$' # Currently, only "*" is supported - in: query name: force required: false diff --git a/pkg/api/controller.go b/pkg/api/controller.go index 48e9b476329..0118a91ab64 100644 --- a/pkg/api/controller.go +++ b/pkg/api/controller.go @@ -683,7 +683,8 @@ func (c *Controller) LinkPhysicalAddress(w http.ResponseWriter, r *http.Request, entryBuilder.Metadata(body.UserMetadata.AdditionalProperties) } entry := entryBuilder.Build() - err = c.Catalog.CreateEntry(ctx, repo.Name, branch, entry, graveler.WithForce(swag.BoolValue(body.Force)), graveler.WithIfAbsent(swag.BoolValue(body.IfAbsent))) + ifAbsent := params.IfNoneMatch != nil + err = c.Catalog.CreateEntry(ctx, repo.Name, branch, entry, graveler.WithForce(swag.BoolValue(body.Force)), graveler.WithIfAbsent(ifAbsent)) if c.handleAPIError(ctx, w, r, err) { return } @@ -3005,10 +3006,6 @@ func (c *Controller) UploadObject(w http.ResponseWriter, r *http.Request, reposi // and then graveler will check again when passed a SetOptions. allowOverwrite := true if params.IfNoneMatch != nil { - if swag.StringValue(params.IfNoneMatch) != "*" { - writeError(w, r, http.StatusBadRequest, "Unsupported value for If-None-Match - Only \"*\" is supported") - return - } // check if exists _, err := c.Catalog.GetEntry(ctx, repo.Name, branch, params.Path, catalog.GetEntryParams{}) if err == nil { diff --git a/pkg/api/controller_test.go b/pkg/api/controller_test.go index 17151cdcda2..fe446c4f3ec 100644 --- a/pkg/api/controller_test.go +++ b/pkg/api/controller_test.go @@ -2081,7 +2081,7 @@ func TestController_UploadObjectHandler(t *testing.T) { } // overwrite contentType, buf = writeMultipart("content", "baz2", "something else!") - all := "*" + all := apigen.IfNonMatch("*") b, err = clt.UploadObjectWithBodyWithResponse(ctx, "my-new-repo", "main", &apigen.UploadObjectParams{ Path: "foo/baz2", IfNoneMatch: &all, @@ -2112,7 +2112,7 @@ func TestController_UploadObjectHandler(t *testing.T) { testutil.Must(t, err) // overwrite after commit - all := "*" + all := apigen.IfNonMatch("*") contentType, buf = writeMultipart("content", "baz3", "something else!") b, err = clt.UploadObjectWithBodyWithResponse(ctx, "my-new-repo", "another-branch", &apigen.UploadObjectParams{ Path: "foo/baz3", @@ -2126,11 +2126,11 @@ func TestController_UploadObjectHandler(t *testing.T) { }) t.Run("disable overwrite with if-none-match (no entry)", func(t *testing.T) { - ifNoneMatch := apiutil.Ptr("*") + ifNoneMatch := apigen.IfNonMatch("*") contentType, buf := writeMultipart("content", "baz4", "something else!") resp, err := clt.UploadObjectWithBodyWithResponse(ctx, "my-new-repo", "main", &apigen.UploadObjectParams{ Path: "foo/baz4", - IfNoneMatch: ifNoneMatch, + IfNoneMatch: &ifNoneMatch, }, contentType, buf) if err != nil { t.Fatalf("UploadObject err=%s, expected no error", err) @@ -3014,7 +3014,6 @@ func TestController_LinkPhysicalAddressHandler(t *testing.T) { t.Fatalf("GetPhysicalAddress non 200 response - status code %d", linkResp.StatusCode()) } const expectedSizeBytes = 38 - ifAbsent := false resp, err := clt.LinkPhysicalAddressWithResponse(ctx, repo, "main", &apigen.LinkPhysicalAddressParams{ Path: "foo/bar2", }, apigen.LinkPhysicalAddressJSONRequestBody{ @@ -3023,7 +3022,6 @@ func TestController_LinkPhysicalAddressHandler(t *testing.T) { Staging: apigen.StagingLocation{ PhysicalAddress: linkResp.JSON200.PhysicalAddress, }, - IfAbsent: &ifAbsent, }) verifyResponseOK(t, resp, err) @@ -3033,16 +3031,16 @@ func TestController_LinkPhysicalAddressHandler(t *testing.T) { if linkResp.JSON200 == nil { t.Fatalf("GetPhysicalAddress non 200 response - status code %d", linkResp.StatusCode()) } - ifAbsent = true + ifNonMatch := apigen.IfNonMatch("*") resp, err = clt.LinkPhysicalAddressWithResponse(ctx, repo, "main", &apigen.LinkPhysicalAddressParams{ - Path: "foo/bar2", + Path: "foo/bar2", + IfNoneMatch: &ifNonMatch, }, apigen.LinkPhysicalAddressJSONRequestBody{ Checksum: "afb0689fe58b82c5f762991453edbbec", SizeBytes: expectedSizeBytes, Staging: apigen.StagingLocation{ PhysicalAddress: linkResp.JSON200.PhysicalAddress, }, - IfAbsent: &ifAbsent, }) testutil.Must(t, err) expectedStatusCode := http.StatusPreconditionFailed diff --git a/pkg/graveler/graveler_test.go b/pkg/graveler/graveler_test.go index ba1f1353a28..5c4af6b08e0 100644 --- a/pkg/graveler/graveler_test.go +++ b/pkg/graveler/graveler_test.go @@ -324,6 +324,7 @@ func TestGraveler_Set(t *testing.T) { stagingMgr: &testutil.StagingFake{}, refMgr: &testutil.RefsFake{Branch: &graveler.Branch{CommitID: "bla"}, Commits: map[graveler.CommitID]*graveler.Commit{"": {}}}, expectedValueResult: nil, + expectedErr: graveler.ErrPreconditionFailed, ifAbsent: true, }, { @@ -332,6 +333,7 @@ func TestGraveler_Set(t *testing.T) { stagingMgr: &testutil.StagingFake{Values: map[string]map[string]*graveler.Value{"st": {"key": sampleVal}}, LastSetValueRecord: &graveler.ValueRecord{Key: []byte("key"), Value: sampleVal}}, refMgr: &testutil.RefsFake{Branch: &graveler.Branch{CommitID: "bla", StagingToken: "st"}, Commits: map[graveler.CommitID]*graveler.Commit{"": {}}}, expectedValueResult: &graveler.ValueRecord{Key: []byte("key"), Value: sampleVal}, + expectedErr: graveler.ErrPreconditionFailed, ifAbsent: true, }, {