Replies: 1 comment 3 replies
-
for the cloud specific qualifiers, maybe it makes sense to add |
Beta Was this translation helpful? Give feedback.
3 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
The Object Storage is one of the fundamental services provided by the cloud provides. The objects are generally stored in the tree directory structure similary like on the file system. The objects are consumed either by API or in most cases by their unique HTTP URL or by cloud specific internal URI (See Appendix 1).
Motivation
The initiative addresses a growing need to support the hybrid cloud applications by allowing the developers to transparently access and manipulate the objects from within applications running in various cloud environments.
Goal
The goal of the object storage abstraction layer is to create an object storage interface that is independent on the object storage provider. The abstraction layer hides the provider's object storage specifics and allows the developer to interact with the object storage no matter the subject of interaction is any of the supported object storage services (AWS S3, Google Cloud Storage, Azure Blob Storage, Oracle Cloud Object Storage) or local storage.
Use cases
The general use cases related to the manipulation with the objects on objects storage.
Put object
Upload objects to the object storage.
Example:
Get object
Receive object from object storage.
Example:
Update object
Update already existing object on object storage. Based on the object storage policy, this operation may fail.
Example:
Copy objects
Copy objects in the scope of one object storage or in between the object storages.
Example:
Delete object
Delete object from object storage. Based on the object storage policy, this operation may fail.
Example:
List objects
List objects from object storage.
Example:
Sync objects
Sync directories in between object storages or with local directory.
Example:
Design
The design consists from the 4 parts:
Low Level API
This section describes the main building blocks of the Object Storage abstraction layer.
Object entry
Every object is uniquely identified by its path within the bucket. Additionally the objects have metadata associated with them. The metadata represents various object properties (like content type, tags, cache control, ..) and are provided when creating or updating the object on the object storage. See Appendix 3 for the object metadata list that are generally provided by cloud providers.
For the sake of the object-oriented approach, the object on object storage has its own object representation:
Object storage
Note: In general the ObjectStorage is understood rather as the service than the storage itself. Every object storage service has some internal architecture. The most known and used name for the place where are the objects stored is the bucket. The bucket is used by AWS, GoogleCloud, OracleCloud. However, the inclusion of the bucket into the internal architecture differs. For AWS,GCloud the name of the bucket is unique globally. For Oracle Cloud the uniqueness is in scope of the namespace (tenant). On the opposite the Azure uses container instead of bucket and the uniquness is in scope of the storage account. Because of that the noun ObjectStorage is IMHO the best representation of the main interaction with the service itself as it abstracts all the cloud provider's specifics and yet is not related to any cloud provider nomenclature.
The
ObjectStorage
interface provides the common operations with objects on the logical storage. Such abstraction allows to have specificObjectStorage
configurations like authentication, ACL policies, tags or hooks with respect to the implemented adapter for the given provider. For example if the application has two object storages configured, then there are twoObjectStorage
beans created.The location of the object on the logical storage is represented as the file path in directory structure, without containing any object storage provider specifics. For example the object on AWS S3 represented as S3 URI
s3://micronaut-object-storage/micronaut-buffer-netty-3.1.1.pom
is represented asmicronaut-buffer-netty-3.1.1.pom
. Such approach allows the developer to independently work with objects leaving the object storage specifics be handled by the respective implementation of theObjectStorage
interface.The API of
ObjectStorage
mixes Java native types methods with the object-oriented approach. The Java native types methods are for quick and easy interaction.Reactive version:
Q: Since the object locator is a path without object storage specific, using the String as locator was a first call. However, the java.nio.file.Path could be a more suited option. This also means the
ObjectStorageObject#getPath
andObjectStorageObject#getAbsolutePath
would reflect that. See extensions where this is discussed moreExample 1: Interaction using Java native types
Configuration
The common configuration interface contains just name of the object storage only, e.g. for
s3://micronaut-object-storage/
it ismicronaut-object-storage
. The rest of the properties is cloud provider specific:The "DSL" of configuration:
Example for hybrid cloud application:
Note the same name of the object storage.
application-ec2.yml
application-oraclecloud.yml
:application-azure.yml
:application-gcp.yml
:Example for using more cloud providers:
application.yml
:Configuration Alternative
The configuration can be merged into flat structure, having the object storage implementation be driven by mandatory field
provider
.The "DSL" of configuration:
Example for using more cloud providers:
Injection
ObjectStorage Qualifier
The ObjectStorage qualifier is evaluated from the
ObjectStorageConfiguration#getName
property. The propertyname
is derived from the configuration (in this order):micronaut-object-storage
The reason for having this way of qualifier evaluation lies within the hybrid cloud use case when it is not possible to have unified name of the bucket across the cloud providers. This is a case for AWS S3 and Google Cloud Object Storage where the bucket are globally uniquely identified.
For the configuration:
the injection using the the
@Named
annotation looks like for the configuration:Extensions
Extension 1: ObjectStorage beans based on configured SDK authentication using @nAmed
Allows to create
ObjectStorage
beans using qualifiers if there's either~/.aws/,
~/.oci/`).Then for example if OCI sdk is present and the credentials were automatically deduced:
Will cause the
ObjectStorage
forOracle Cloud Object Storage
for bucketmicronaut-object-storage
using thenamespace
andregion
evaluated from the OCI sdk are used.The advantage is there's no need to configure the object storage in
application.yml
.Note that this is possible to do only in case there's one cloud provider ObjectStorage library presented on classpath. In case there would be two supported ObjectStorage implementation, the internals wouldn't have a way how to find out what cloud provider to use.
Extension 2: ObjectStorage beans based on configured SDK authentication using specialised bean qualifiers
This allows to leverage the automatic SDK evaluation even when there are more ObjectStorage implementations by using specialised qualifiers like:
@AwsObjectStorage
,@OciObjectStorage
Then:
Will cause the
ObjectStorage
annotated by@OciObjectStorage
will create forOracle Cloud Object Storage
for bucketmicronaut-object-storage
using thenamespace
andregion
evaluated from the OCI sdk are used. Similarly for the@AwsObjectStorage
.Note that by using the cloud provider specific annotation the cloud agnostic approach is broken.
Extension 3: The
ResourceLoader
for quick access of objects using agnostic URIImplements the ResourceLoader in order to get the objects using shorter URI in common format:
ObjectStorage#getName
Then for configuration:
The locator would be:
public-images://path/to/file
Extension 4: The
ResourceLoader
for quick access of objects using cloud specific URIImplements the ResourceLoader in order to get the objects using shorter URI in common format:
Where for the cloud providers:
s3://<bucket-name>/path/to/file
s3://micronaut-object-storage/micronaut-buffer-netty-3.1.1.pom
azb:<storage-account-name>://<container>/path/to/file
azb:micronautpgressatest://micronaut-object-storate/micronaut-buffer-netty-3.1.1.pom
gs://<bucket-name>/path/to/file
sgs//micronaut-object-storage/micronaut-buffer-netty-3.1.1.pom
os:<region>:<namespace>://<bucket-name>/path/to/file
os:us-ashburn-1:cloudnative-devrel://micronaut-object-storate/micronaut-buffer-netty-3.1.1.pom
Extension 5: StreamingFileUpload using agnostic api
Idea is to implement cloud agnostic StreamingFileUpload where when
transferTo(String)
method would be used using cloud agnostic locator:Extension 6: StreamingFileUpload using cloud specifc URI
Extension 7: java.nio extension
The idea is to implement the https://docs.oracle.com/javase/7/docs/api/java/nio/file/FileSystem.html for given cloud providers leveriging already existing beans etc.
There are projects that implement to some extend the java.nio:
Appendix
Appendix 1: Object URL access
AWS
https://<bucket-name>.s3.<region>.amazonaws.com/<object-name>
https://micronaut-object-storage.s3.eu-west-1.amazonaws.com/micronaut-buffer-netty-3.1.1.pom
s3://<bucket-name>/<object-name>
s3://micronaut-object-storage/micronaut-buffer-netty-3.1.1.pom
arn:aws:s3:::<bucket-name>/<object-name>
arn:aws:s3:::micronaut-object-storage/micronaut-buffer-netty-3.1.1.pom
Azure
https://<storage-account-name>.blob.core.windows.net/<container>/<blob-name>
https://micronautpgressatest.blob.core.windows.net/micronaut-object-storate/micronaut-buffer-netty-3.1.1.pom
Google Cloud
https://storage.cloud.google.com/<bucket-name>/<object-name>
https://storage.cloud.google.com/micronaut-object-storage/micronaut-buffer-netty-3.1.1.pom
gs://<bucket-name>/<object-name>
gs://micronaut-object-storage/micronaut-buffer-netty-3.1.1.pom
Oracle Cloud
https://objectstorage.<region>.oraclecloud.com/n/<namespace>/b/<bucket-name>/o/<object-name>
https://objectstorage.us-ashburn-1.oraclecloud.com/n/cloudnative-devrel/b/micronaut-object-storage/o/micronaut-buffer-netty-3.1.1.pom
Appendix 2: Internal structure of object storage per provider
Even though the object storage use case is the file manipulation, the internal complexity varies among the cloud provides. For example the logical nesting of an object in the service:
Azure
Amazon Web Services
Google Cloud
Oracle Cloud
Appendix 3: Object common properties
cache-control
content-type
content-language
content-encoding
meta
expires
Next steps
Minimum usable product
Minimum viable product
Updates:
2021-11-16 - jcloud/blobstore - https://jclouds.apache.org
jcloud - Apache jcloud is an open source multi-cloud toolkit for the Java platform that gives you the freedom to create applications that are portable across clouds while giving you full control to use cloud-specific features.
Comment: Specifically the
blobstore
module. The BlobStore abstracts the object storage service itself. The consumer then needs to provide the name of the container (bucket) for every operation with the objects.Source: https://jclouds.apache.org/guides/aws/
This makes the consumer interaction less readable. The only simplification Micronaut can then offer is the pre-configuration of the
BlobStoreContext
. After that the consumer would have to always use the name of the container for every object operation.An option is to use this library to do the muscle work, so the
ObjectStorage
interface would be kept.(!) The jcloud is not built on top of official SDKs, the communication/authenticaion is handled by jcloud itself. This increases risk of regression or missing features: s3client, azureblob, gcloud-object-storage.
Pros:
Cons:
Summary:
jcloud is great inspiration how to handle the abstraction but for our case the library is bit outadated and does not reflect the asynchronous/reactive approach. Also the fact that it is not built on top of officially supported cloud SDKs raises concerns related to security and level of supported features, authentication mechanisms specifically. If our goal is to provide lightweight abstraction that is highly integrated into Micronaut, then jcloud is not a library I recommend to use.
Beta Was this translation helpful? Give feedback.
All reactions