Wallets¶
Wallets hold allocations which grant access to a provider’s resources.
Rationale¶
Wallet
s are the core abstraction used in the accounting system of UCloud. This feature builds
on top of various other features of UCloud. Here is a quick recap:
The users of UCloud are members of Workspaces and Projects. These form the foundation of all collaboration in UCloud.
UCloud is an orchestrator of
Resource
s. UCloud delegates the responsibility of hostingResource
s toProvider
s.Provider
s define which services they support usingProduct
s.All
Product
s belong in aProductCategory
. The category contains similarProduct
s. Under normal circumstances, all products in a category run on the same system.Product
s define a payment model. The model supports quotas (DIFFERENTIAL_QUOTA
), one-time payments and periodic payments (ABSOLUTE
). All absolute payment models support paying in a product-specific unit or in DKK.All
Product
s in a category share the exact same payment model
Allocators grant access to Resource
s via WalletAllocation
s. In a simplified view, an
allocation is:
An initial balance, specified in the “unit of allocation” which the
Product
specifies. For example: 1000 DKK or 500 Core Hours.Start date and optional end date.
An optional parent allocation.
A current balance, the balance remaining for this allocation and all descendants.
A local balance, the balance remaining if it had no descendants
UCloud combines allocations of the same category into a Wallet
Every Wallet
has
exactly one owner, a workspace.
Wallet
s create a natural hierarchical structure. Below we show an example of this:
Figure: Allocations create a natural allocation hierarchy.
📝NOTE: The wallet and accounting systems are currently considered internal due to some limitations in the API. We aim to keep the provider API (the control interfaces) stable but the accounting system itself will remain at an internal level until we have resolved the issues at an API level. We plan on making this API stable in the long-term.
Table of Contents¶
1. Remote Procedure Calls
Name | Description |
---|---|
browse |
Browses the catalog of accessible Wallets |
browseSubAllocations |
Browses the catalog of sub-allocations |
retrieveProviderSummary |
Retrieves a provider summary of relevant wallets |
retrieveRecipient |
Retrieves information about a potential WalletAllocation recipient |
searchSubAllocations |
Searches the catalog of sub-allocations |
push |
Pushes a Wallet to the catalog |
register |
Registers an allocation created outside of UCloud |
2. Data Models
Name | Description |
---|---|
Wallet |
Wallets hold allocations which grant access to a provider's resources. |
WalletAllocation |
An allocation grants access to resources |
AllocationSelectorPolicy |
A policy for how to select a WalletAllocation in a single Wallet |
ProviderWalletSummary |
No description |
SubAllocation |
A parent allocator's view of a `WalletAllocation` |
WalletOwner |
No description |
WalletOwner.Project |
No description |
WalletOwner.User |
No description |
PushWalletChangeRequestItem |
No description |
RegisterWalletRequestItem |
No description |
WalletBrowseRequest |
The base type for requesting paginated content. |
WalletsBrowseSubAllocationsRequest |
No description |
WalletsRetrieveProviderSummaryRequest |
The base type for requesting paginated content. |
WalletsRetrieveRecipientRequest |
No description |
WalletsSearchSubAllocationsRequest |
No description |
WalletsRetrieveRecipientResponse |
No description |
Remote Procedure Calls¶
browse
¶
Browses the catalog of accessible Wallets
Request | Response | Error |
---|---|---|
WalletBrowseRequest |
PageV2<Wallet> |
CommonErrorMessage |
browseSubAllocations
¶
Browses the catalog of sub-allocations
Request | Response | Error |
---|---|---|
WalletsBrowseSubAllocationsRequest |
PageV2<SubAllocation> |
CommonErrorMessage |
This endpoint will find all WalletAllocation
s which are direct children of one of your
accessible WalletAllocation
s.
retrieveProviderSummary
¶
Retrieves a provider summary of relevant wallets
Request | Response | Error |
---|---|---|
WalletsRetrieveProviderSummaryRequest |
PageV2<ProviderWalletSummary> |
CommonErrorMessage |
This endpoint is only usable by providers. The endpoint will return a stable sorted summary of all allocations that a provider currently has.
retrieveRecipient
¶
Retrieves information about a potential WalletAllocation recipient
Request | Response | Error |
---|---|---|
WalletsRetrieveRecipientRequest |
WalletsRetrieveRecipientResponse |
CommonErrorMessage |
You can use this endpoint to find information about a Workspace. This is useful when creating a sub-allocation.
searchSubAllocations
¶
Searches the catalog of sub-allocations
Request | Response | Error |
---|---|---|
WalletsSearchSubAllocationsRequest |
PageV2<SubAllocation> |
CommonErrorMessage |
This endpoint will find all WalletAllocation
s which are direct children of one of your
accessible WalletAllocation
s.
push
¶
Pushes a Wallet to the catalog
Request | Response | Error |
---|---|---|
BulkRequest<PushWalletChangeRequestItem> |
Unit |
CommonErrorMessage |
Be careful with using this endpoint as it might go away in a future release.
register
¶
Registers an allocation created outside of UCloud
Request | Response | Error |
---|---|---|
BulkRequest<RegisterWalletRequestItem> |
Unit |
CommonErrorMessage |
Be careful with using this endpoint as it might go away in a future release.
Data Models¶
Wallet
¶
Wallets hold allocations which grant access to a provider’s resources.
data class Wallet(
val owner: WalletOwner,
val paysFor: ProductCategoryId,
val allocations: List<WalletAllocation>,
val chargePolicy: AllocationSelectorPolicy,
val productType: ProductType?,
val chargeType: ChargeType?,
val unit: ProductPriceUnit?,
)
You can find more information about WalletAllocations here.
Properties
owner
: WalletOwner
WalletOwner
paysFor
: ProductCategoryId
ProductCategoryId
allocations
: List<WalletAllocation>
List<WalletAllocation>
chargePolicy
: AllocationSelectorPolicy
AllocationSelectorPolicy
productType
: ProductType?
ProductType?
chargeType
: ChargeType?
ChargeType?
unit
: ProductPriceUnit?
ProductPriceUnit?
WalletAllocation
¶
An allocation grants access to resources
data class WalletAllocation(
val id: String,
val allocationPath: List<String>,
val balance: Long,
val initialBalance: Long,
val localBalance: Long,
val startDate: Long,
val endDate: Long?,
val grantedIn: Long?,
val canAllocate: Boolean?,
val allowSubAllocationsToAllocate: Boolean?,
)
You can find more information about WalletAllocations here.
Properties
id
: String
A unique ID of this allocation
String
allocationPath
: List<String>
A path, starting from the top, through the allocations that will be charged, when a charge is made
List<String>
Note that this allocation path will always include, as its last element, this allocation.
balance
: Long
The current balance of this wallet allocation's subtree
Long
initialBalance
: Long
The initial balance which was granted to this allocation
Long
localBalance
: Long
The current balance of this wallet allocation
Long
startDate
: Long
Timestamp for when this allocation becomes valid
Long
endDate
: Long?
Timestamp for when this allocation becomes invalid, null indicates that this allocation does not expire automatically
Long?
grantedIn
: Long?
ID reference to which grant application this allocation was granted in
Long?
canAllocate
: Boolean?
A property which indicates if this allocation can be used to create sub-allocations
Boolean?
allowSubAllocationsToAllocate
: Boolean?
A property which indicates that new sub-allocations of this allocation by default should have canAllocate = true
Boolean?
AllocationSelectorPolicy
¶
A policy for how to select a WalletAllocation in a single Wallet
enum class AllocationSelectorPolicy {
EXPIRE_FIRST,
}
Properties
EXPIRE_FIRST
Use the WalletAllocation which is closest to expiration
ProviderWalletSummary
¶
data class ProviderWalletSummary(
val id: String,
val owner: WalletOwner,
val categoryId: ProductCategoryId,
val productType: ProductType,
val chargeType: ChargeType,
val unitOfPrice: ProductPriceUnit,
val maxUsableBalance: Long,
val maxPromisedBalance: Long,
val notBefore: Long,
val notAfter: Long?,
)
Properties
id
: String
String
owner
: WalletOwner
WalletOwner
categoryId
: ProductCategoryId
ProductCategoryId
productType
: ProductType
ProductType
chargeType
: ChargeType
ChargeType
unitOfPrice
: ProductPriceUnit
ProductPriceUnit
maxUsableBalance
: Long
Maximum balance usable until a charge would fail
Long
This balance is calculated when the data is requested and thus can immediately become invalid due to changes in the tree.
maxPromisedBalance
: Long
Maximum balance usable as promised by a top-level grant giver
Long
This balance is calculated when the data is requested and thus can immediately become invalid due to changes in the tree.
notBefore
: Long
The earliest timestamp which allows for the balance to be consumed
Long
notAfter
: Long?
The earliest timestamp at which the reported balance is no longer fully usable
Long?
SubAllocation
¶
A parent allocator’s view of a WalletAllocation
data class SubAllocation(
val id: String,
val path: String,
val startDate: Long,
val endDate: Long?,
val productCategoryId: ProductCategoryId,
val productType: ProductType,
val chargeType: ChargeType,
val unit: ProductPriceUnit,
val workspaceId: String,
val workspaceTitle: String,
val workspaceIsProject: Boolean,
val projectPI: String?,
val remaining: Long,
val initialBalance: Long,
)
Properties
id
: String
String
path
: String
String
startDate
: Long
Long
endDate
: Long?
Long?
productCategoryId
: ProductCategoryId
ProductCategoryId
productType
: ProductType
ProductType
chargeType
: ChargeType
ChargeType
unit
: ProductPriceUnit
ProductPriceUnit
workspaceId
: String
String
workspaceTitle
: String
String
workspaceIsProject
: Boolean
Boolean
projectPI
: String?
String?
remaining
: Long
Long
initialBalance
: Long
Long
WalletOwner
¶
sealed class WalletOwner {
class Project : WalletOwner()
class User : WalletOwner()
}
WalletOwner.Project
¶
data class Project(
val projectId: String,
val type: String /* "project" */,
)
WalletOwner.User
¶
data class User(
val username: String,
val type: String /* "user" */,
)
PushWalletChangeRequestItem
¶
data class PushWalletChangeRequestItem(
val allocationId: String,
val amount: Long,
)
RegisterWalletRequestItem
¶
data class RegisterWalletRequestItem(
val owner: WalletOwner,
val uniqueAllocationId: String,
val categoryId: String,
val balance: Long,
val providerGeneratedId: String?,
)
Properties
owner
: WalletOwner
WalletOwner
uniqueAllocationId
: String
String
categoryId
: String
String
balance
: Long
Long
providerGeneratedId
: String?
String?
WalletBrowseRequest
¶
The base type for requesting paginated content.
data class WalletBrowseRequest(
val itemsPerPage: Int?,
val next: String?,
val consistency: PaginationRequestV2Consistency?,
val itemsToSkip: Long?,
val filterType: ProductType?,
)
Paginated content can be requested with one of the following consistency
guarantees, this greatly changes the
semantics of the call:
Consistency | Description |
---|---|
PREFER |
Consistency is preferred but not required. An inconsistent snapshot might be returned. |
REQUIRE |
Consistency is required. A request will fail if consistency is no longer guaranteed. |
The consistency
refers to if collecting all the results via the pagination API are consistent. We consider the
results to be consistent if it contains a complete view at some point in time. In practice this means that the results
must contain all the items, in the correct order and without duplicates.
If you use the PREFER
consistency then you may receive in-complete results that might appear out-of-order and can
contain duplicate items. UCloud will still attempt to serve a snapshot which appears mostly consistent. This is helpful
for user-interfaces which do not strictly depend on consistency but would still prefer something which is mostly
consistent.
The results might become inconsistent if the client either takes too long, or a service instance goes down while
fetching the results. UCloud attempts to keep each next
token alive for at least one minute before invalidating it.
This does not mean that a client must collect all results within a minute but rather that they must fetch the next page
within a minute of the last page. If this is not feasible and consistency is not required then PREFER
should be used.
📝 NOTE: Services are allowed to ignore extra criteria of the request if the next
token is supplied. This is
needed in order to provide a consistent view of the results. Clients should provide the same criterion as they
paginate through the results.
Properties
itemsPerPage
: Int?
Requested number of items per page. Supported values: 10, 25, 50, 100, 250.
Int?
next
: String?
A token requesting the next page of items
String?
consistency
: PaginationRequestV2Consistency?
Controls the consistency guarantees provided by the backend
PaginationRequestV2Consistency?
itemsToSkip
: Long?
Items to skip ahead
Long?
filterType
: ProductType?
ProductType?
WalletsBrowseSubAllocationsRequest
¶
data class WalletsBrowseSubAllocationsRequest(
val filterType: ProductType?,
val itemsPerPage: Int?,
val next: String?,
val consistency: PaginationRequestV2Consistency?,
val itemsToSkip: Long?,
)
Properties
filterType
: ProductType?
ProductType?
itemsPerPage
: Int?
Requested number of items per page. Supported values: 10, 25, 50, 100, 250.
Int?
next
: String?
A token requesting the next page of items
String?
consistency
: PaginationRequestV2Consistency?
Controls the consistency guarantees provided by the backend
PaginationRequestV2Consistency?
itemsToSkip
: Long?
Items to skip ahead
Long?
WalletsRetrieveProviderSummaryRequest
¶
The base type for requesting paginated content.
data class WalletsRetrieveProviderSummaryRequest(
val itemsPerPage: Int?,
val next: String?,
val consistency: PaginationRequestV2Consistency?,
val itemsToSkip: Long?,
val filterOwnerId: String?,
val filterOwnerIsProject: Boolean?,
val filterCategory: String?,
)
Paginated content can be requested with one of the following consistency
guarantees, this greatly changes the
semantics of the call:
Consistency | Description |
---|---|
PREFER |
Consistency is preferred but not required. An inconsistent snapshot might be returned. |
REQUIRE |
Consistency is required. A request will fail if consistency is no longer guaranteed. |
The consistency
refers to if collecting all the results via the pagination API are consistent. We consider the
results to be consistent if it contains a complete view at some point in time. In practice this means that the results
must contain all the items, in the correct order and without duplicates.
If you use the PREFER
consistency then you may receive in-complete results that might appear out-of-order and can
contain duplicate items. UCloud will still attempt to serve a snapshot which appears mostly consistent. This is helpful
for user-interfaces which do not strictly depend on consistency but would still prefer something which is mostly
consistent.
The results might become inconsistent if the client either takes too long, or a service instance goes down while
fetching the results. UCloud attempts to keep each next
token alive for at least one minute before invalidating it.
This does not mean that a client must collect all results within a minute but rather that they must fetch the next page
within a minute of the last page. If this is not feasible and consistency is not required then PREFER
should be used.
📝 NOTE: Services are allowed to ignore extra criteria of the request if the next
token is supplied. This is
needed in order to provide a consistent view of the results. Clients should provide the same criterion as they
paginate through the results.
Properties
itemsPerPage
: Int?
Requested number of items per page. Supported values: 10, 25, 50, 100, 250.
Int?
next
: String?
A token requesting the next page of items
String?
consistency
: PaginationRequestV2Consistency?
Controls the consistency guarantees provided by the backend
PaginationRequestV2Consistency?
itemsToSkip
: Long?
Items to skip ahead
Long?
filterOwnerId
: String?
String?
filterOwnerIsProject
: Boolean?
Boolean?
filterCategory
: String?
String?
WalletsRetrieveRecipientRequest
¶
data class WalletsRetrieveRecipientRequest(
val query: String,
)
Properties
query
: String
String
WalletsSearchSubAllocationsRequest
¶
data class WalletsSearchSubAllocationsRequest(
val query: String,
val filterType: ProductType?,
val itemsPerPage: Int?,
val next: String?,
val consistency: PaginationRequestV2Consistency?,
val itemsToSkip: Long?,
)
Properties
query
: String
String
filterType
: ProductType?
ProductType?
itemsPerPage
: Int?
Requested number of items per page. Supported values: 10, 25, 50, 100, 250.
Int?
next
: String?
A token requesting the next page of items
String?
consistency
: PaginationRequestV2Consistency?
Controls the consistency guarantees provided by the backend
PaginationRequestV2Consistency?
itemsToSkip
: Long?
Items to skip ahead
Long?
WalletsRetrieveRecipientResponse
¶
data class WalletsRetrieveRecipientResponse(
val id: String,
val isProject: Boolean,
val title: String,
val principalInvestigator: String,
val numberOfMembers: Int,
)
Properties
id
: String
String
isProject
: Boolean
Boolean
title
: String
String
principalInvestigator
: String
String
numberOfMembers
: Int
Int