### Action Lists for Sequential Operations in DocStore Source: https://github.com/salesforce/multicloudj/blob/main/documentation/guides/docstore-guide.md Manages a list of actions (get, put, delete, etc.) to be executed sequentially. Actions can be chained using a fluent API. Requires an initialized docstore client to get the ActionList object. ```java ActionList actions = client.getActions(); actions.put(doc1).get(doc2).delete(doc3); actions.run(); ``` -------------------------------- ### StsClient Creation Source: https://github.com/salesforce/multicloudj/blob/main/documentation/guides/sts-guide.md Demonstrates how to create an instance of the StsClient for a specific cloud provider, with options for region and custom endpoints. ```APIDOC ## StsClient Creation ### Description Instantiates an `StsClient` for a given cloud provider (e.g., "aws"), specifying the region and optionally a custom endpoint. ### Method `StsClient.builder(String provider).withRegion(String region).withEndpoint(URI endpoint).build()` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```java // Basic client creation StsClient stsClient = StsClient.builder("aws") .withRegion("us-west-2") .build(); // Client creation with custom endpoint URI endpoint = URI.create("https://sts.custom-endpoint.com"); StsClient stsClientWithCustomEndpoint = StsClient.builder("aws") .withRegion("us-west-2") .withEndpoint(endpoint) .build(); ``` ### Response #### Success Response (200) An initialized `StsClient` object. #### Response Example (No specific response body for client creation, returns an object) ``` -------------------------------- ### Example Upload Method Logic (Java) Source: https://github.com/salesforce/multicloudj/blob/main/documentation/design/layers.md Illustrates the execution flow of an upload method within the driver layer. It shows common validation and preparation steps before invoking the provider-specific upload logic. ```java public UploadResponse upload(UploadRequest uploadRequest) { validation(); // this is common validation for all substrates prepContent(); // this is provider specific prep content doUpload(); // this is provider specific upload of the content } ``` -------------------------------- ### Handle SubstrateSdkException Source: https://github.com/salesforce/multicloudj/blob/main/documentation/guides/sts-guide.md Provides an example of how to catch and handle `SubstrateSdkException` and its subclasses, which are thrown by the StsClient for various errors like access denied or timeouts. ```java try { CallerIdentity identity = stsClient.getCallerIdentity(); } catch (SubstrateSdkException e) { // Handle known errors: AccessDenied, Timeout, etc. e.printStackTrace(); } ``` -------------------------------- ### Manage Blob Metadata and Tags in Java Source: https://context7.com/salesforce/multicloudj/llms.txt Retrieve and manage object metadata (ETag, size, last modified, content type, custom metadata) and tags for blobs in cloud storage. This example uses the BucketClient and demonstrates setting and getting tags. Ensure the necessary client configurations are in place. ```java import com.salesforce.multicloudj.blob.client.BucketClient; import com.salesforce.multicloudj.blob.driver.BlobMetadata; import java.util.Map; import java.util.HashMap; // Create client BucketClient client = BucketClient.builder("aws") .withBucket("my-bucket") .withRegion("us-west-2") .build(); String blobKey = "documents/report.pdf"; String versionId = "version-123"; // Get metadata BlobMetadata metadata = client.getMetadata(blobKey, versionId); System.out.println("ETag: " + metadata.getETag()); System.out.println("Size: " + metadata.getObjectSize() + " bytes"); System.out.println("Last modified: " + metadata.getLastModified()); System.out.println("Content type: " + metadata.getContentType()); System.out.println("Custom metadata: " + metadata.getMetadata()); // Get tags Map tags = client.getTags(blobKey); if (tags != null && !tags.isEmpty()) { System.out.println("Tags:"); tags.forEach((key, value) -> System.out.println(" " + key + ": " + value)); } else { System.out.println("No tags found"); } // Set tags (replaces all existing tags) Map newTags = new HashMap<>(); newTags.put("environment", "production"); newTags.put("department", "finance"); newTags.put("classification", "confidential"); client.setTags(blobKey, newTags); System.out.println("Tags updated successfully"); ``` -------------------------------- ### Create StsClient Instance Source: https://github.com/salesforce/multicloudj/blob/main/documentation/guides/sts-guide.md Demonstrates how to build an StsClient instance for a specific cloud provider (e.g., 'aws') and region. It also shows how to optionally configure a custom endpoint for the STS service. ```java StsClient stsClient = StsClient.builder("aws") .withRegion("us-west-2") .build(); ``` ```java URI endpoint = URI.create("https://sts.custom-endpoint.com"); StsClient stsClient = StsClient.builder("aws") .withRegion("us-west-2") .withEndpoint(endpoint) .build(); ``` -------------------------------- ### Handle SubstrateSdkException with Bucket Client (Java) Source: https://github.com/salesforce/multicloudj/blob/main/documentation/guides/blobstore-guide.md Provides an example of how to catch and handle `SubstrateSdkException`, the generic exception class for operations performed by the BucketClient. This allows for robust error management for various issues like access denial or IO failures. ```java try { bucketClient.upload(request, new File("file.txt")); } catch (SubstrateSdkException e) { // Handle access denied, IO failure, etc. e.printStackTrace(); } ``` -------------------------------- ### Error Handling Source: https://github.com/salesforce/multicloudj/blob/main/documentation/guides/sts-guide.md Explains how exceptions are handled by the StsClient, translating underlying driver errors into `SubstrateSdkException` subclasses. ```APIDOC ## Error Handling ### Description The `StsClient` translates all underlying cloud provider errors into subclasses of `SubstrateSdkException`. This provides a consistent error handling mechanism across different cloud providers. ### Method N/A (This describes exception handling during method calls) ### Endpoint N/A ### Parameters None ### Request Example ```java try { // Assume a method call that might throw an exception CallerIdentity identity = stsClient.getCallerIdentity(); } catch (SubstrateSdkException e) { // Handle specific or general SubstrateSdkExceptions System.err.println("An SDK error occurred: " + e.getMessage()); e.printStackTrace(); // Example: checking for specific error types // if (e instanceof AccessDeniedException) { ... } } ``` ### Response #### Success Response (200) N/A (This section pertains to error scenarios) #### Response Example N/A ### Potential `SubstrateSdkException` Subclasses - `AccessDeniedException` - `TimeoutException` - `ProviderSpecificException` (for errors not mapped to specific types) ``` -------------------------------- ### Configure Blob Storage Authentication in Java Source: https://context7.com/salesforce/multicloudj/llms.txt Configure different authentication methods for cloud blob storage providers using the BucketClient. This example shows how to use default credentials, explicit session credentials, custom endpoints for local testing, and proxy endpoints. ```java import com.salesforce.multicloudj.blob.client.BucketClient; import com.salesforce.multicloudj.sts.model.CredentialsOverrider; import com.salesforce.multicloudj.sts.model.CredentialsType; import com.salesforce.multicloudj.sts.model.StsCredentials; import java.net.URI; // Option 1: Use default credentials (from environment, instance profile, etc.) BucketClient defaultClient = BucketClient.builder("aws") .withBucket("my-bucket") .withRegion("us-west-2") .build(); // Option 2: Use explicit session credentials String accessKeyId = "AKIAIOSFODNN7EXAMPLE"; String secretAccessKey = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"; String sessionToken = "FwoGZXIvYXdzEBQaD..."; // Optional StsCredentials credentials = new StsCredentials(accessKeyId, secretAccessKey, sessionToken); CredentialsOverrider sessionOverrider = new CredentialsOverrider.Builder(CredentialsType.SESSION) .withSessionCredentials(credentials) .build(); BucketClient sessionClient = BucketClient.builder("aws") .withBucket("my-bucket") .withRegion("us-west-2") .withCredentialsOverrider(sessionOverrider) .build(); // Option 3: Use custom endpoint (for local testing, MinIO, etc.) BucketClient customEndpointClient = BucketClient.builder("aws") .withBucket("test-bucket") .withRegion("us-west-2") .withEndpoint(URI.create("http://localhost:9000")) .build(); // Option 4: Use proxy endpoint (for testing or monitoring) BucketClient proxyClient = BucketClient.builder("aws") .withBucket("my-bucket") .withRegion("us-west-2") .withProxyEndpoint(URI.create("http://proxy.example.com:8080")) .build(); ``` -------------------------------- ### Example Blob Download Source: https://github.com/salesforce/multicloudj/blob/main/examples/src/main/java/com/salesforce/multicloudj/blob/README.md Demonstrates downloading a blob using the client. It involves creating a DownloadRequest with the object's key and an OutputStream to save the downloaded data. The client's download method is then invoked. ```java // Create a DownloadRequest object with the specified object key DownloadRequest downloadRequest = new DownloadRequest.Builder() .withKey("examples/image1-chameleon.jpg") .build(); // Create an OutputStream to save the downloaded content to a file OutputStream content = new FileOutputStream("/exampleFile.txt"); // Download the blob using the client, download request, and output stream using bucket client instance client.download(downloadRequest, content); ``` -------------------------------- ### Represent Document using HashMap Source: https://github.com/salesforce/multicloudj/blob/main/documentation/guides/docstore-guide.md Illustrates creating a Document object by utilizing a HashMap. Key-value pairs representing the document's fields and their values are added to the HashMap, which is then used to instantiate the Document object. ```java Map map = new HashMap<>(); map.put("pName", "Alice"); map.put("i", 42); map.put("f", 99.5f); map.put("b", true); map.put("s", "metadata"); Document doc = new Document(map); ``` -------------------------------- ### Configure Test Recording Mode with JVM Options Source: https://github.com/salesforce/multicloudj/blob/main/docs/guides/conformance-tests-guide.html This describes how to enable test recording mode using the Java system property `-Drecord`. It explains how to configure this property in IntelliJ IDEA for Bazel builds and provides an example of how to set it using JVM options in Bazel. ```text -Drecord --jvmopt="-Drecord" ``` -------------------------------- ### Create Document in DocStore Source: https://github.com/salesforce/multicloudj/blob/main/documentation/guides/docstore-guide.md Creates a new document in DocStore. Throws a ResourceAlreadyExists exception if the document with the same key already exists. Requires a initialized docstore client and a document object. ```java client.create(doc); ``` -------------------------------- ### Initialize Query in DocStore Source: https://github.com/salesforce/multicloudj/blob/main/documentation/guides/docstore-guide.md Initializes a query object for retrieving or manipulating multiple documents based on conditions. The query interface is chainable and supports filtering and sorting. Requires an initialized docstore client. ```java Query query = client.query(); // Apply filtering, sorting, etc. ``` -------------------------------- ### Create and Execute Action Lists in Java Source: https://github.com/salesforce/multicloudj/blob/main/docs/guides/docstore-guide.html Constructs a list of actions (put, get, delete) that can be executed sequentially or atomically. The fluent API allows chaining operations before a final 'run'. Supports atomic execution when 'enableAtomicWrites()' is called. ```java ActionList actions = client.getActions(); actions.put(doc1).get(doc2).delete(doc3); actions.run(); ``` ```java client.getActions() .create(new Document(new Player("Alice", 1, 3.99f, true, "CA"))) .create(new Document(new Player("Bob", 2, 3.99f, true, "PT"))) .create(new Document(new Player("Carol", 3, 3.99f, true, "PA"))) .enableAtomicWrites() .create(new Document(new Player("Dave", 4, 3.99f, true, "TX"))) .create(new Document(new Player("Eve", 5, 3.99f, true, "OR"))) .create(new Document(new Player("Frank", 6, 3.99f, true, "NJ"))) .run(); ``` -------------------------------- ### Upload Blob using Portable Layer in Java Source: https://github.com/salesforce/multicloudj/blob/main/documentation/design/layers.md Demonstrates uploading a blob to a bucket using the substrate-agnostic BucketClient from the Portable Layer. It shows how to configure credentials, specify the bucket and region, and perform the upload operation. This example assumes AWS as the substrate but is designed to be substrate-agnostic. ```java String substrate = "aws"; String region = "us-east-1"; // Setting up session credentials - // these are optional and ideally in prod, this is not required // since the k8s pods are set with default credentials and Substrate SDK // uses the default credentials in that case. StsCredentials credentials = new StsCredentials( "accessKeyId", "accessKeySecret", "sessionToken"); CredentialsOverrider credsOverrider = new CredentialsOverrider .Builder(CredentialsType.SESSION).withSessionCredentials(credentials).build(); // Initiate the substrate agnostic BucketClient BucketClient client = BucketClient.builder(substrate) .withBucket("chameleon-java") .withRegion(region) .withCredentialsOverrider(credsOverrider).build(); // Prepare the substrate agnostic UploadRequest UploadRequest uploadRequest = new UploadRequest.Builder() .withKey("bucket-path/chameleon.jpg"); // Upload the content UploadResponse response = client.upload(uploadRequest, "dummy-content"); ``` -------------------------------- ### Handle Substrate SDK Exceptions in Java Source: https://github.com/salesforce/multicloudj/blob/main/docs/guides/sts-guide.html Illustrates error handling for AWS STS operations using the Substrate SDK. All errors are translated into subclasses of `SubstrateSdkException`. The example shows a try-catch block to manage potential exceptions like `AccessDenied` or `Timeout`. ```java try { CallerIdentity identity = stsClient.getCallerIdentity(); } catch (SubstrateSdkException e) { // Handle known errors: AccessDenied, Timeout, etc. e.printStackTrace(); } ``` -------------------------------- ### Example Blob Copy Source: https://github.com/salesforce/multicloudj/blob/main/examples/src/main/java/com/salesforce/multicloudj/blob/README.md Demonstrates copying a blob using the client. It involves specifying the destination bucket, source key, and destination key, then calling the copy method. The ETag of the newly copied blob is returned. ```java //destination bucket key to be copied to String destBucket = "destination-bucket"; //object key of the src blob String srcKey = "src-key"; //object key of the destination blob String destKey = "dest-key"; //receive ETag of the copied Blob or null if an exception occurs using bucket client instance var eTag = bucketClient.copy(destBucket, srcKey, destKey); ``` -------------------------------- ### Client Creation Source: https://github.com/salesforce/multicloudj/blob/main/docs/guides/docstore-guide.html Demonstrates how to create an instance of the DocStoreClient using the static builder pattern. It shows how to configure collection options, specify the region, and build the client for a specific cloud provider. ```APIDOC ## Creating a Client To begin using `DocStoreClient`, use the static builder: ```java CollectionOptions collectionOptions = new CollectionOptions.CollectionOptionsBuilder() .withTableName("chameleon-test") .withPartitionKey("pName") .withSortKey("s") .withRevisionField("docRevision") .build(); DocStoreClient client = DocStoreClient.builder("aws") .withRegion("us-west-2") .withCollectionOptions(collectionOptions) .build(); ``` ``` -------------------------------- ### Batch Document Operations Source: https://github.com/salesforce/multicloudj/blob/main/documentation/guides/docstore-guide.md Efficiently perform operations on multiple documents at once using batch requests for 'Get' and 'Put' actions. ```APIDOC ## Batch Operations ### Batch Get ```java List docs = List.of( new Document().put("pName", "Alice").put("s", "metadata"), new Document().put("pName", "Bob").put("s", "stats") ); client.batchGet(docs); ``` ### Batch Put ```java List docs = List.of( new Document().put("pName", "Alice").put("f", 10.5f), new Document().put("pName", "Bob").put("f", 20.0f) ); client.batchPut(docs); ``` ``` -------------------------------- ### Create DocStoreClient Instance Source: https://github.com/salesforce/multicloudj/blob/main/docs/guides/docstore-guide.html Initializes a DocStoreClient for a specified cloud provider (e.g., 'aws') with region and collection options. Collection options define table name, partition key, sort key, and revision field. ```java CollectionOptions collectionOptions = new CollectionOptions.CollectionOptionsBuilder() .withTableName("chameleon-test") .withPartitionKey("pName") .withSortKey("s") .withRevisionField("docRevision") .build(); DocStoreClient client = DocStoreClient.builder("aws") .withRegion("us-west-2") .withCollectionOptions(collectionOptions) .build(); ``` -------------------------------- ### Get Access Token Source: https://github.com/salesforce/multicloudj/blob/main/documentation/guides/sts-guide.md Obtains an OAuth2-style access token from the security token service. Provider support may vary. ```APIDOC ## Get Access Token ### Description Requests an access token, typically in an OAuth2 format, from the security token service. This feature's availability and exact implementation can differ between cloud providers. ### Method `stsClient.getAccessToken(GetAccessTokenRequest request)` ### Endpoint N/A (This is a client method call) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **GetAccessTokenRequest** (object) - An object to configure the token request (may be empty for default settings). ### Request Example ```java GetAccessTokenRequest request = new GetAccessTokenRequest(); StsCredentials token = stsClient.getAccessToken(request); System.out.println("Access Token: " + token.getAccessToken()); ``` ### Response #### Success Response (200) - **StsCredentials** (object) - An object containing the requested security credentials. - **accessToken** (string) - The obtained access token. - (Other potential credential fields like expiration, etc.) #### Response Example ```json { "accessToken": "ey...example.token...", "expiration": "2023-10-27T10:00:00Z" } ``` ``` -------------------------------- ### Configure Alibaba Cloud Credentials in GoLand IDE Source: https://github.com/salesforce/multicloudj/blob/main/docs/guides/conformance-tests-guide.html This section details how to set up Alibaba Cloud credentials within the GoLand IDE for authenticating to services. It specifies the environment variables required for general Alibaba Cloud access and for the Docstore service, along with the necessary program argument for recording tests. ```bash acs-sso login --env ``` ```text ALICLOUD_ACCESS_KEY ALICLOUD_SECRET_KEY ALICLOUD_SECURITY_TOKEN TABLESTORE_ACCESS_KEY_ID TABLESTORE_ACCESS_KEY_SECRET TABLESTORE_SESSION_TOKEN -Drecord ``` -------------------------------- ### BucketClient Creation Source: https://github.com/salesforce/multicloudj/blob/main/docs/guides/blobstore-guide.html Demonstrates how to create a BucketClient instance for AWS, with options for region, bucket name, custom endpoints, and proxy configurations. ```APIDOC ## Creating a Client ### Description Instantiate a `BucketClient` for a specific cloud provider (e.g., 'aws'). Supports configuration of region, bucket name, and advanced options like custom endpoints and proxy servers. ### Method Instantiation using `BucketClient.builder() ### Endpoint N/A (Client instantiation) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```java // Basic AWS client BucketClient bucketClient = BucketClient.builder("aws") .withRegion("us-west-2") .withBucket("my-bucket") .build(); // Client with advanced options URI endpoint = URI.create("https://custom-endpoint.com"); URI proxy = URI.create("https://proxy.example.com"); bucketClient = BucketClient.builder("aws") .withRegion("us-west-2") .withBucket("my-bucket") .withEndpoint(endpoint) .withProxyEndpoint(proxy) .build(); ``` ### Response #### Success Response (200) N/A (Client instantiation returns a `BucketClient` object) #### Response Example N/A ``` -------------------------------- ### Get Caller Identity Source: https://github.com/salesforce/multicloudj/blob/main/documentation/guides/sts-guide.md Retrieves the identity information (ARN) of the current caller associated with the STS client's credentials. ```APIDOC ## Get Caller Identity ### Description Retrieves the identity information of the current caller using the configured `StsClient`. ### Method `stsClient.getCallerIdentity()` ### Endpoint N/A (This is a client method call) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```java CallerIdentity identity = stsClient.getCallerIdentity(); System.out.println("Caller ARN: " + identity.getArn()); ``` ### Response #### Success Response (200) - **CallerIdentity** (object) - An object containing the caller's identity information. - **arn** (string) - The Amazon Resource Name (ARN) of the caller. #### Response Example ```json { "arn": "arn:aws:sts::123456789012:assumed-role/example-role/example-session" } ``` ``` -------------------------------- ### Document Store - Query with Pagination (Java) Source: https://context7.com/salesforce/multicloudj/llms.txt Demonstrates how to query documents from the Document Store with support for pagination using tokens and offsets. It shows retrieving the first page, obtaining a token for subsequent pages, and scanning all documents. Requires the DocStoreClient and related driver classes. ```java import com.salesforce.multicloudj.docstore.client.DocStoreClient; import com.salesforce.multicloudj.docstore.driver.DocumentIterator; import com.salesforce.multicloudj.docstore.driver.FilterOperation; import com.salesforce.multicloudj.docstore.driver.PaginationToken; // Create client DocStoreClient client = DocStoreClient.builder("aws") .withRegion("us-west-2") .withCollectionOptions(options) .build(); // Query first page with limit DocumentIterator page1 = client.query() .where("price", FilterOperation.GREATER_THAN, 10.0) .limit(5) .offset(0) .get(); System.out.println("=== Page 1 ==="); int count = 0; while (page1.hasNext()) { Book book = new Book(null, null, null, 0); page1.next(new Document(book)); count++; System.out.println(count + ". " + book.getTitle() + " - $" + book.getPrice()); } // Get pagination token for next page PaginationToken token = page1.getPaginationToken(); if (token != null) { // Query next page using pagination token DocumentIterator page2 = client.query() .where("price", FilterOperation.GREATER_THAN, 10.0) .limit(5) .paginationToken(token) .get(); System.out.println("=== Page 2 ==="); count = 0; while (page2.hasNext()) { Book book = new Book(null, null, null, 0); page2.next(new Document(book)); count++; System.out.println(count + ". " + book.getTitle() + " - $" + book.getPrice()); } } // Scan all documents (use with caution on large tables) DocumentIterator allDocs = client.query().get(); int total = 0; while (allDocs.hasNext()) { Book book = new Book(null, null, null, 0); allDocs.next(new Document(book)); total++; } System.out.println("Total documents: " + total); ``` -------------------------------- ### Build DocStoreClient with Collection Options Source: https://github.com/salesforce/multicloudj/blob/main/documentation/guides/docstore-guide.md Demonstrates how to create a DocStoreClient instance using the static builder. It includes configuring collection options such as table name, partition key, sort key, and revision field, along with specifying the cloud provider and region. ```java CollectionOptions collectionOptions = new CollectionOptions.CollectionOptionsBuilder() .withTableName("chameleon-test") .withPartitionKey("pName") .withSortKey("s") .withRevisionField("docRevision") .build(); DocStoreClient client = DocStoreClient.builder("aws") .withRegion("us-west-2") .withCollectionOptions(collectionOptions) .build(); ``` -------------------------------- ### Get Access Token Source: https://github.com/salesforce/multicloudj/blob/main/documentation/guides/sts-guide.md Illustrates how to obtain an OAuth2-style access token using the StsClient. This method is valuable when integrating with services that require token-based authentication. ```java GetAccessTokenRequest request = new GetAccessTokenRequest(); StsCredentials token = stsClient.getAccessToken(request); System.out.println("Access Token: " + token.getAccessToken()); ``` -------------------------------- ### Get Document by Primary Key in DocStore Source: https://github.com/salesforce/multicloudj/blob/main/documentation/guides/docstore-guide.md Retrieves a document from DocStore using its primary key. Requires a Document object initialized with key fields. Optionally, specific fields can be requested. ```java Player player = new Player(); player.setPName("Alice"); // Assuming pName is the partition key player.setS("metadata"); // Assuming s is the sort key client.get(new Document(player)); ``` ```java client.get(new Document(player), "pName", "f"); ``` -------------------------------- ### AWSBlobStore Provider Implementation for AWS Substrate Source: https://github.com/salesforce/multicloudj/blob/main/docs/design/layers.html Provides a concrete implementation of an AbstractBlobStore for the AWS substrate. It demonstrates how to initialize an S3Client and override methods like doUploadFile to perform substrate-specific operations, adhering to the driver layer contract. ```Java public class AWSBlobStore extends AbstractBlobStore { S3Client s3Client; public AWSBlobStore(Builder builder) { s3Client = ... // code logic to build the s3Client by information from builder } @Override protected void doUploadFile(String key, String filePath) { Map metadata = new HashMap<>(); PutObjectRequest putOb = PutObjectRequest.builder() .bucket(this.bucketName) .key(key) .metadata(metadata) .build(); s3Client.putObject(putOb, RequestBody.fromFile(new File(filePath))); log.info("Successfully placed object" + " into bucket " + bucketName); } @Override public Builder builder() { return new Builder(); } public static class Builder extends AbstractBlobStore.Builder { public Builder() { providerId("aws"); } @Override public AwsBlobStore build() { return new AwsBlobStore(this); } ... } } ``` -------------------------------- ### Example Blob Metadata Retrieval Source: https://github.com/salesforce/multicloudj/blob/main/examples/src/main/java/com/salesforce/multicloudj/blob/README.md Shows how to get the metadata for a blob. A blob key is specified, and then the client's getMetadata method is called to fetch the metadata, which is stored in a BlobMetadata object. ```java // reference to the blob key var blobKey = "blob-key"; // Use the BucketClient instance to get the metadata for the specified blob key using bucket client instance BlobMetadata metadata = client.getMetadata(blobKey); ``` -------------------------------- ### Handle Substrate SDK Exceptions Source: https://github.com/salesforce/multicloudj/blob/main/docs/guides/blobstore-guide.html Demonstrates how to catch and handle `SubstrateSdkException`, which is thrown for various errors such as access denied or I/O failures during bucket operations. ```java try { bucketClient.upload(request, new File("file.txt")); } catch (SubstrateSdkException e) { // Handle access denied, IO failure, etc. e.printStackTrace(); } ``` -------------------------------- ### Create BucketClient instance Source: https://github.com/salesforce/multicloudj/blob/main/documentation/guides/blobstore-guide.md Demonstrates how to create an instance of BucketClient for AWS S3, specifying the region and bucket name. Advanced options like endpoint and proxy overrides can also be configured. ```java BucketClient bucketClient = BucketClient.builder("aws") .withRegion("us-west-2") .withBucket("my-bucket") .build(); URI endpoint = URI.create("https://custom-endpoint.com"); URI proxy = URI.create("https://proxy.example.com"); bucketClient = BucketClient.builder("aws") .withRegion("us-west-2") .withBucket("my-bucket") .withEndpoint(endpoint) .withProxyEndpoint(proxy) .build(); ``` -------------------------------- ### Batch Get Documents in DocStore Source: https://github.com/salesforce/multicloudj/blob/main/documentation/guides/docstore-guide.md Retrieves multiple documents in a single batch operation. Requires a list of Document objects, each initialized with the key fields of the documents to retrieve. Uses an initialized docstore client. ```java List docs = List.of( new Document().put("pName", "Alice").put("s", "metadata"), new Document().put("pName", "Bob").put("s", "stats") ); client.batchGet(docs); ``` -------------------------------- ### Set Up Google Cloud Credentials in IDE Source: https://github.com/salesforce/multicloudj/blob/main/docs/guides/conformance-tests-guide.html Instructions for configuring Google Cloud credentials in an IDE. This involves logging into gcloud CLI, optionally impersonating a service account, and setting the GOOGLE_APPLICATION_CREDENTIALS environment variable to the location of the credentials file. ```bash gcloud auth application-default login gcloud config set auth/impersonate_service_account $SA_EMAIL GOOGLE_APPLICATION_CREDENTIALS=/Users//.config/gcloud/application_default_credentials.json ``` -------------------------------- ### Get Caller Identity Source: https://github.com/salesforce/multicloudj/blob/main/documentation/guides/sts-guide.md Shows how to retrieve the ARN (Amazon Resource Name) of the caller identity associated with the current credentials using the StsClient. This is useful for identifying the active security principal. ```java CallerIdentity identity = stsClient.getCallerIdentity(); System.out.println("Caller: " + identity.getArn()); ``` -------------------------------- ### Update Documents in NoSQL Databases (Java) Source: https://context7.com/salesforce/multicloudj/llms.txt Provides examples of updating existing documents in NoSQL databases using optimistic locking. It demonstrates replacing a document entirely and performing atomic updates on multiple documents. The process involves retrieving the document (to get its revision), modifying it, and then using the client's replace or update methods. ```java import com.salesforce.multicloudj.docstore.client.DocStoreClient; import com.salesforce.multicloudj.docstore.driver.Document; // Create client DocStoreClient client = DocStoreClient.builder("ali") .withRegion("cn-hangzhou") .withCollectionOptions(options) .build(); // Update a document (replace operation) Book bookToUpdate = new Book("1984", null, "Penguin", 0); // First, get the current document (includes revision info) client.get(new Document(bookToUpdate)); System.out.println("Current price: $" + bookToUpdate.getPrice()); // Modify the document bookToUpdate.setPrice(18.99f); // Replace with new values client.getActions() .replace(new Document(bookToUpdate)) .get(new Document(bookToUpdate)) // Retrieve updated document .run(); System.out.println("Updated price: $" + bookToUpdate.getPrice()); // Update multiple documents atomically Book book1 = new Book("Brave New World", null, "Harper", 0); client.get(new Document(book1)); book1.setPrice(book1.getPrice() * 1.1f); // 10% increase Book book2 = new Book("Fahrenheit 451", null, "Simon", 0); client.get(new Document(book2)); book2.setPrice(book2.getPrice() * 1.1f); client.getActions() .enableAtomicWrites() .replace(new Document(book1)) .replace(new Document(book2)) .run(); System.out.println("Multiple books updated atomically"); ``` -------------------------------- ### Upload Blob using Portable Layer for Blob Storage (Java) Source: https://github.com/salesforce/multicloudj/blob/main/docs/design/layers.html Demonstrates how to use the portable layer to upload a blob to a specified bucket in a cloud substrate (e.g., AWS). It shows setting up credentials, initializing the BucketClient, preparing an UploadRequest, and executing the upload. This layer is substrate-agnostic, requiring only the substrate type and region to be specified. ```java String substrate = "aws" String region = "us-east-1" StsCredentials credentials = new StsCredentials( "accessKeyId", "accessKeySecret", "sessionToken"); CredentialsOverrider credsOverrider = new CredentialsOverrider .Builder(CredentialsType.SESSION).withSessionCredentials(credentials).build(); BucketClient client = BucketClient.builder(substrate) .withBucket("chameleon-java") .withRegion(region) .withCredentialsOverrider(credsOverrider).build(); UploadRequest uploadRequest = new UploadRequest.Builder() .withKey("bucket-path/chameleon.jpg") UploadResponse response = client.upload(uploadRequest, "dummy-content"); ``` -------------------------------- ### Example Single Blob Deletion Source: https://github.com/salesforce/multicloudj/blob/main/examples/src/main/java/com/salesforce/multicloudj/blob/README.md Shows an example of deleting a single blob using its key. The client's delete method is called with the specific key of the blob to be removed from the storage. ```java // delete the key using bucket client instance client.delete("key-to-be-deleted"); ``` -------------------------------- ### Example Multiple Blob Deletion Source: https://github.com/salesforce/multicloudj/blob/main/examples/src/main/java/com/salesforce/multicloudj/blob/README.md Illustrates deleting multiple blobs by providing a list of keys to the client's delete method. This example prepares a list of keys and then invokes the delete operation for the collection. ```java // Assume we have a list of keys to delete List keysToDelete = Arrays.asList("key1", "key2", "key3"); // Delete the keys from the bucket using bucket client instance client.delete(keysToDelete); ``` -------------------------------- ### GET /blob/metadata/{key} Source: https://github.com/salesforce/multicloudj/blob/main/examples/src/main/java/com/salesforce/multicloudj/blob/README.md Retrieves the metadata of the Blob. ```APIDOC ## GET /blob/metadata/{key} ### Description Retrieves the metadata of the Blob. ### Method GET ### Endpoint /blob/metadata/{key} ### Parameters #### Path Parameters - **key** (string) - Required - Name of the Blob, whose metadata is to be retrieved. ### Request Example ```java // reference to the blob key var blobKey = "blob-key"; // Use the BucketClient instance to get the metadata for the specified blob key using bucket client instance BlobMetadata metadata = client.getMetadata(blobKey); ``` ### Response #### Success Response (200) - **BlobMetadata** (BlobMetadata) - Metadata of the Blob. #### Response Example ```json { "contentType": "image/jpeg", "contentLength": 1024, "lastModified": "2023-10-27T10:00:00Z" } ``` ``` -------------------------------- ### Get Blob Tags Source: https://github.com/salesforce/multicloudj/blob/main/examples/src/main/java/com/salesforce/multicloudj/blob/README.md Retrieves all tags associated with a specific blob. ```APIDOC ## Get Blob Tags ### Description Retrieves all key-value tags associated with a specific blob identified by its key. ### Method GET ### Endpoint /salesforce/multicloudj/blobs/{key}/tags ### Parameters #### Path Parameters - **key** (string) - Required - The name (key) of the blob whose tags are to be retrieved. ### Request Example ```java // Retrieve the tags for the blob with the key "blob-key" // Map tags = client.getTags("blob-key"); ``` ### Response #### Success Response (200) - **tags** (map[string, string]) - A map containing the tags associated with the blob. #### Response Example ```json { "tags": { "environment": "production", "owner": "data-team" } } ``` ``` -------------------------------- ### Downloading Files Source: https://github.com/salesforce/multicloudj/blob/main/docs/guides/blobstore-guide.html Explains how to download files from a bucket using the BucketClient, with support for saving to OutputStreams, Files, Paths, and byte arrays. ```APIDOC ## Downloading Files ### Description Downloads the content of a specified object key from the bucket. Supports downloading to various destinations including `OutputStream`, `File`, `Path`, and `byte[]`. ### Method `bucketClient.download(...) ### Endpoint N/A (Operation on an existing bucket) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **request** (`DownloadRequest`) - Required - Request object containing the source object key. - **data destination** (`OutputStream`, `File`, `Path`, `byteArray`) - Required - The destination to save the downloaded content. ### Request Example ```java DownloadRequest request = new DownloadRequest("object-key"); // Download to OutputStream bucketClient.download(request, outputStream); // Download to File bucketClient.download(request, new File("dest.txt")); // Download to Path bucketClient.download(request, path); // Download to byte array (assuming byte array is pre-allocated or dynamically sized) bucketClient.download(request, byteArray); ``` ### Response #### Success Response (200) N/A (Download operation typically returns void or a confirmation) #### Response Example N/A ``` -------------------------------- ### Abstract Upload Method in BucketClient Source: https://github.com/salesforce/multicloudj/blob/main/docs/design/layers.html Illustrates the internal workings of an upload method within BucketClient, showing common validation and provider-specific preparation and upload steps. This method is designed to abstract away substrate-specific details from the end-user. ```Java public UploadResponse upload(UploadRequest uploadRequest) { validation(); // common validation for all substrates prepContent(); // provider specific prep content doUpload(); // provider specific upload of the content } ``` -------------------------------- ### Basic Document Operations Source: https://github.com/salesforce/multicloudj/blob/main/documentation/guides/docstore-guide.md Perform fundamental operations on individual documents, such as creating, retrieving, replacing, or putting documents into the DocStore. ```APIDOC ## Basic Operations ### Create Create will throw an exception `ResourceAlreadyExists` if the document already exists. ```java client.create(doc); ``` ### Get To retrieve a document, you must provide a `Document` initialized with the corresponding object and pre-populate the fields that uniquely identify it (e.g., partition key and sort key): ```java Player player = new Player(); player.setPName("Alice"); // Assuming pName is the partition key player.setS("metadata"); // Assuming s is the sort key client.get(new Document(player)); ``` With optional fields you want to retrieve: ```java client.get(new Document(player), "pName", "f"); ``` ### Replace Replaces the existing doc, will throw `ResourceNotFound` is the document doesn't exist. ```java client.replace(doc); ``` ### Put Put is similar to create but will not throw in case the document doesn't exist. ```java client.put(doc); ``` ### Delete To delete a document, the input must also have the required key fields populated: ```java Player player = new Player(); player.setPName("Alice"); player.setS("metadata"); client.delete(new Document(player)); ``` ### Update (Not Supported) ```java client.update(doc, Map.of("f", 120.0f)); // Throws UnSupportedOperationException ``` ``` -------------------------------- ### Copy Recorded Mappings for Bazel Tests Source: https://github.com/salesforce/multicloudj/blob/main/docs/guides/conformance-tests-guide.html Provides a command to copy recorded test mappings from a temporary directory to the appropriate resources directory when using Bazel. This is necessary because Bazel executes tests in a temporary location, and recordings need to be moved to the actual project path for persistence. ```bash cp -r /tmp/mappings /Users/$relativePath/multicloudj/docstore/docstore-aws/src/test/resources/ ``` -------------------------------- ### Generate Presigned URLs with Bucket Client (Java) Source: https://github.com/salesforce/multicloudj/blob/main/documentation/guides/blobstore-guide.md Shows how to generate presigned URLs using the BucketClient. Presigned URLs provide temporary, time-limited access to objects without requiring cloud provider credentials, useful for sharing or downloading specific files. ```java PresignedUrlRequest presignedRequest = new PresignedUrlRequest(); URL url = bucketClient.generatePresignedUrl(presignedRequest); ``` -------------------------------- ### Batch Get Operation Source: https://github.com/salesforce/multicloudj/blob/main/docs/guides/docstore-guide.html Retrieves multiple documents in a single batch request. Provide a list of `Document` objects, each populated with the necessary key fields to identify the documents. ```APIDOC ## Batch Get ```java List docs = List.of( new Document().put("pName", "Alice").put("s", "metadata"), new Document().put("pName", "Bob").put("s", "stats") ); client.batchGet(docs); ``` ``` -------------------------------- ### Manage Blob Metadata and Tags with Bucket Client (Java) Source: https://github.com/salesforce/multicloudj/blob/main/documentation/guides/blobstore-guide.md Demonstrates how to retrieve, set, and manage metadata and tags for objects (blobs) in a bucket using the BucketClient. This is useful for organizing and categorizing data within cloud storage. ```java BlobMetadata metadata = bucketClient.getMetadata("object-key", null); Map tags = bucketClient.getTags("object-key"); bucketClient.setTags("object-key", Map.of("env", "prod")); ``` -------------------------------- ### Get Document Operation Source: https://github.com/salesforce/multicloudj/blob/main/docs/guides/docstore-guide.html Retrieves a document using its unique identifier (partition key and sort key). An optional list of fields can be provided to retrieve only specific attributes. ```java Player player = new Player(); player.setPName("Alice"); // Assuming pName is the partition key player.setS("metadata"); // Assuming s is the sort key client.get(new Document(player)); // Get with all fields client.get(new Document(player), "pName", "f"); // Get with specific fields ``` -------------------------------- ### Manage Blob Metadata and Tags Source: https://github.com/salesforce/multicloudj/blob/main/docs/guides/blobstore-guide.html Retrieves or sets metadata and tags for a blob. Supports getting the blob's metadata, retrieving its tags, and setting new tags. ```java BlobMetadata metadata = bucketClient.getMetadata("object-key", null); Map tags = bucketClient.getTags("object-key"); bucketClient.setTags("object-key", Map.of("env", "prod")); ``` -------------------------------- ### Perform Multipart Uploads with Bucket Client (Java) Source: https://github.com/salesforce/multicloudj/blob/main/documentation/guides/blobstore-guide.md Illustrates the process of initiating, uploading parts, completing, listing, and aborting multipart uploads using the BucketClient. This is essential for efficiently uploading large files by breaking them into smaller, manageable parts. ```java MultipartUploadRequest initRequest = new MultipartUploadRequest(); MultipartUpload upload = bucketClient.initiateMultipartUpload(initRequest); UploadPartResponse part = bucketClient.uploadMultipartPart(upload, partData); List parts = List.of(part1, part2); bucketClient.completeMultipartUpload(upload, parts); List uploadedParts = bucketClient.listMultipartUpload(upload); bucketClient.abortMultipartUpload(upload); ``` -------------------------------- ### Querying Documents Source: https://github.com/salesforce/multicloudj/blob/main/documentation/guides/docstore-guide.md Retrieve multiple documents matching specific conditions using the flexible query interface, which supports filtering and sorting. ```APIDOC ## Queries DocStore's `get` action retrieves a single document by its primary key. However, when you need to retrieve or manipulate multiple documents that match a condition, you can use queries. Queries allow you to: - Retrieve all documents that match specific conditions. - Delete or update documents in bulk based on criteria. The query interface is chainable and supports filtering and sorting (depending on driver support). DocStore can also optimize queries automatically. Based on your filter conditions, it attempts to determine whether a global secondary index (GSI) or a local secondary index (LSI) can be used to execute the query more efficiently. This helps reduce latency and improves performance. Queries support the following methods: - **Where**: Describes a condition on a document. You can ask whether a field is equal to, greater than, or less than a value. The "not equals" comparison isn't supported, because it isn't portable across providers. - **OrderBy**: Specifies the order of the resulting documents, by field and direction. For portability, you can specify at most one OrderBy, and its field must also be mentioned in a Where clause. - **Limit**: Limits the number of documents in the result. ```java Query query = client.query(); // Apply filtering, sorting, etc. ``` (Depends on driver implementation.) ``` -------------------------------- ### Create Documents in NoSQL Databases (Java) Source: https://context7.com/salesforce/multicloudj/llms.txt Demonstrates how to create single and multiple documents in NoSQL databases using the DocStoreClient. This involves defining a data model, configuring collection options with partition and sort keys, and then using the client's create methods. Atomic writes can be enabled for multiple document creations. ```java import com.salesforce.multicloudj.docstore.client.DocStoreClient; import com.salesforce.multicloudj.docstore.driver.CollectionOptions; import com.salesforce.multicloudj.docstore.driver.Document; // Define your data model class Book { private String title; private String author; private String publisher; private float price; public Book(String title, String author, String publisher, float price) { this.title = title; this.author = author; this.publisher = publisher; this.price = price; } // Getters and setters... } // Configure collection options CollectionOptions options = new CollectionOptions.CollectionOptionsBuilder() .withTableName("books-table") .withPartitionKey("title") // Primary key .withSortKey("publisher") // Sort key (optional) .withRevisionField("docRevision") // For optimistic locking .withAllowScans(true) // Enable table scans .build(); // Create client DocStoreClient client = DocStoreClient.builder("aws") .withRegion("us-west-2") .withCollectionOptions(options) .build(); // Create single document Book book = new Book("The Great Gatsby", "F. Scott Fitzgerald", "Scribner", 15.99f); client.create(new Document(book)); System.out.println("Book created successfully"); // Create multiple documents with atomic writes client.getActions() .enableAtomicWrites() .create(new Document(new Book("1984", "George Orwell", "Penguin", 14.99f))) .create(new Document(new Book("Brave New World", "Aldous Huxley", "Harper", 13.99f))) .create(new Document(new Book("Fahrenheit 451", "Ray Bradbury", "Simon", 12.99f))) .run(); System.out.println("Multiple books created atomically"); ``` -------------------------------- ### Download Blobs using BucketClient Source: https://github.com/salesforce/multicloudj/blob/main/documentation/guides/blobstore-guide.md Illustrates downloading blobs from cloud storage via the BucketClient. Downloads can be directed to an OutputStream, File, Path, or byte array. ```java DownloadRequest request = new DownloadRequest("object-key"); bucketClient.download(request, outputStream); bucketClient.download(request, new File("dest.txt")); bucketClient.download(request, path); bucketClient.download(request, byteArray); ```