diff --git a/blob/blob-aws/src/test/java/com/salesforce/multicloudj/blob/aws/AwsBlobStoreIT.java b/blob/blob-aws/src/test/java/com/salesforce/multicloudj/blob/aws/AwsBlobStoreIT.java index 61e247c29..9b6beb6b5 100644 --- a/blob/blob-aws/src/test/java/com/salesforce/multicloudj/blob/aws/AwsBlobStoreIT.java +++ b/blob/blob-aws/src/test/java/com/salesforce/multicloudj/blob/aws/AwsBlobStoreIT.java @@ -57,6 +57,11 @@ public AbstractBlobStore createBlobStore(boolean useValidBucket, boolean useVali return createBlobStore(bucketNameToUse, credentialsOverrider); } + @Override + public boolean isObjectLockSupported() { + return true; + } + private AbstractBlobStore createBlobStore(final String bucketName, final CredentialsOverrider credentialsOverrider) { AwsSessionCredentials awsCredentials = AwsSessionCredentials.create( diff --git a/blob/blob-aws/src/test/resources/mappings/delete-5wi9bl80gj.json b/blob/blob-aws/src/test/resources/mappings/delete-5wi9bl80gj.json new file mode 100644 index 000000000..78ba8d3ec --- /dev/null +++ b/blob/blob-aws/src/test/resources/mappings/delete-5wi9bl80gj.json @@ -0,0 +1,22 @@ +{ + "id" : "9128ed99-d86c-4570-a55e-8ebc755dd931", + "name" : "chameleon-jcloud-versioned_conformance-tests_objectlock_retention-compliance", + "request" : { + "url" : "/chameleon-jcloud-versioned/conformance-tests/objectlock/retention-compliance", + "method" : "DELETE" + }, + "response" : { + "status" : 204, + "headers" : { + "Server" : "AmazonS3", + "x-amz-delete-marker" : "true", + "x-amz-request-id" : "C23ABJCWFSRXW4K0", + "x-amz-id-2" : "MLoEc2sWyXmlIIhbwmOi+5CHcWSSZeb60O9zSrCBzSMEhMN6kmrl8/vy4iGCBvA6sRAkyujJ4zh8sptutw0ya7MRZj8aH/Kd", + "x-amz-version-id" : "0RgbnwcYl_V5zHPmusuDFt8VFbd3AupL", + "Date" : "Fri, 06 Feb 2026 20:00:16 GMT" + } + }, + "uuid" : "9128ed99-d86c-4570-a55e-8ebc755dd931", + "persistent" : true, + "insertionIndex" : 614 +} \ No newline at end of file diff --git a/blob/blob-aws/src/test/resources/mappings/delete-vkfpscvsg1.json b/blob/blob-aws/src/test/resources/mappings/delete-vkfpscvsg1.json new file mode 100644 index 000000000..08617e2a0 --- /dev/null +++ b/blob/blob-aws/src/test/resources/mappings/delete-vkfpscvsg1.json @@ -0,0 +1,22 @@ +{ + "id" : "7198d55b-c61b-4ecb-a4e0-4fd6226a4add", + "name" : "chameleon-jcloud-versioned_conformance-tests_objectlock_retention-governance", + "request" : { + "url" : "/chameleon-jcloud-versioned/conformance-tests/objectlock/retention-governance", + "method" : "DELETE" + }, + "response" : { + "status" : 204, + "headers" : { + "Server" : "AmazonS3", + "x-amz-delete-marker" : "true", + "x-amz-request-id" : "1YEXQ12C579RW0KQ", + "x-amz-id-2" : "qyXEwb1T0zhsflhscoSkSYHfouB8AmoZdd65/TvtY2JTOW59XBWF0Q0JesbKQ5q3surPipEb9dNJ8Oiqh7cMlSV4G16Ffp+j", + "x-amz-version-id" : "XIyxjBTeuMrVLlQhZyBknIysvYH2fSGK", + "Date" : "Fri, 06 Feb 2026 20:00:19 GMT" + } + }, + "uuid" : "7198d55b-c61b-4ecb-a4e0-4fd6226a4add", + "persistent" : true, + "insertionIndex" : 619 +} \ No newline at end of file diff --git a/blob/blob-aws/src/test/resources/mappings/delete-zc3job12kj.json b/blob/blob-aws/src/test/resources/mappings/delete-zc3job12kj.json new file mode 100644 index 000000000..d95fa9e15 --- /dev/null +++ b/blob/blob-aws/src/test/resources/mappings/delete-zc3job12kj.json @@ -0,0 +1,22 @@ +{ + "id" : "aa2145d4-1c1b-423d-924f-057d98ebbe16", + "name" : "chameleon-jcloud-versioned_conformance-tests_objectlock_no-lock", + "request" : { + "url" : "/chameleon-jcloud-versioned/conformance-tests/objectlock/no-lock", + "method" : "DELETE" + }, + "response" : { + "status" : 204, + "headers" : { + "Server" : "AmazonS3", + "x-amz-delete-marker" : "true", + "x-amz-request-id" : "E2QV4DT8PTVMRM4G", + "x-amz-id-2" : "jiiJxUakuDURxGBT51SfcjtaoO1IQDnPpJ74FDNrrIuUpoqRzfZ0UhW2oJMHoKq+vkd9+S779ozwgEHfaBcTMDZ4WolgiERE", + "x-amz-version-id" : "lMcN19fE1JZNwdtTafPoKlg90sChfKhN", + "Date" : "Fri, 06 Feb 2026 20:00:12 GMT" + } + }, + "uuid" : "aa2145d4-1c1b-423d-924f-057d98ebbe16", + "persistent" : true, + "insertionIndex" : 608 +} \ No newline at end of file diff --git a/blob/blob-aws/src/test/resources/mappings/get-6wbl1f0j9t.json b/blob/blob-aws/src/test/resources/mappings/get-6wbl1f0j9t.json new file mode 100644 index 000000000..078e55a37 --- /dev/null +++ b/blob/blob-aws/src/test/resources/mappings/get-6wbl1f0j9t.json @@ -0,0 +1,21 @@ +{ + "id" : "611524a6-323a-4db2-876f-8ba87d7b18ef", + "name" : "chameleon-jcloud-versioned_conformance-tests_objectlock_retention-compliance", + "request" : { + "url" : "/chameleon-jcloud-versioned/conformance-tests/objectlock/retention-compliance?retention", + "method" : "GET" + }, + "response" : { + "status" : 200, + "base64Body" : "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPFJldGVudGlvbiB4bWxucz0iaHR0cDovL3MzLmFtYXpvbmF3cy5jb20vZG9jLzIwMDYtMDMtMDEvIj48TW9kZT5DT01QTElBTkNFPC9Nb2RlPjxSZXRhaW5VbnRpbERhdGU+MjAyNi0wMi0wN1QyMDowMDoxMS45MTZaPC9SZXRhaW5VbnRpbERhdGU+PC9SZXRlbnRpb24+", + "headers" : { + "Server" : "AmazonS3", + "x-amz-request-id" : "7Y29EQQXX4YRQ62V", + "x-amz-id-2" : "SV0qkewBtQqyCSx7ItCA1I3gQ2TtIDuXE/hcEDQL/634+ZKIfbTszIcvvZbCdfzKhl3YtJHiNkStg4irE1AVP3p2ASZAKBTh", + "Date" : "Fri, 06 Feb 2026 20:00:13 GMT" + } + }, + "uuid" : "611524a6-323a-4db2-876f-8ba87d7b18ef", + "persistent" : true, + "insertionIndex" : 616 +} \ No newline at end of file diff --git a/blob/blob-aws/src/test/resources/mappings/get-dtkyrojxp0.json b/blob/blob-aws/src/test/resources/mappings/get-dtkyrojxp0.json new file mode 100644 index 000000000..0931dca5a --- /dev/null +++ b/blob/blob-aws/src/test/resources/mappings/get-dtkyrojxp0.json @@ -0,0 +1,22 @@ +{ + "id" : "6dcec650-0822-426b-9c7e-627c19a53f79", + "name" : "chameleon-jcloud-versioned_conformance-tests_objectlock_nonexistent", + "request" : { + "url" : "/chameleon-jcloud-versioned/conformance-tests/objectlock/nonexistent?retention", + "method" : "GET" + }, + "response" : { + "status" : 404, + "body" : "\nNoSuchKeyThe specified key does not exist.conformance-tests/objectlock/nonexistentE2QS9BPQM508ZYTPTfte+PiDMU55Rd3ptoQW0bgwDAmEnkTpJkaAOmmag6CIRi+xPOE5w3F8ZtihAHOjhbGe8NQMP5v6Re9miaKhzwCubJcQh/Bw", + "headers" : { + "Server" : "AmazonS3", + "x-amz-request-id" : "E2QS9BPQM508ZYTP", + "x-amz-id-2" : "Tfte+PiDMU55Rd3ptoQW0bgwDAmEnkTpJkaAOmmag6CIRi+xPOE5w3F8ZtihAHOjhbGe8NQMP5v6Re9miaKhzwCubJcQh/Bw", + "Date" : "Fri, 06 Feb 2026 20:00:11 GMT", + "Content-Type" : "application/xml" + } + }, + "uuid" : "6dcec650-0822-426b-9c7e-627c19a53f79", + "persistent" : true, + "insertionIndex" : 612 +} \ No newline at end of file diff --git a/blob/blob-aws/src/test/resources/mappings/get-fcaqtgbgub.json b/blob/blob-aws/src/test/resources/mappings/get-fcaqtgbgub.json new file mode 100644 index 000000000..a5f46b52e --- /dev/null +++ b/blob/blob-aws/src/test/resources/mappings/get-fcaqtgbgub.json @@ -0,0 +1,21 @@ +{ + "id" : "e00b9056-fecb-4ec4-9769-847cee9f9da3", + "name" : "chameleon-jcloud-versioned_conformance-tests_objectlock_retention-compliance", + "request" : { + "url" : "/chameleon-jcloud-versioned/conformance-tests/objectlock/retention-compliance?legal-hold", + "method" : "GET" + }, + "response" : { + "status" : 200, + "base64Body" : "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExlZ2FsSG9sZCB4bWxucz0iaHR0cDovL3MzLmFtYXpvbmF3cy5jb20vZG9jLzIwMDYtMDMtMDEvIj48U3RhdHVzPk9GRjwvU3RhdHVzPjwvTGVnYWxIb2xkPg==", + "headers" : { + "Server" : "AmazonS3", + "x-amz-request-id" : "C23FABFN3SN6PG1B", + "x-amz-id-2" : "H4u8GFY0H5QZYjQl7FKqdV3EmLAnliaJAQDJ4/td8uC596pQ5wtszuVh48//gHrrM8PA/wrjy9eFcUeOJ6ORZAJ+61nf6KVt", + "Date" : "Fri, 06 Feb 2026 20:00:16 GMT" + } + }, + "uuid" : "e00b9056-fecb-4ec4-9769-847cee9f9da3", + "persistent" : true, + "insertionIndex" : 615 +} \ No newline at end of file diff --git a/blob/blob-aws/src/test/resources/mappings/get-qmwrx6fg5w.json b/blob/blob-aws/src/test/resources/mappings/get-qmwrx6fg5w.json new file mode 100644 index 000000000..dd77b0b6f --- /dev/null +++ b/blob/blob-aws/src/test/resources/mappings/get-qmwrx6fg5w.json @@ -0,0 +1,21 @@ +{ + "id" : "0dc7e8dd-9e38-45e4-b2bd-0368d9a13bd8", + "name" : "chameleon-jcloud-versioned_conformance-tests_objectlock_retention-governance", + "request" : { + "url" : "/chameleon-jcloud-versioned/conformance-tests/objectlock/retention-governance?legal-hold", + "method" : "GET" + }, + "response" : { + "status" : 200, + "base64Body" : "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExlZ2FsSG9sZCB4bWxucz0iaHR0cDovL3MzLmFtYXpvbmF3cy5jb20vZG9jLzIwMDYtMDMtMDEvIj48U3RhdHVzPk9GRjwvU3RhdHVzPjwvTGVnYWxIb2xkPg==", + "headers" : { + "Server" : "AmazonS3", + "x-amz-request-id" : "WXBAJ5BCDB6PKFNQ", + "x-amz-id-2" : "wR/R6DkhCWPKkkDIWXU7h1EgU6+Yvnjj0SnvopHwN9tev1G0V94cTHqEUac2g9E3bahqNeatBn1tZvz52qqRUS9eqLPIBCom", + "Date" : "Fri, 06 Feb 2026 20:00:18 GMT" + } + }, + "uuid" : "0dc7e8dd-9e38-45e4-b2bd-0368d9a13bd8", + "persistent" : true, + "insertionIndex" : 620 +} \ No newline at end of file diff --git a/blob/blob-aws/src/test/resources/mappings/get-u6nywavkbn.json b/blob/blob-aws/src/test/resources/mappings/get-u6nywavkbn.json new file mode 100644 index 000000000..17a3fda58 --- /dev/null +++ b/blob/blob-aws/src/test/resources/mappings/get-u6nywavkbn.json @@ -0,0 +1,22 @@ +{ + "id" : "dd95a9a9-9e6d-4953-9adc-89e7a0185f43", + "name" : "chameleon-jcloud-versioned_conformance-tests_objectlock_no-lock", + "request" : { + "url" : "/chameleon-jcloud-versioned/conformance-tests/objectlock/no-lock?retention", + "method" : "GET" + }, + "response" : { + "status" : 404, + "body" : "\nNoSuchObjectLockConfigurationThe specified object does not have a ObjectLock configuration7JHPTBAXJHCYX1R7nNGCN7quGVRkRpcCHDzMhZnUIqs60PXeC3IrbCDjfYuXtdV1YKseAxs4dSGEVSYzrDEIV8seTM8TjRP4XD5xUhjfvgdnOE7g", + "headers" : { + "Server" : "AmazonS3", + "x-amz-request-id" : "7JHPTBAXJHCYX1R7", + "x-amz-id-2" : "nNGCN7quGVRkRpcCHDzMhZnUIqs60PXeC3IrbCDjfYuXtdV1YKseAxs4dSGEVSYzrDEIV8seTM8TjRP4XD5xUhjfvgdnOE7g", + "Date" : "Fri, 06 Feb 2026 20:00:10 GMT", + "Content-Type" : "application/xml" + } + }, + "uuid" : "dd95a9a9-9e6d-4953-9adc-89e7a0185f43", + "persistent" : true, + "insertionIndex" : 609 +} \ No newline at end of file diff --git a/blob/blob-aws/src/test/resources/mappings/get-ymd9e7ep32.json b/blob/blob-aws/src/test/resources/mappings/get-ymd9e7ep32.json new file mode 100644 index 000000000..b9d230ad6 --- /dev/null +++ b/blob/blob-aws/src/test/resources/mappings/get-ymd9e7ep32.json @@ -0,0 +1,21 @@ +{ + "id" : "2f00cb5c-d843-49db-b554-19207256f5e7", + "name" : "chameleon-jcloud-versioned_conformance-tests_objectlock_retention-governance", + "request" : { + "url" : "/chameleon-jcloud-versioned/conformance-tests/objectlock/retention-governance?retention", + "method" : "GET" + }, + "response" : { + "status" : 200, + "base64Body" : "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPFJldGVudGlvbiB4bWxucz0iaHR0cDovL3MzLmFtYXpvbmF3cy5jb20vZG9jLzIwMDYtMDMtMDEvIj48TW9kZT5HT1ZFUk5BTkNFPC9Nb2RlPjxSZXRhaW5VbnRpbERhdGU+MjAyNi0wMi0wN1QyMDowMDoxNS44OTFaPC9SZXRhaW5VbnRpbERhdGU+PC9SZXRlbnRpb24+", + "headers" : { + "Server" : "AmazonS3", + "x-amz-request-id" : "WXB2QJ1M2XQYR34A", + "x-amz-id-2" : "xrgTXDlXYgwvVDuRbOy4ZQijJkTu67qe36AIprLJHlLJ0rnqE7BXsSYlnQ8cc+BYbrc84pPr+wqqjAeMxau4a+BAkEUVsoJn", + "Date" : "Fri, 06 Feb 2026 20:00:18 GMT" + } + }, + "uuid" : "2f00cb5c-d843-49db-b554-19207256f5e7", + "persistent" : true, + "insertionIndex" : 621 +} \ No newline at end of file diff --git a/blob/blob-aws/src/test/resources/mappings/put-ievkn426z3.json b/blob/blob-aws/src/test/resources/mappings/put-ievkn426z3.json new file mode 100644 index 000000000..45f0df537 --- /dev/null +++ b/blob/blob-aws/src/test/resources/mappings/put-ievkn426z3.json @@ -0,0 +1,28 @@ +{ + "id" : "59624aa0-ea9e-4ecc-97b0-9216a5ce865f", + "name" : "chameleon-jcloud-versioned_conformance-tests_objectlock_retention-compliance", + "request" : { + "url" : "/chameleon-jcloud-versioned/conformance-tests/objectlock/retention-compliance", + "method" : "PUT", + "bodyPatterns" : [ { + "binaryEqualTo" : "T2JqZWN0IGxvY2sgcmV0ZW50aW9uIGNvbXBsaWFuY2UgdGVzdA==" + } ] + }, + "response" : { + "status" : 200, + "headers" : { + "Server" : "AmazonS3", + "ETag" : "\"a0d246afc0f8baf1e7dd602c80efd967\"", + "x-amz-checksum-type" : "FULL_OBJECT", + "x-amz-request-id" : "7Y27F0JTG6BQ309P", + "x-amz-checksum-crc32c" : "4z8aNg==", + "x-amz-server-side-encryption" : "AES256", + "x-amz-id-2" : "33jV28bqt3rbRAgU4yEqZI+31fgfqmBWeh7SbWyoJpj18EIGEXpO+kFDBmGguMqnrIOe3XwvjaqrXm//cCQkIB8aTlVxshD5", + "x-amz-version-id" : "zLsUsFgmtnxTZCDrCMNEl40YqfTx..oB", + "Date" : "Fri, 06 Feb 2026 20:00:13 GMT" + } + }, + "uuid" : "59624aa0-ea9e-4ecc-97b0-9216a5ce865f", + "persistent" : true, + "insertionIndex" : 617 +} \ No newline at end of file diff --git a/blob/blob-aws/src/test/resources/mappings/put-riacevxmhn.json b/blob/blob-aws/src/test/resources/mappings/put-riacevxmhn.json new file mode 100644 index 000000000..d7d60144d --- /dev/null +++ b/blob/blob-aws/src/test/resources/mappings/put-riacevxmhn.json @@ -0,0 +1,28 @@ +{ + "id" : "48f566ce-94a6-4d4c-ac5f-5b8268399987", + "name" : "chameleon-jcloud-versioned_conformance-tests_objectlock_no-lock", + "request" : { + "url" : "/chameleon-jcloud-versioned/conformance-tests/objectlock/no-lock", + "method" : "PUT", + "bodyPatterns" : [ { + "binaryEqualTo" : "T2JqZWN0IHdpdGhvdXQgbG9jayB0ZXN0" + } ] + }, + "response" : { + "status" : 200, + "headers" : { + "Server" : "AmazonS3", + "ETag" : "\"fdd2c398fd6d009c474f1f9a02d38ec5\"", + "x-amz-checksum-crc64nvme" : "59pOl5UH6tE=", + "x-amz-checksum-type" : "FULL_OBJECT", + "x-amz-request-id" : "7JHK68N47E4ZRWSQ", + "x-amz-server-side-encryption" : "AES256", + "x-amz-id-2" : "YScnzGFcPCL7GM0FLOaNQcXRX/dDB5qEl+SFmLQUHVURw6x9eRtZVc6u2EFBxFM4p+BNH9FBWnoUP80AaSlnVJL1JFYdnWYQ", + "x-amz-version-id" : "nMqKRM_DQzj1_w2Pn52cIMooegPvSHz5", + "Date" : "Fri, 06 Feb 2026 20:00:11 GMT" + } + }, + "uuid" : "48f566ce-94a6-4d4c-ac5f-5b8268399987", + "persistent" : true, + "insertionIndex" : 610 +} \ No newline at end of file diff --git a/blob/blob-aws/src/test/resources/mappings/put-sp1enepgxu.json b/blob/blob-aws/src/test/resources/mappings/put-sp1enepgxu.json new file mode 100644 index 000000000..a4bbf5cca --- /dev/null +++ b/blob/blob-aws/src/test/resources/mappings/put-sp1enepgxu.json @@ -0,0 +1,28 @@ +{ + "id" : "1dfcd8e4-17e1-4b89-b83e-6e8462167d65", + "name" : "chameleon-jcloud-versioned_conformance-tests_objectlock_retention-governance", + "request" : { + "url" : "/chameleon-jcloud-versioned/conformance-tests/objectlock/retention-governance", + "method" : "PUT", + "bodyPatterns" : [ { + "binaryEqualTo" : "T2JqZWN0IGxvY2sgcmV0ZW50aW9uIGdvdmVybmFuY2UgdGVzdA==" + } ] + }, + "response" : { + "status" : 200, + "headers" : { + "Server" : "AmazonS3", + "ETag" : "\"7e7cee74a915a322ef6c75c3ab034d4f\"", + "x-amz-checksum-type" : "FULL_OBJECT", + "x-amz-request-id" : "0TJ4VZ9FH6KD5WK6", + "x-amz-checksum-crc32c" : "s67YvA==", + "x-amz-server-side-encryption" : "AES256", + "x-amz-id-2" : "hupN+V74krKCrybh1oxcxWN1YBCKITqnYb9Yn146ZfeTDsrMy+yNM6A2U1Q29wFFAp2gUGo2cuSYGUkRKzrsOw97LQDeUaoS", + "x-amz-version-id" : "gxWcsKRtCMgLuudI4nVJ4MPxZLnPJL1i", + "Date" : "Fri, 06 Feb 2026 20:00:17 GMT" + } + }, + "uuid" : "1dfcd8e4-17e1-4b89-b83e-6e8462167d65", + "persistent" : true, + "insertionIndex" : 622 +} \ No newline at end of file diff --git a/blob/blob-client/src/test/java/com/salesforce/multicloudj/blob/client/AbstractBlobStoreIT.java b/blob/blob-client/src/test/java/com/salesforce/multicloudj/blob/client/AbstractBlobStoreIT.java index 8023b3d39..703db12fc 100644 --- a/blob/blob-client/src/test/java/com/salesforce/multicloudj/blob/client/AbstractBlobStoreIT.java +++ b/blob/blob-client/src/test/java/com/salesforce/multicloudj/blob/client/AbstractBlobStoreIT.java @@ -17,7 +17,10 @@ import com.salesforce.multicloudj.blob.driver.MultipartUpload; import com.salesforce.multicloudj.blob.driver.MultipartUploadRequest; import com.salesforce.multicloudj.blob.driver.PresignedOperation; +import com.salesforce.multicloudj.blob.driver.ObjectLockConfiguration; +import com.salesforce.multicloudj.blob.driver.ObjectLockInfo; import com.salesforce.multicloudj.blob.driver.PresignedUrlRequest; +import com.salesforce.multicloudj.blob.driver.RetentionMode; import com.salesforce.multicloudj.blob.driver.UploadPartResponse; import com.salesforce.multicloudj.blob.driver.UploadRequest; import com.salesforce.multicloudj.blob.driver.UploadResponse; @@ -52,6 +55,7 @@ import java.nio.file.Path; import java.time.Duration; import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -74,6 +78,23 @@ public interface Harness extends AutoCloseable { // Method to create a blob driver AbstractBlobStore createBlobStore(boolean useValidBucket, boolean useValidCredentials, boolean useVersionedBucket); + /** + * Creates a blob store, optionally with an object-lock-enabled bucket. + * Default implementation ignores useObjectLockBucket and delegates to the 3-arg overload. + * Override in providers that support object lock (e.g. AWS, GCP) to use an object-lock bucket when true. + */ + default AbstractBlobStore createBlobStore(boolean useValidBucket, boolean useValidCredentials, + boolean useVersionedBucket, boolean useObjectLockBucket) { + return createBlobStore(useValidBucket, useValidCredentials, useVersionedBucket); + } + + /** + * Whether this provider supports object lock (WORM). When false, object lock conformance tests are skipped. + */ + default boolean isObjectLockSupported() { + return false; + } + // provide the BlobClient endpoint in provider String getEndpoint(); @@ -122,13 +143,22 @@ default String computeChecksum(byte[] content) { private static final String GCP_PROVIDER_ID = "gcp"; + /** + * WireMock extension class names (e.g. StubMappingTransformer) to load for replay. + * Override to add provider-specific transformers (e.g. relax body matching for object lock). + */ + protected String[] getWireMockExtensionClasses() { + return new String[0]; + } + /** * Initializes the WireMock server before all tests. */ @BeforeAll public void initializeWireMockServer() { harness = createHarness(); - TestsUtil.startWireMockServer("src/test/resources", harness.getPort()); + TestsUtil.startWireMockServer( + "src/test/resources", harness.getPort(), getWireMockExtensionClasses()); } /** @@ -1801,6 +1831,126 @@ public TestConfig(String testName, String key, byte[] content, Map bucketClient.getObjectLock("conformance-tests/objectlock/nonexistent", null)); + } + @Test public void testGetVersionedMetadata() throws IOException { diff --git a/blob/blob-gcp/src/test/java/com/salesforce/multicloudj/blob/gcp/GcpBlobStoreIT.java b/blob/blob-gcp/src/test/java/com/salesforce/multicloudj/blob/gcp/GcpBlobStoreIT.java index eb9756d0c..0f8b9ba37 100644 --- a/blob/blob-gcp/src/test/java/com/salesforce/multicloudj/blob/gcp/GcpBlobStoreIT.java +++ b/blob/blob-gcp/src/test/java/com/salesforce/multicloudj/blob/gcp/GcpBlobStoreIT.java @@ -19,9 +19,12 @@ import java.net.URI; import java.util.concurrent.ThreadLocalRandom; +import static com.salesforce.multicloudj.common.util.common.TestsUtil.WIREMOCK_HOST; + public class GcpBlobStoreIT extends AbstractBlobStoreIT { private static final String endpoint = "https://storage.googleapis.com"; + private static final String bucketName = "substrate-sdk-gcp-poc1-test-bucket"; private static final String versionedBucketName = "substrate-sdk-gcp-poc1-test-bucket-versioned"; private static final String nonExistentBucketName = "java-bucket-does-not-exist"; @@ -59,9 +62,22 @@ public AbstractBlobStore createBlobStore(boolean useValidBucket, boolean useVali } } - private AbstractBlobStore createBlobStore(final String bucketName, final Credentials credentials){ + @Override + public AbstractBlobStore createBlobStore(boolean useValidBucket, boolean useValidCredentials, + boolean useVersionedBucket, boolean useObjectLockBucket) { + // GCP retention/legal hold works on any bucket; use versioned bucket for object lock tests + return createBlobStore(useValidBucket, useValidCredentials, useVersionedBucket || useObjectLockBucket); + } - HttpTransport httpTransport = TestsUtilGcp.getHttpTransport(port); + @Override + public boolean isObjectLockSupported() { + return true; + } + + private AbstractBlobStore createBlobStore(final String bucketName, final Credentials credentials){ + // Connect directly to WireMock HTTPS so it can record/replay the full request (no CONNECT tunnel) + String host = "https://" + WIREMOCK_HOST + ":" + port; + HttpTransport httpTransport = TestsUtilGcp.getHttpTransportDirect(port); HttpTransportOptions transportOptions = HttpTransportOptions.newBuilder() .setHttpTransportFactory(() -> httpTransport) .build(); @@ -69,7 +85,7 @@ private AbstractBlobStore createBlobStore(final String bucketName, final Credent Storage storage = StorageOptions.newBuilder() .setTransportOptions(transportOptions) .setCredentials(credentials) - .setHost(endpoint) + .setHost(host) .build().getService(); diff --git a/blob/blob-gcp/src/test/resources/mappings/delete-06fviw5cly.json b/blob/blob-gcp/src/test/resources/mappings/delete-06fviw5cly.json new file mode 100644 index 000000000..8c63a905c --- /dev/null +++ b/blob/blob-gcp/src/test/resources/mappings/delete-06fviw5cly.json @@ -0,0 +1,25 @@ +{ + "id" : "68501692-9dee-40f4-a6a4-2ad61d5348f0", + "name" : "storage_v1_b_substrate-sdk-gcp-poc1-test-bucket-versioned_o_conformance-tests_objectlock_no-lock", + "request" : { + "url" : "/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned/o/conformance-tests%2Fobjectlock%2Fno-lock", + "method" : "DELETE" + }, + "response" : { + "status" : 204, + "headers" : { + "Alt-Svc" : "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "Server" : "UploadServer", + "Cache-Control" : "no-cache, no-store, max-age=0, must-revalidate", + "X-GUploader-UploadID" : "AJRbA5VnqE4Flo6Ko9OgVhLdGHoE7ppgXZLdDUQ35ds1YDsN71CLTIEWYo37pYVvlRAsYKW5qt2dV5M", + "Vary" : [ "Origin", "X-Origin" ], + "Pragma" : "no-cache", + "Expires" : "Mon, 01 Jan 1990 00:00:00 GMT", + "Date" : "Fri, 06 Feb 2026 19:33:35 GMT", + "Content-Type" : "application/json" + } + }, + "uuid" : "68501692-9dee-40f4-a6a4-2ad61d5348f0", + "persistent" : true, + "insertionIndex" : 951 +} \ No newline at end of file diff --git a/blob/blob-gcp/src/test/resources/mappings/delete-0ltakthvrn.json b/blob/blob-gcp/src/test/resources/mappings/delete-0ltakthvrn.json new file mode 100644 index 000000000..6255b1c13 --- /dev/null +++ b/blob/blob-gcp/src/test/resources/mappings/delete-0ltakthvrn.json @@ -0,0 +1,25 @@ +{ + "id" : "05f67bd6-ccdb-4804-b2a9-5ba3b57b55c9", + "name" : "storage_v1_b_substrate-sdk-gcp-poc1-test-bucket-versioned_o_conformance-tests_objectlock_retention-compliance", + "request" : { + "url" : "/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned/o/conformance-tests%2Fobjectlock%2Fretention-compliance", + "method" : "DELETE" + }, + "response" : { + "status" : 204, + "headers" : { + "Alt-Svc" : "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "Server" : "UploadServer", + "Cache-Control" : "no-cache, no-store, max-age=0, must-revalidate", + "X-GUploader-UploadID" : "AJRbA5Xt8Om5j4CLBydZSvMygGfONhIrvOm7F99bZUvY9C39-Erfw26SWzhJu-vnzd_kz8q-UcUqmJ4", + "Vary" : [ "Origin", "X-Origin" ], + "Pragma" : "no-cache", + "Expires" : "Mon, 01 Jan 1990 00:00:00 GMT", + "Date" : "Fri, 06 Feb 2026 19:33:36 GMT", + "Content-Type" : "application/json" + } + }, + "uuid" : "05f67bd6-ccdb-4804-b2a9-5ba3b57b55c9", + "persistent" : true, + "insertionIndex" : 959 +} \ No newline at end of file diff --git a/blob/blob-gcp/src/test/resources/mappings/delete-sd5qoxlnch.json b/blob/blob-gcp/src/test/resources/mappings/delete-sd5qoxlnch.json new file mode 100644 index 000000000..6d50c7fb5 --- /dev/null +++ b/blob/blob-gcp/src/test/resources/mappings/delete-sd5qoxlnch.json @@ -0,0 +1,25 @@ +{ + "id" : "b19b6b38-398b-4ede-a8c8-7984025093a3", + "name" : "storage_v1_b_substrate-sdk-gcp-poc1-test-bucket-versioned_o_conformance-tests_objectlock_retention-governance", + "request" : { + "url" : "/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned/o/conformance-tests%2Fobjectlock%2Fretention-governance", + "method" : "DELETE" + }, + "response" : { + "status" : 204, + "headers" : { + "Alt-Svc" : "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "Server" : "UploadServer", + "Cache-Control" : "no-cache, no-store, max-age=0, must-revalidate", + "X-GUploader-UploadID" : "AJRbA5UNz41TRRsiutNAc6zx3Mf9tDxuQiUgGYgDOuwxLumCHoUt-8mlZmytEHoRGh2EsG6CH4igVns", + "Vary" : [ "Origin", "X-Origin" ], + "Pragma" : "no-cache", + "Expires" : "Mon, 01 Jan 1990 00:00:00 GMT", + "Date" : "Fri, 06 Feb 2026 19:33:38 GMT", + "Content-Type" : "application/json" + } + }, + "uuid" : "b19b6b38-398b-4ede-a8c8-7984025093a3", + "persistent" : true, + "insertionIndex" : 965 +} \ No newline at end of file diff --git a/blob/blob-gcp/src/test/resources/mappings/get-abqrpeam2d.json b/blob/blob-gcp/src/test/resources/mappings/get-abqrpeam2d.json new file mode 100644 index 000000000..7a146660b --- /dev/null +++ b/blob/blob-gcp/src/test/resources/mappings/get-abqrpeam2d.json @@ -0,0 +1,29 @@ +{ + "id" : "2162af26-cc0d-47f1-a434-912cb283feea", + "name" : "storage_v1_b_substrate-sdk-gcp-poc1-test-bucket-versioned_o_conformance-tests_objectlock_no-lock", + "request" : { + "url" : "/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned/o/conformance-tests%2Fobjectlock%2Fno-lock?projection=full", + "method" : "GET" + }, + "response" : { + "status" : 200, + "body" : "{\n \"kind\": \"storage#object\",\n \"id\": \"substrate-sdk-gcp-poc1-test-bucket-versioned/conformance-tests/objectlock/no-lock/1770406414100158\",\n \"selfLink\": \"https://www.googleapis.com/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned/o/conformance-tests%2Fobjectlock%2Fno-lock\",\n \"mediaLink\": \"https://storage.googleapis.com/download/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned/o/conformance-tests%2Fobjectlock%2Fno-lock?generation=1770406414100158&alt=media\",\n \"name\": \"conformance-tests/objectlock/no-lock\",\n \"bucket\": \"substrate-sdk-gcp-poc1-test-bucket-versioned\",\n \"generation\": \"1770406414100158\",\n \"metageneration\": \"1\",\n \"contentType\": \"application/octet-stream\",\n \"storageClass\": \"STANDARD\",\n \"size\": \"24\",\n \"md5Hash\": \"/dLDmP1tAJxHTx+aAtOOxQ==\",\n \"crc32c\": \"sPg8aA==\",\n \"etag\": \"CL7NruvNxZIDEAE=\",\n \"timeCreated\": \"2026-02-06T19:33:34.157Z\",\n \"updated\": \"2026-02-06T19:33:34.157Z\",\n \"timeStorageClassUpdated\": \"2026-02-06T19:33:34.157Z\",\n \"timeFinalized\": \"2026-02-06T19:33:34.157Z\"\n}\n", + "headers" : { + "Alt-Svc" : "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "Server" : "UploadServer", + "Cache-Control" : "private, max-age=0, must-revalidate, no-transform", + "ETag" : "CL7NruvNxZIDEAE=", + "X-GUploader-UploadID" : "AJRbA5VQomY4Sc0OtRzow2WlDM663_Iu8emZ0_H3w2k26nnYDHMzAmCyuj6TP67QoblXJ1_OhqF4Tsk", + "Vary" : [ "Origin", "X-Origin" ], + "Expires" : "Fri, 06 Feb 2026 19:33:34 GMT", + "Date" : "Fri, 06 Feb 2026 19:33:34 GMT", + "Content-Type" : "application/json; charset=UTF-8" + } + }, + "uuid" : "2162af26-cc0d-47f1-a434-912cb283feea", + "persistent" : true, + "scenarioName" : "scenario-1-storage-v1-b-substrate-sdk-gcp-poc1-test-bucket-versioned-o-conformance-tests-objectlock-no-lock", + "requiredScenarioState" : "Started", + "newScenarioState" : "scenario-1-storage-v1-b-substrate-sdk-gcp-poc1-test-bucket-versioned-o-conformance-tests-objectlock-no-lock-2", + "insertionIndex" : 954 +} \ No newline at end of file diff --git a/blob/blob-gcp/src/test/resources/mappings/get-cndoimbgwu.json b/blob/blob-gcp/src/test/resources/mappings/get-cndoimbgwu.json new file mode 100644 index 000000000..8b7d0d5ca --- /dev/null +++ b/blob/blob-gcp/src/test/resources/mappings/get-cndoimbgwu.json @@ -0,0 +1,28 @@ +{ + "id" : "37f83a89-470f-412e-aab7-9913a877cb96", + "name" : "storage_v1_b_substrate-sdk-gcp-poc1-test-bucket-versioned_o_conformance-tests_objectlock_retention-governance", + "request" : { + "url" : "/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned/o/conformance-tests%2Fobjectlock%2Fretention-governance?projection=full", + "method" : "GET" + }, + "response" : { + "status" : 200, + "body" : "{\n \"kind\": \"storage#object\",\n \"id\": \"substrate-sdk-gcp-poc1-test-bucket-versioned/conformance-tests/objectlock/retention-governance/1770406417555204\",\n \"selfLink\": \"https://www.googleapis.com/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned/o/conformance-tests%2Fobjectlock%2Fretention-governance\",\n \"mediaLink\": \"https://storage.googleapis.com/download/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned/o/conformance-tests%2Fobjectlock%2Fretention-governance?generation=1770406417555204&alt=media\",\n \"name\": \"conformance-tests/objectlock/retention-governance\",\n \"bucket\": \"substrate-sdk-gcp-poc1-test-bucket-versioned\",\n \"generation\": \"1770406417555204\",\n \"metageneration\": \"1\",\n \"contentType\": \"application/octet-stream\",\n \"storageClass\": \"STANDARD\",\n \"size\": \"37\",\n \"md5Hash\": \"fnzudKkVoyLvbHXDqwNNTw==\",\n \"crc32c\": \"s67YvA==\",\n \"etag\": \"CIS+ge3NxZIDEAE=\",\n \"temporaryHold\": false,\n \"retentionExpirationTime\": \"2026-02-07T19:33:37.019Z\",\n \"retention\": {\n \"retainUntilTime\": \"2026-02-07T19:33:37.019Z\",\n \"mode\": \"Unlocked\"\n },\n \"timeCreated\": \"2026-02-06T19:33:37.611Z\",\n \"updated\": \"2026-02-06T19:33:37.611Z\",\n \"timeStorageClassUpdated\": \"2026-02-06T19:33:37.611Z\",\n \"timeFinalized\": \"2026-02-06T19:33:37.611Z\"\n}\n", + "headers" : { + "Alt-Svc" : "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "Server" : "UploadServer", + "Cache-Control" : "private, max-age=0, must-revalidate, no-transform", + "ETag" : "CIS+ge3NxZIDEAE=", + "X-GUploader-UploadID" : "AJRbA5VF9x3VnyQ4WLD_epeNQAN5UMA-Ew8sAP21OiTd3k2tF7EyU8JK-i3O0RgfHAU5xYpYuhQx2aA", + "Vary" : [ "Origin", "X-Origin" ], + "Expires" : "Fri, 06 Feb 2026 19:33:38 GMT", + "Date" : "Fri, 06 Feb 2026 19:33:38 GMT", + "Content-Type" : "application/json; charset=UTF-8" + } + }, + "uuid" : "37f83a89-470f-412e-aab7-9913a877cb96", + "persistent" : true, + "scenarioName" : "scenario-1-storage-v1-b-substrate-sdk-gcp-poc1-test-bucket-versioned-o-conformance-tests-objectlock-retention-governance", + "requiredScenarioState" : "scenario-1-storage-v1-b-substrate-sdk-gcp-poc1-test-bucket-versioned-o-conformance-tests-objectlock-retention-governance-2", + "insertionIndex" : 967 +} \ No newline at end of file diff --git a/blob/blob-gcp/src/test/resources/mappings/get-cxg2ljnmwq.json b/blob/blob-gcp/src/test/resources/mappings/get-cxg2ljnmwq.json new file mode 100644 index 000000000..7c0814005 --- /dev/null +++ b/blob/blob-gcp/src/test/resources/mappings/get-cxg2ljnmwq.json @@ -0,0 +1,28 @@ +{ + "id" : "ce7d8148-fc3a-4e76-8c3c-72b460b9dceb", + "name" : "storage_v1_b_substrate-sdk-gcp-poc1-test-bucket-versioned_o_conformance-tests_objectlock_retention-compliance", + "request" : { + "url" : "/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned/o/conformance-tests%2Fobjectlock%2Fretention-compliance?projection=full", + "method" : "GET" + }, + "response" : { + "status" : 200, + "body" : "{\n \"kind\": \"storage#object\",\n \"id\": \"substrate-sdk-gcp-poc1-test-bucket-versioned/conformance-tests/objectlock/retention-compliance/1770406416023931\",\n \"selfLink\": \"https://www.googleapis.com/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned/o/conformance-tests%2Fobjectlock%2Fretention-compliance\",\n \"mediaLink\": \"https://storage.googleapis.com/download/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned/o/conformance-tests%2Fobjectlock%2Fretention-compliance?generation=1770406416023931&alt=media\",\n \"name\": \"conformance-tests/objectlock/retention-compliance\",\n \"bucket\": \"substrate-sdk-gcp-poc1-test-bucket-versioned\",\n \"generation\": \"1770406416023931\",\n \"metageneration\": \"1\",\n \"contentType\": \"application/octet-stream\",\n \"storageClass\": \"STANDARD\",\n \"size\": \"37\",\n \"md5Hash\": \"oNJGr8D4uvHn3WAsgO/ZZw==\",\n \"crc32c\": \"4z8aNg==\",\n \"etag\": \"CPuCpOzNxZIDEAE=\",\n \"temporaryHold\": false,\n \"retentionExpirationTime\": \"2026-02-07T19:33:35.525Z\",\n \"retention\": {\n \"retainUntilTime\": \"2026-02-07T19:33:35.525Z\",\n \"mode\": \"Locked\"\n },\n \"timeCreated\": \"2026-02-06T19:33:36.078Z\",\n \"updated\": \"2026-02-06T19:33:36.078Z\",\n \"timeStorageClassUpdated\": \"2026-02-06T19:33:36.078Z\",\n \"timeFinalized\": \"2026-02-06T19:33:36.078Z\"\n}\n", + "headers" : { + "Alt-Svc" : "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "Server" : "UploadServer", + "Cache-Control" : "private, max-age=0, must-revalidate, no-transform", + "ETag" : "CPuCpOzNxZIDEAE=", + "X-GUploader-UploadID" : "AJRbA5W6Gvhq3XgQKFPb8ILHh-M3IGkCXQ4X7ecjrBgYyMb3iT08-TkLP1Y_3QT3-TtD624355lgqdQ", + "Vary" : [ "Origin", "X-Origin" ], + "Expires" : "Fri, 06 Feb 2026 19:33:36 GMT", + "Date" : "Fri, 06 Feb 2026 19:33:36 GMT", + "Content-Type" : "application/json; charset=UTF-8" + } + }, + "uuid" : "ce7d8148-fc3a-4e76-8c3c-72b460b9dceb", + "persistent" : true, + "scenarioName" : "scenario-1-storage-v1-b-substrate-sdk-gcp-poc1-test-bucket-versioned-o-conformance-tests-objectlock-retention-compliance", + "requiredScenarioState" : "scenario-1-storage-v1-b-substrate-sdk-gcp-poc1-test-bucket-versioned-o-conformance-tests-objectlock-retention-compliance-2", + "insertionIndex" : 961 +} \ No newline at end of file diff --git a/blob/blob-gcp/src/test/resources/mappings/get-fjttdpp4cy.json b/blob/blob-gcp/src/test/resources/mappings/get-fjttdpp4cy.json new file mode 100644 index 000000000..1ee77c4f9 --- /dev/null +++ b/blob/blob-gcp/src/test/resources/mappings/get-fjttdpp4cy.json @@ -0,0 +1,26 @@ +{ + "id" : "bd288dbe-4abf-4024-9bde-8d42fb7033fc", + "name" : "storage_v1_b_substrate-sdk-gcp-poc1-test-bucket-versioned", + "request" : { + "url" : "/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned?projection=full", + "method" : "GET" + }, + "response" : { + "status" : 200, + "body" : "{\n \"kind\": \"storage#bucket\",\n \"selfLink\": \"https://www.googleapis.com/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned\",\n \"id\": \"substrate-sdk-gcp-poc1-test-bucket-versioned\",\n \"name\": \"substrate-sdk-gcp-poc1-test-bucket-versioned\",\n \"projectNumber\": \"599653580068\",\n \"generation\": \"1758831414065126441\",\n \"metageneration\": \"3\",\n \"location\": \"US\",\n \"storageClass\": \"STANDARD\",\n \"etag\": \"CAM=\",\n \"timeCreated\": \"2025-09-25T20:16:54.302Z\",\n \"updated\": \"2026-02-06T05:13:44.227Z\",\n \"versioning\": {\n \"enabled\": true\n },\n \"objectRetention\": {\n \"mode\": \"Enabled\"\n },\n \"softDeletePolicy\": {\n \"retentionDurationSeconds\": \"604800\",\n \"effectiveTime\": \"2025-09-25T20:16:54.302Z\"\n },\n \"iamConfiguration\": {\n \"bucketPolicyOnly\": {\n \"enabled\": true,\n \"lockedTime\": \"2025-12-24T20:16:54.302Z\"\n },\n \"uniformBucketLevelAccess\": {\n \"enabled\": true,\n \"lockedTime\": \"2025-12-24T20:16:54.302Z\"\n },\n \"publicAccessPrevention\": \"inherited\"\n },\n \"locationType\": \"multi-region\",\n \"rpo\": \"DEFAULT\"\n}\n", + "headers" : { + "Alt-Svc" : "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "Server" : "UploadServer", + "Cache-Control" : "private, max-age=0, must-revalidate, no-transform", + "ETag" : "CAM=", + "X-GUploader-UploadID" : "AJRbA5X_H-1GYvPlOS3BgVdMAXFbOgs8UOL2ZFsuaBTzGrCj_84tvGsKWzjuccmlu3xYH2s_eVb_gh0", + "Vary" : [ "Origin", "X-Origin" ], + "Expires" : "Fri, 06 Feb 2026 19:33:38 GMT", + "Date" : "Fri, 06 Feb 2026 19:33:38 GMT", + "Content-Type" : "application/json; charset=UTF-8" + } + }, + "uuid" : "bd288dbe-4abf-4024-9bde-8d42fb7033fc", + "persistent" : true, + "insertionIndex" : 966 +} \ No newline at end of file diff --git a/blob/blob-gcp/src/test/resources/mappings/get-iyvxgwu5eg.json b/blob/blob-gcp/src/test/resources/mappings/get-iyvxgwu5eg.json new file mode 100644 index 000000000..eda5c14ed --- /dev/null +++ b/blob/blob-gcp/src/test/resources/mappings/get-iyvxgwu5eg.json @@ -0,0 +1,26 @@ +{ + "id" : "7469e521-aab6-4c45-a365-e69ce6b7f68f", + "name" : "storage_v1_b_substrate-sdk-gcp-poc1-test-bucket-versioned_o_conformance-tests_objectlock_nonexistent", + "request" : { + "url" : "/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned/o/conformance-tests%2Fobjectlock%2Fnonexistent?projection=full", + "method" : "GET" + }, + "response" : { + "status" : 404, + "body" : "{\n \"error\": {\n \"code\": 404,\n \"message\": \"No such object: substrate-sdk-gcp-poc1-test-bucket-versioned/conformance-tests/objectlock/nonexistent\",\n \"errors\": [\n {\n \"message\": \"No such object: substrate-sdk-gcp-poc1-test-bucket-versioned/conformance-tests/objectlock/nonexistent\",\n \"domain\": \"global\",\n \"reason\": \"notFound\"\n }\n ]\n }\n}\n", + "headers" : { + "Alt-Svc" : "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "Server" : "UploadServer", + "Cache-Control" : "no-cache, no-store, max-age=0, must-revalidate", + "X-GUploader-UploadID" : "AJRbA5WKRiz_nCfZspiX2H3eNMxZmIArvIbXmn3mVgug34h1TfKM3XFoRN0qRvkCtDvsp8QheHqAsKQ", + "Vary" : [ "Origin", "X-Origin" ], + "Pragma" : "no-cache", + "Expires" : "Mon, 01 Jan 1990 00:00:00 GMT", + "Date" : "Fri, 06 Feb 2026 19:33:35 GMT", + "Content-Type" : "application/json; charset=UTF-8" + } + }, + "uuid" : "7469e521-aab6-4c45-a365-e69ce6b7f68f", + "persistent" : true, + "insertionIndex" : 957 +} \ No newline at end of file diff --git a/blob/blob-gcp/src/test/resources/mappings/get-lrhicy5wwb.json b/blob/blob-gcp/src/test/resources/mappings/get-lrhicy5wwb.json new file mode 100644 index 000000000..27bf7af41 --- /dev/null +++ b/blob/blob-gcp/src/test/resources/mappings/get-lrhicy5wwb.json @@ -0,0 +1,28 @@ +{ + "id" : "72e60f4d-b822-4c30-b347-766efdd0fe13", + "name" : "storage_v1_b_substrate-sdk-gcp-poc1-test-bucket-versioned_o_conformance-tests_objectlock_no-lock", + "request" : { + "url" : "/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned/o/conformance-tests%2Fobjectlock%2Fno-lock?projection=full", + "method" : "GET" + }, + "response" : { + "status" : 200, + "body" : "{\n \"kind\": \"storage#object\",\n \"id\": \"substrate-sdk-gcp-poc1-test-bucket-versioned/conformance-tests/objectlock/no-lock/1770406414100158\",\n \"selfLink\": \"https://www.googleapis.com/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned/o/conformance-tests%2Fobjectlock%2Fno-lock\",\n \"mediaLink\": \"https://storage.googleapis.com/download/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned/o/conformance-tests%2Fobjectlock%2Fno-lock?generation=1770406414100158&alt=media\",\n \"name\": \"conformance-tests/objectlock/no-lock\",\n \"bucket\": \"substrate-sdk-gcp-poc1-test-bucket-versioned\",\n \"generation\": \"1770406414100158\",\n \"metageneration\": \"1\",\n \"contentType\": \"application/octet-stream\",\n \"storageClass\": \"STANDARD\",\n \"size\": \"24\",\n \"md5Hash\": \"/dLDmP1tAJxHTx+aAtOOxQ==\",\n \"crc32c\": \"sPg8aA==\",\n \"etag\": \"CL7NruvNxZIDEAE=\",\n \"timeCreated\": \"2026-02-06T19:33:34.157Z\",\n \"updated\": \"2026-02-06T19:33:34.157Z\",\n \"timeStorageClassUpdated\": \"2026-02-06T19:33:34.157Z\",\n \"timeFinalized\": \"2026-02-06T19:33:34.157Z\"\n}\n", + "headers" : { + "Alt-Svc" : "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "Server" : "UploadServer", + "Cache-Control" : "private, max-age=0, must-revalidate, no-transform", + "ETag" : "CL7NruvNxZIDEAE=", + "X-GUploader-UploadID" : "AJRbA5UpHu-oO99KdoKMQGJ3n9eY4tjQUxaQ9eU75yo3kZtY4flBhX14FFAgyElHmg2On0dVL7I7sHE", + "Vary" : [ "Origin", "X-Origin" ], + "Expires" : "Fri, 06 Feb 2026 19:33:34 GMT", + "Date" : "Fri, 06 Feb 2026 19:33:34 GMT", + "Content-Type" : "application/json; charset=UTF-8" + } + }, + "uuid" : "72e60f4d-b822-4c30-b347-766efdd0fe13", + "persistent" : true, + "scenarioName" : "scenario-1-storage-v1-b-substrate-sdk-gcp-poc1-test-bucket-versioned-o-conformance-tests-objectlock-no-lock", + "requiredScenarioState" : "scenario-1-storage-v1-b-substrate-sdk-gcp-poc1-test-bucket-versioned-o-conformance-tests-objectlock-no-lock-2", + "insertionIndex" : 953 +} \ No newline at end of file diff --git a/blob/blob-gcp/src/test/resources/mappings/get-qhxkse0yvc.json b/blob/blob-gcp/src/test/resources/mappings/get-qhxkse0yvc.json new file mode 100644 index 000000000..5cc8ae8c4 --- /dev/null +++ b/blob/blob-gcp/src/test/resources/mappings/get-qhxkse0yvc.json @@ -0,0 +1,26 @@ +{ + "id" : "2f32abc0-b776-4d01-9bae-92f8ab4d882f", + "name" : "storage_v1_b_substrate-sdk-gcp-poc1-test-bucket-versioned", + "request" : { + "url" : "/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned?projection=full", + "method" : "GET" + }, + "response" : { + "status" : 200, + "body" : "{\n \"kind\": \"storage#bucket\",\n \"selfLink\": \"https://www.googleapis.com/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned\",\n \"id\": \"substrate-sdk-gcp-poc1-test-bucket-versioned\",\n \"name\": \"substrate-sdk-gcp-poc1-test-bucket-versioned\",\n \"projectNumber\": \"599653580068\",\n \"generation\": \"1758831414065126441\",\n \"metageneration\": \"3\",\n \"location\": \"US\",\n \"storageClass\": \"STANDARD\",\n \"etag\": \"CAM=\",\n \"timeCreated\": \"2025-09-25T20:16:54.302Z\",\n \"updated\": \"2026-02-06T05:13:44.227Z\",\n \"versioning\": {\n \"enabled\": true\n },\n \"objectRetention\": {\n \"mode\": \"Enabled\"\n },\n \"softDeletePolicy\": {\n \"retentionDurationSeconds\": \"604800\",\n \"effectiveTime\": \"2025-09-25T20:16:54.302Z\"\n },\n \"iamConfiguration\": {\n \"bucketPolicyOnly\": {\n \"enabled\": true,\n \"lockedTime\": \"2025-12-24T20:16:54.302Z\"\n },\n \"uniformBucketLevelAccess\": {\n \"enabled\": true,\n \"lockedTime\": \"2025-12-24T20:16:54.302Z\"\n },\n \"publicAccessPrevention\": \"inherited\"\n },\n \"locationType\": \"multi-region\",\n \"rpo\": \"DEFAULT\"\n}\n", + "headers" : { + "Alt-Svc" : "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "Server" : "UploadServer", + "Cache-Control" : "private, max-age=0, must-revalidate, no-transform", + "ETag" : "CAM=", + "X-GUploader-UploadID" : "AJRbA5XNjIAl6Gx7so-v5O6SrkywHkbHZDL621Fn0Sie8egiYxtxUoOu7zxIqe7_sfD2zj-WCouOaVg", + "Vary" : [ "Origin", "X-Origin" ], + "Expires" : "Fri, 06 Feb 2026 19:33:34 GMT", + "Date" : "Fri, 06 Feb 2026 19:33:34 GMT", + "Content-Type" : "application/json; charset=UTF-8" + } + }, + "uuid" : "2f32abc0-b776-4d01-9bae-92f8ab4d882f", + "persistent" : true, + "insertionIndex" : 952 +} \ No newline at end of file diff --git a/blob/blob-gcp/src/test/resources/mappings/get-swpt2dpzmm.json b/blob/blob-gcp/src/test/resources/mappings/get-swpt2dpzmm.json new file mode 100644 index 000000000..e316f21ad --- /dev/null +++ b/blob/blob-gcp/src/test/resources/mappings/get-swpt2dpzmm.json @@ -0,0 +1,26 @@ +{ + "id" : "1aee5d74-db21-4556-9d6e-078702accafc", + "name" : "storage_v1_b_substrate-sdk-gcp-poc1-test-bucket-versioned", + "request" : { + "url" : "/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned?projection=full", + "method" : "GET" + }, + "response" : { + "status" : 200, + "body" : "{\n \"kind\": \"storage#bucket\",\n \"selfLink\": \"https://www.googleapis.com/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned\",\n \"id\": \"substrate-sdk-gcp-poc1-test-bucket-versioned\",\n \"name\": \"substrate-sdk-gcp-poc1-test-bucket-versioned\",\n \"projectNumber\": \"599653580068\",\n \"generation\": \"1758831414065126441\",\n \"metageneration\": \"3\",\n \"location\": \"US\",\n \"storageClass\": \"STANDARD\",\n \"etag\": \"CAM=\",\n \"timeCreated\": \"2025-09-25T20:16:54.302Z\",\n \"updated\": \"2026-02-06T05:13:44.227Z\",\n \"versioning\": {\n \"enabled\": true\n },\n \"objectRetention\": {\n \"mode\": \"Enabled\"\n },\n \"softDeletePolicy\": {\n \"retentionDurationSeconds\": \"604800\",\n \"effectiveTime\": \"2025-09-25T20:16:54.302Z\"\n },\n \"iamConfiguration\": {\n \"bucketPolicyOnly\": {\n \"enabled\": true,\n \"lockedTime\": \"2025-12-24T20:16:54.302Z\"\n },\n \"uniformBucketLevelAccess\": {\n \"enabled\": true,\n \"lockedTime\": \"2025-12-24T20:16:54.302Z\"\n },\n \"publicAccessPrevention\": \"inherited\"\n },\n \"locationType\": \"multi-region\",\n \"rpo\": \"DEFAULT\"\n}\n", + "headers" : { + "Alt-Svc" : "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "Server" : "UploadServer", + "Cache-Control" : "private, max-age=0, must-revalidate, no-transform", + "ETag" : "CAM=", + "X-GUploader-UploadID" : "AJRbA5X6haVwoabWBqjlcoggaquVe9Yqz_3GMoC9gUEyBLEoC3nbBY_QM7r3rITejVy7sT9anNhTFwA", + "Vary" : [ "Origin", "X-Origin" ], + "Expires" : "Fri, 06 Feb 2026 19:33:36 GMT", + "Date" : "Fri, 06 Feb 2026 19:33:36 GMT", + "Content-Type" : "application/json; charset=UTF-8" + } + }, + "uuid" : "1aee5d74-db21-4556-9d6e-078702accafc", + "persistent" : true, + "insertionIndex" : 960 +} \ No newline at end of file diff --git a/blob/blob-gcp/src/test/resources/mappings/get-xe5wbrnidv.json b/blob/blob-gcp/src/test/resources/mappings/get-xe5wbrnidv.json new file mode 100644 index 000000000..3cf695840 --- /dev/null +++ b/blob/blob-gcp/src/test/resources/mappings/get-xe5wbrnidv.json @@ -0,0 +1,29 @@ +{ + "id" : "18d9f0ea-e6d6-4f4c-a47a-933ed0f5052b", + "name" : "storage_v1_b_substrate-sdk-gcp-poc1-test-bucket-versioned_o_conformance-tests_objectlock_retention-compliance", + "request" : { + "url" : "/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned/o/conformance-tests%2Fobjectlock%2Fretention-compliance?projection=full", + "method" : "GET" + }, + "response" : { + "status" : 200, + "body" : "{\n \"kind\": \"storage#object\",\n \"id\": \"substrate-sdk-gcp-poc1-test-bucket-versioned/conformance-tests/objectlock/retention-compliance/1770406416023931\",\n \"selfLink\": \"https://www.googleapis.com/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned/o/conformance-tests%2Fobjectlock%2Fretention-compliance\",\n \"mediaLink\": \"https://storage.googleapis.com/download/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned/o/conformance-tests%2Fobjectlock%2Fretention-compliance?generation=1770406416023931&alt=media\",\n \"name\": \"conformance-tests/objectlock/retention-compliance\",\n \"bucket\": \"substrate-sdk-gcp-poc1-test-bucket-versioned\",\n \"generation\": \"1770406416023931\",\n \"metageneration\": \"1\",\n \"contentType\": \"application/octet-stream\",\n \"storageClass\": \"STANDARD\",\n \"size\": \"37\",\n \"md5Hash\": \"oNJGr8D4uvHn3WAsgO/ZZw==\",\n \"crc32c\": \"4z8aNg==\",\n \"etag\": \"CPuCpOzNxZIDEAE=\",\n \"temporaryHold\": false,\n \"retentionExpirationTime\": \"2026-02-07T19:33:35.525Z\",\n \"retention\": {\n \"retainUntilTime\": \"2026-02-07T19:33:35.525Z\",\n \"mode\": \"Locked\"\n },\n \"timeCreated\": \"2026-02-06T19:33:36.078Z\",\n \"updated\": \"2026-02-06T19:33:36.078Z\",\n \"timeStorageClassUpdated\": \"2026-02-06T19:33:36.078Z\",\n \"timeFinalized\": \"2026-02-06T19:33:36.078Z\"\n}\n", + "headers" : { + "Alt-Svc" : "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "Server" : "UploadServer", + "Cache-Control" : "private, max-age=0, must-revalidate, no-transform", + "ETag" : "CPuCpOzNxZIDEAE=", + "X-GUploader-UploadID" : "AJRbA5WBF8tgBlmVHOlQyakpvj9fBg2y6p7UpR_ch8EscSOIyqX0DLjvn0E25pi6bqED-1EkAqJKEGI", + "Vary" : [ "Origin", "X-Origin" ], + "Expires" : "Fri, 06 Feb 2026 19:33:36 GMT", + "Date" : "Fri, 06 Feb 2026 19:33:36 GMT", + "Content-Type" : "application/json; charset=UTF-8" + } + }, + "uuid" : "18d9f0ea-e6d6-4f4c-a47a-933ed0f5052b", + "persistent" : true, + "scenarioName" : "scenario-1-storage-v1-b-substrate-sdk-gcp-poc1-test-bucket-versioned-o-conformance-tests-objectlock-retention-compliance", + "requiredScenarioState" : "Started", + "newScenarioState" : "scenario-1-storage-v1-b-substrate-sdk-gcp-poc1-test-bucket-versioned-o-conformance-tests-objectlock-retention-compliance-2", + "insertionIndex" : 962 +} \ No newline at end of file diff --git a/blob/blob-gcp/src/test/resources/mappings/get-z4q5tmjzzk.json b/blob/blob-gcp/src/test/resources/mappings/get-z4q5tmjzzk.json new file mode 100644 index 000000000..41f662a66 --- /dev/null +++ b/blob/blob-gcp/src/test/resources/mappings/get-z4q5tmjzzk.json @@ -0,0 +1,29 @@ +{ + "id" : "50c6e5b9-44b5-46ed-be19-b5e845166ed3", + "name" : "storage_v1_b_substrate-sdk-gcp-poc1-test-bucket-versioned_o_conformance-tests_objectlock_retention-governance", + "request" : { + "url" : "/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned/o/conformance-tests%2Fobjectlock%2Fretention-governance?projection=full", + "method" : "GET" + }, + "response" : { + "status" : 200, + "body" : "{\n \"kind\": \"storage#object\",\n \"id\": \"substrate-sdk-gcp-poc1-test-bucket-versioned/conformance-tests/objectlock/retention-governance/1770406417555204\",\n \"selfLink\": \"https://www.googleapis.com/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned/o/conformance-tests%2Fobjectlock%2Fretention-governance\",\n \"mediaLink\": \"https://storage.googleapis.com/download/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned/o/conformance-tests%2Fobjectlock%2Fretention-governance?generation=1770406417555204&alt=media\",\n \"name\": \"conformance-tests/objectlock/retention-governance\",\n \"bucket\": \"substrate-sdk-gcp-poc1-test-bucket-versioned\",\n \"generation\": \"1770406417555204\",\n \"metageneration\": \"1\",\n \"contentType\": \"application/octet-stream\",\n \"storageClass\": \"STANDARD\",\n \"size\": \"37\",\n \"md5Hash\": \"fnzudKkVoyLvbHXDqwNNTw==\",\n \"crc32c\": \"s67YvA==\",\n \"etag\": \"CIS+ge3NxZIDEAE=\",\n \"temporaryHold\": false,\n \"retentionExpirationTime\": \"2026-02-07T19:33:37.019Z\",\n \"retention\": {\n \"retainUntilTime\": \"2026-02-07T19:33:37.019Z\",\n \"mode\": \"Unlocked\"\n },\n \"timeCreated\": \"2026-02-06T19:33:37.611Z\",\n \"updated\": \"2026-02-06T19:33:37.611Z\",\n \"timeStorageClassUpdated\": \"2026-02-06T19:33:37.611Z\",\n \"timeFinalized\": \"2026-02-06T19:33:37.611Z\"\n}\n", + "headers" : { + "Alt-Svc" : "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "Server" : "UploadServer", + "Cache-Control" : "private, max-age=0, must-revalidate, no-transform", + "ETag" : "CIS+ge3NxZIDEAE=", + "X-GUploader-UploadID" : "AJRbA5XeOaLjkkYPDZx9yG7lJtO7tIj267LUkWkhg_zTIY-TGdhiP6myatUlqmgZ1Qs7WM42E-0yeUg", + "Vary" : [ "Origin", "X-Origin" ], + "Expires" : "Fri, 06 Feb 2026 19:33:37 GMT", + "Date" : "Fri, 06 Feb 2026 19:33:37 GMT", + "Content-Type" : "application/json; charset=UTF-8" + } + }, + "uuid" : "50c6e5b9-44b5-46ed-be19-b5e845166ed3", + "persistent" : true, + "scenarioName" : "scenario-1-storage-v1-b-substrate-sdk-gcp-poc1-test-bucket-versioned-o-conformance-tests-objectlock-retention-governance", + "requiredScenarioState" : "Started", + "newScenarioState" : "scenario-1-storage-v1-b-substrate-sdk-gcp-poc1-test-bucket-versioned-o-conformance-tests-objectlock-retention-governance-2", + "insertionIndex" : 968 +} \ No newline at end of file diff --git a/blob/blob-gcp/src/test/resources/mappings/post-cnnqenruqx.json b/blob/blob-gcp/src/test/resources/mappings/post-cnnqenruqx.json new file mode 100644 index 000000000..e3b415bcd --- /dev/null +++ b/blob/blob-gcp/src/test/resources/mappings/post-cnnqenruqx.json @@ -0,0 +1 @@ +{"id":"80082217-34b4-4c0a-b2c2-7cabf8fef4a7","name":"upload_storage_v1_b_substrate-sdk-gcp-poc1-test-bucket-versioned_o","request":{"url":"/upload/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned/o?name=conformance-tests/objectlock/retention-compliance&uploadType=resumable","method":"POST","bodyPatterns":[{"matchesJsonPath":"$.bucket"},{"matchesJsonPath":"$.name"},{"matchesJsonPath":"$.retention"},{"matchesJsonPath":"$.retention.retainUntilTime"},{"matchesJsonPath":"$.temporaryHold"}]},"response":{"status":200,"headers":{"Alt-Svc":"h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000","Server":"UploadServer","Cache-Control":"no-cache, no-store, max-age=0, must-revalidate","X-GUploader-UploadID":"AJRbA5VF8v3jseLKUzkIcJA12AMsr26L-muFNHRsvSsf41FxRkk4YJZTh2jYi2XrIxgNA9a8BSusA4_iyGcDTIpxwuSEV6xbWdb1AB0mTlSPj4U","Vary":["Origin","X-Origin"],"Pragma":"no-cache","Expires":"Mon, 01 Jan 1990 00:00:00 GMT","Date":"Fri, 06 Feb 2026 19:33:35 GMT","Location":"https://storage.googleapis.com/upload/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned/o?name=conformance-tests/objectlock/retention-compliance&uploadType=resumable&upload_id=AJRbA5VF8v3jseLKUzkIcJA12AMsr26L-muFNHRsvSsf41FxRkk4YJZTh2jYi2XrIxgNA9a8BSusA4_iyGcDTIpxwuSEV6xbWdb1AB0mTlSPj4U","Content-Type":"text/plain; charset=utf-8"}},"uuid":"80082217-34b4-4c0a-b2c2-7cabf8fef4a7","persistent":true,"insertionIndex":963} diff --git a/blob/blob-gcp/src/test/resources/mappings/post-cot0l9cfvf.json b/blob/blob-gcp/src/test/resources/mappings/post-cot0l9cfvf.json new file mode 100644 index 000000000..2f75a1576 --- /dev/null +++ b/blob/blob-gcp/src/test/resources/mappings/post-cot0l9cfvf.json @@ -0,0 +1,31 @@ +{ + "id" : "bfc84ff4-1426-46ac-ba48-ea4fb4ba356c", + "name" : "upload_storage_v1_b_substrate-sdk-gcp-poc1-test-bucket-versioned_o", + "request" : { + "url" : "/upload/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned/o?name=conformance-tests/objectlock/no-lock&uploadType=resumable", + "method" : "POST", + "bodyPatterns" : [ { + "equalToJson" : "{\"bucket\":\"substrate-sdk-gcp-poc1-test-bucket-versioned\",\"metadata\":{},\"name\":\"conformance-tests/objectlock/no-lock\"}", + "ignoreArrayOrder" : true, + "ignoreExtraElements" : false + } ] + }, + "response" : { + "status" : 200, + "headers" : { + "Alt-Svc" : "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "Server" : "UploadServer", + "Cache-Control" : "no-cache, no-store, max-age=0, must-revalidate", + "X-GUploader-UploadID" : "AJRbA5V4edHZ8BAunfxpBMnU7XAuhozzXoywxWxCjEmWKaNnn94F6RLc5IN_vf-4Z1s9RsU_8J9v7DLHDQ5BIoIwWhhMjtI63Gmv5xnKfmaQ2A", + "Vary" : [ "Origin", "X-Origin" ], + "Pragma" : "no-cache", + "Expires" : "Mon, 01 Jan 1990 00:00:00 GMT", + "Date" : "Fri, 06 Feb 2026 19:33:33 GMT", + "Location" : "https://storage.googleapis.com/upload/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned/o?name=conformance-tests/objectlock/no-lock&uploadType=resumable&upload_id=AJRbA5V4edHZ8BAunfxpBMnU7XAuhozzXoywxWxCjEmWKaNnn94F6RLc5IN_vf-4Z1s9RsU_8J9v7DLHDQ5BIoIwWhhMjtI63Gmv5xnKfmaQ2A", + "Content-Type" : "text/plain; charset=utf-8" + } + }, + "uuid" : "bfc84ff4-1426-46ac-ba48-ea4fb4ba356c", + "persistent" : true, + "insertionIndex" : 955 +} \ No newline at end of file diff --git a/blob/blob-gcp/src/test/resources/mappings/post-txqfacbfx6.json b/blob/blob-gcp/src/test/resources/mappings/post-txqfacbfx6.json new file mode 100644 index 000000000..a02f342cd --- /dev/null +++ b/blob/blob-gcp/src/test/resources/mappings/post-txqfacbfx6.json @@ -0,0 +1 @@ +{"id":"ee8f0876-bee7-472d-9f51-f52d90726374","name":"upload_storage_v1_b_substrate-sdk-gcp-poc1-test-bucket-versioned_o","request":{"url":"/upload/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned/o?name=conformance-tests/objectlock/retention-governance&uploadType=resumable","method":"POST","bodyPatterns":[{"matchesJsonPath":"$.bucket"},{"matchesJsonPath":"$.name"},{"matchesJsonPath":"$.retention"},{"matchesJsonPath":"$.retention.retainUntilTime"},{"matchesJsonPath":"$.temporaryHold"}]},"response":{"status":200,"headers":{"Alt-Svc":"h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000","Server":"UploadServer","Cache-Control":"no-cache, no-store, max-age=0, must-revalidate","X-GUploader-UploadID":"AJRbA5Wr0vjpL93q8X9pgaVbnglGrIcSxf1u2H4e7FQYqdIIHlvsLoVS4cBHQo0A5tW9l2p7kLaBP0shjW4-PRvOc5ZMyUk73rfDC5qK_vUsHQ","Vary":["Origin","X-Origin"],"Pragma":"no-cache","Expires":"Mon, 01 Jan 1990 00:00:00 GMT","Date":"Fri, 06 Feb 2026 19:33:37 GMT","Location":"https://storage.googleapis.com/upload/storage/v1/b/substrate-sdk-gcp-poc1-test-bucket-versioned/o?name=conformance-tests/objectlock/retention-governance&uploadType=resumable&upload_id=AJRbA5Wr0vjpL93q8X9pgaVbnglGrIcSxf1u2H4e7FQYqdIIHlvsLoVS4cBHQo0A5tW9l2p7kLaBP0shjW4-PRvOc5ZMyUk73rfDC5qK_vUsHQ","Content-Type":"text/plain; charset=utf-8"}},"uuid":"ee8f0876-bee7-472d-9f51-f52d90726374","persistent":true,"insertionIndex":969} diff --git a/multicloudj-common-gcp/src/test/java/com/salesforce/multicloudj/common/gcp/util/TestsUtilGcp.java b/multicloudj-common-gcp/src/test/java/com/salesforce/multicloudj/common/gcp/util/TestsUtilGcp.java index ea6e01833..10b30fc61 100644 --- a/multicloudj-common-gcp/src/test/java/com/salesforce/multicloudj/common/gcp/util/TestsUtilGcp.java +++ b/multicloudj-common-gcp/src/test/java/com/salesforce/multicloudj/common/gcp/util/TestsUtilGcp.java @@ -75,8 +75,10 @@ private static SSLContext createTrustAllSSLContext() { } /** - * Gets an HttpTransport configured with a proxy to the WireMock server. - * This allows HTTP/HTTPS traffic to be intercepted for testing. + * Gets an HttpTransport configured with a proxy to the WireMock server (HTTP port). + * Note: Using an HTTP proxy causes HTTPS requests to use CONNECT tunneling, so WireMock + * never sees the actual request body. Prefer {@link #getHttpTransportDirect(int)} for + * record/replay so requests hit WireMock's HTTPS port directly. * * @param port The base port for WireMock (proxy will use port+1) * @return A configured HttpTransport @@ -84,13 +86,8 @@ private static SSLContext createTrustAllSSLContext() { */ public static HttpTransport getHttpTransport(int port) { try { - // Get SSL socket factory that trusts all certificates SSLSocketFactory sslSocketFactory = createTrustAllSSLContext().getSocketFactory(); - - // Define proxy to WireMock Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(WIREMOCK_HOST, port + 1)); - - // Set up HTTP transport with proxy and SSL settings return new NetHttpTransport.Builder() .setProxy(proxy) .doNotValidateCertificate() @@ -101,6 +98,26 @@ public static HttpTransport getHttpTransport(int port) { } } + /** + * Gets an HttpTransport that connects directly to WireMock's HTTPS port (no proxy). + * Use with StorageOptions.setHost("https://localhost:" + port) so the client talks + * to WireMock directly. WireMock can then record/replay the full request in both modes. + * + * @param port WireMock HTTPS port (same as harness.getPort()) + * @return A configured HttpTransport with trust-all certs, no proxy + */ + public static HttpTransport getHttpTransportDirect(int port) { + try { + SSLSocketFactory sslSocketFactory = createTrustAllSSLContext().getSocketFactory(); + return new NetHttpTransport.Builder() + .doNotValidateCertificate() + .setSslSocketFactory(sslSocketFactory) + .build(); + } catch (GeneralSecurityException e) { + throw new SecurityConfigurationException("Failed to configure transport", e); + } + } + /** * Gets a transport channel provider configured with a proxy to the WireMock server. * This allows HTTP/HTTPS traffic to be intercepted for testing.