This document introduces the high level business API (Biz API) in the aps.biz
name space that
substantially simplifies the interaction of an APS application with the business modules of the platform.
Business module | Module actions | Application actions |
---|---|---|
User management | Operations with service users | Assign and configure services for users |
Domain management | Operations with DNS zones | Not implemented yet |
Subscription management | Operations with resource limits and usage | Change resource limitation and usage |
In this document:
The following sections consider two typical resource management models. In both scenarios, there is an application that assigns its service as amount of resources to users.
The management platform controls the following objects and processes:
The following resource management models differ in resource usage control.
In this case, the platform determines the actual resource usage by means of a resource counter that the platform polls periodically. Generally, the resource usage is less than the assigned amount. The business model implies a customer pays for the actual resource usage following the pay-as-you-go method. However, the application takes into account the total assigned amount and compares the subscription Limit with the Assigned total when assigning the service to users.
In this scenario, once the subscriber assigns a license for a service to a service user, the platform considers one more unit of the resource is used. In this case, the resource usage equals the assigned amount.
To monitor and change resource usage and assignment on high level, the Biz API exposes a few methods with the following typical workflow in a UI view:
A view that uses the aps.biz
methods must provide the predefined view-plugin placeholder
in the application APP-META.xml
file:
<plugin-placeholder id=“http://www.aps-standard.org/core/package#biz" />
The APS JS module responsible for the aps.biz
methods will plug into the specified placeholder.
To support async operations, each of the aps.biz
methods returns a
dojo/Deferred promise for the
output specified in the table below.
Method | Input | Output | Description |
---|---|---|---|
getResourcesToBind | - |
{
users: [users],domains: [domains],subscriptions: [subscriptions]}
|
Returns up to three lists of objects to bind the application services to.
Currently, the method is integrated with the user creation wizard that returns the users list. |
getResourcesInfo | { filter: [<resource filters>] }
A resource filter:
{
apsType: <APS type>,apsProperty: <counter property>,apsId: <APS ID of a reference resource>}
|
[resources]
Each entry is a resource representation
|
Returns a list of entries, each containing billing data about a requested resource.
Primary keys for filtering resources are apsType , apsProperty , and apsId . |
canChangeUsage | {deltas:[resource requests]}
A resource request:
{
apsType: <APS type>,apsProperty: <counter property>,apsId: <APS ID of a reference resource>delta: <request for increase>}
|
- true - update allowed
- false - update not allowed
|
Requests if the subscription allows assigning the specified amounts (deltas) of resources. For example, an application can enable or disable a button on the result of the method call. |
requestUsageChange | {
deltas: [resource requests],
operations: [operations]
}
|
Deferred object. In the case of success, it returns the input object with additional limit and rateId fields.
Otherwise, it rejects the request. |
Requests the platform for the specified amounts (deltas) of resources. If the subscription limitation does not prevent it, the platform processes the required operations to assign the requested resources. Otherwise, it will propose the customer to increase the subscription limits by purchasing additional resources. The commit method is necessary to commit the requested changes. |
requestLimitsChange | {
limits: [new limits]},
operations: [operations]
}
|
Deferred object. In the case of success, it returns the input object with additional limit and rateId fields.
Otherwise, it rejects the request. |
Requests the platform to update resource limits. Each element of the limits array is an object
consisting of the resource apsType , apsProperty (for counters), apsId (for references),
and new limit . The commit method is necessary to commit the requested changes. |
commit | - |
- Promise resolved - success
- Promise rejected - failure
|
Commits the changes requested by requestUsageChange and requestLimitsChange methods.
If a view is plugged into a wizard the latter must use this method.
Otherwise, the application view must call this method itself. |
Note
1. If there were more than one aps.biz.requestUsageChange
requests for changing the same resource
in a subscription before the aps.biz.commit
method is called, the system will commit only the last request.
aps.biz.requestLimitsChange
requests.Currently, an application view plugged into the system user creation wizard can use this method to get a list of new users whom the application service must be assigned to.
The method returns an object in the form of:
{ users: [<user-1>, <user-2>,...] }
Each <user> in the list is a JSON representation of a new user in the format as in the following example:
{ "aps": {
"type":"http://parallels.com/aps/types/pa/service-user/1.2",
"id":"6bbc5494-f525-5475-c61e-de8aaf1edfd3"},
"addressPostal":{},
"locale":"en_US",
"givenName":"Andy",
"familyName":"Williams",
"email":"aw@aps.test",
"displayName":"Andy Williams",
"fullName":"Andy Williams",
"login":"aw@aps.test",
"isAccountAdmin":false
}
The following example demonstrates this method:
aps.biz.getResourcesToBind().then(function(resources) {
var users = resources.users;
// ... Assign a service to users
});
An application can request the platform for the list of resources in a subscription. Each returned resource representation contains commercial properties, such as name, limit, usage, and so on.
filter
as an array of filters and optionally subscriptonid
The getResourcesInfo
method call looks as follows:
getResourcesInfo({ filter: [<filter-1>, <filter-2>,...] },
subscriptionId: <subscription APS ID>
);
If the subscriptionId
input is missing, the method uses by default the aps.context.subscriptionId
value.
Each filter contains a named list of up to three parameters (all are optional) to filter resources:
{
apsType: "<APS type ID>",
apsProperty: "<property of the Application Counter resources>",
apsId: "<APS ID of the Application Service Reference resources>"
}
The method returns an array of resources:
[<resource-1>, <resource-2>,...]
Each resource representation complies with the following schema:
{
"apsType": { "required": false, "type": "string" },
"apsProperty": { "required": false, "type": "string" },
"apsId": { "required": false, "type": "string" },
"name": { "required": false, "type": "string" },
"min": { "type": "integer" },
"usage": { "type": "integer" },
"limit": { "required": false, "type": "integer" },
"max": { "type": "integer" },
"unit": { "required": false, "type": "enum" },
"priceText": { "required": false, "type": "string" },
"isLimited": { "type": "boolean"}, // Added by BSS
"isUpsellPossible": {"type": "boolean"} // Added by BSS
}
Property | Type | Notes |
---|---|---|
apsType |
URI | APS type ID as specified in APS Type ID |
apsId |
GUID | Unique resource ID as specified in Resources |
apsProperty |
String | Only Application Counter resource types contain this property that is the name of a
Counter structure
as specified by the core Resource APS type.The string pattern is ^[a-zA-Z_][a-zA-Z0-9_]*$.
|
name |
String | Can be localized. |
description |
String | Can be localized. |
min |
0
Positive integer
|
Specified by the respective resource rate. |
max |
0
Positive integer
undefined |
Specified by the respective resource rate. |
usage |
0
Positive integer
|
Current resource usage. |
limit |
0
Positive integer
|
Specified by the respective subscription. |
unit |
String | Can be localized. |
priceText |
String | Can be localized. |
isUpsellPossible |
Boolean | It is possible to upsell the resource in accordance with the respective resource rate. The field is added by BSS. |
isLimited |
Boolean | The resource amount is limited as specified in the subscription. The field is added by BSS. |
Note
apsId
.apsProperty
.3. priceText
is returned by the billing system. It contains
the price per a subscription period, for example ‘$4/month for 1 Additional VPS’.
limit
property only if isLimited==true
.The method filters the subscription resources using the best-match in the following order:
The following sample call must return the resource of the specified vps type and the diskspace counter specified by the context type:
aps.biz.getResourcesInfo({ filter: [{
apsType: "http://aps-demo.org/samples/basic/vps"
}, {
apsType: "http://aps-demo.org/samples/basic/context",
apsProperty: "diskspace"
}]}).then(function(resources) {
//... process the returned array
});
An application can evaluate whether the current customer is able to request the specified amount of resources.
deltas
array of requests for changeFor the current subscription, the input is an object in the following format:
{ deltas: [<request-1>, <request-2>,...] }
An AWS application can specify several subscriptions in the method call in the form of:
{
<subscriptionId-1>: { deltas: [requests] },
<subscriptionId-2>: { deltas: [requests] },
...
}
In this case, the method will return a response mapped to subscription IDs, for example:
{
<subscriptionId-1>: true,
<subscriptionId-2>: false,
...
}
Each request is an object complied with the following schema containing the filtering parameters and the requested total resource amount:
{
"apsType": { "required": false, "type": "string" },
"apsProperty": { "required": false, "type": "string" },
"apsId": { "required": false, "type": "string" },
"delta": { "type": "integer" }
}
The delta
property is the amount of the specified resource to assign.
The following example tests if the current subscription allows assigning 2 more VPSes and 50 GB of disk space:
aps.biz.canChangeUsage({deltas: [{
apsType: "http://aps-demo.org/samples/basic/vps",
delta: 2
}, {
apsType: "http://aps-demo.org/samples/basic/context",
apsProperty: "diskspace",
delta: 50
}]}).then(function() {...});
An application calls this method to request assignment of the specified resources and to request a set of operations over those resources.
deltas
array of requests for change and the operations
array of
requested operationsIn the case of success, the method returns the input object with the following additional fields:
limit
- the updated limit of the resourcerateId
- the internal ID of the updated resource in the platformFor a single subscription, the input is an object in the following format:
{
deltas: [<request-1>, <request-2>,...],
operations: [<operation-1>, <operation-2>,...]
}
An AWS application can specify several subscriptions in the method call in the form of:
{
<subscriptionId-1>: {
deltas: [<requests>],
operations: [<operations>]
},
<subscriptionId-2>: {
deltas: [<requests>],
operations: [<operations>]
},
...
}
The deltas
array and the requests inside it are of the same format as in the canChangeUsage
method.
Each request is an object complied with the following schema:
{
"apsType": { "required": false, "type": "string" },
"apsProperty": { "required": false, "type": "string" },
"apsId": { "required": false, "type": "string" },
"delta": { "type": "integer" }
}
Normally, an application calls the specified operations to implement the requested deltas
, although formally
the former are not related to the latter.
The operations are called one-by-one in the specified sequence.
An operation can be one of the following:
provision
- create a specified resource
{ "provision": { resource JSON representation } }
unprovision
- remove a specified resource
{ "unprovision": { apsId: "<resource APS ID>" } }
call
- a custom operation with the following properties:
resourceId
- APS ID of the resource to processoperation
- the operation name as declared in the resource schema (APS type)parameters
- named list of parameters to pass to the method as input argumentsNote
Currently, it works with custom operations declared in accordance with the following rules:
verb
property must be “POST”.name
must equal its path
property.kind
property is “body”.The following example illustrates how to use the method to request totally for 1 more VPS and 50 GB of additional disk space.
If the subscription allows assignment of the requested resources, the unprovision
operation
removes an old VPS and then the provision
operations create two more VPSes:
aps.biz.requestUsageChange({
deltas: [{
apsType: "http://aps-demo.org/samples/basic/vps",
delta: 1 // Totally, one more VPS is needed
}, {
apsType: "http://aps-demo.org/samples/basic/vps",
apsProperty: "diskspace", // Counter
delta: 50 // Assign 50 GB of disk space
}],
operations: [
{ unprovision: {apsId: oldVpsId} }, // Remove an old VPS
{ provision: getPlainValue(self.model.newVPS[1]) } // Create a VPS
{ provision: getPlainValue(self.model.newVPS[2]) } // One more VPS
]
})
An application uses this method to update the resource limitation in a subscription or in a set of subscriptions.
limits
array of requests for change and the operations
array of
requested operationsIn the case of success, the method returns the input object with the following additional fields:
limit
- the updated limit of the resourcerateId
- the internal ID of the updated resource in the platformFor a single subscription, the input is an object in the following format:
{
limits: [<request-1>, <request-2>,...],
operations: [<operation-1>, <operation-2>,...]
}
Normally, to apply the requested limits, the application requests some operations to be called one-by-one in the specified sequence.
An AWS application can request updates in several subscriptions in the form of:
{
<subscriptionId-1>: {
limits: [<requests>],
operations: [<operations>]
},
<subscriptionId-2>: {
limits: [<requests>],
operations: [<operations>]
},
...
}
Each request in the limits
array is an object complied with the following schema:
{
"apsType": { "required": false, "type": "string" },
"apsProperty": { "required": false, "type": "string" },
"apsId": { "required": false, "type": "string" },
"limit": { "type": "integer" }
}
The limit on the subscribed resource matching the filtering parameters will be updated to the specified limit
value.
The following example defines a function that updates a resource limit:
updateBuyAmount: function(newValue) {
if (isNaN(newValue) return;
return aps.biz.requestLimitsChange({
limits: [{
apsId: this.owcProfile.apsId,
limit: newValue + this.owcProfile.limit
}]
})
.then(null, displayError);
}
The method is necessary to commit the requests and operations specified by
the requestUsageChange
and requestLimitsChange
methods.
It does not require any input arguments.
The following example illustrates a sequence of method calls:
aps.biz.requestLimitsChange
method to determine if update of the specified limits is allowed.aps.biz.commit
method to commit the request.submit
navigation method.aps.biz.requestLimitsChange({
limits: [{
apsId: profile.aps.id,
limit: amount
}]
}).then(function() {
return aps.biz.commit();
}).then(function() {
this.submit();
},
displayError
);
When the platform contains both parts, the Operations Support System (OSS) and Business Support System (BSS), the Biz API allows operating resources only if those resources are presented in the respective service plan. A resource rate sets the lower limit, upper limit, and the included amount of the respective resource. In addition to the included amount of a resource, a customer can buy more amount of that resource. The Prepare Product Deployment Configuration and Deploy Product steps of the User Management demo illustrate configuration of resource rates.
In BSS, the provider can add a resource to one or more composite resources and then create resource rates in a service plan for those composite resources. A composite resource is a bunch of ordinary resources with respective rates. For example, the provider wants to sell mailboxes along with disk space for those mailboxes. In this case, it is possible to create several composite resources with different number of mailboxes and amount of disk space in each. A customer is able to update the limits in their subscription by purchasing one or any combination of composite resources presented by the respective resource rates in the service plan. The Customize Resource Rates (optional step) step of the User Management demo illustrates configuration of composite resources and the respective resource rates.
When an application view sends an aps.biz.requestUsageChange
or aps.biz.requestLimtsChange
request to
increase resource usage and to perform
some provisioning operations, the platform validates if the specified subscription allows that usage. If the current
limits in the subscription do not allow the request, the user panel notifies the customer about the upsell options.
For example, if the request exceeds the limit on mailboxes, the customer is able to select one of composite resources containing the mailbox resource.
The process looks as follows:
Inside the onContext
method, the aps.biz.requestUsageChange
method requests the platform if it is able to
increase the resource usage and perform the required provisioning operations in scope of a certain subscription.
Note
It is important to call the aps.biz.requestUsageChange
method inside the onContext
method. In
this case, the user panel will notify the customer about the upsell options. The customer will be able to
cancel the operation, or select another amount of the resource, or select the proper upsell option. After that,
the application will be able to call the aps.biz.requestUsageChange
method again with the updated request.
The New Users view code of the User Management demo illustrates the use of Biz APi.
The platform identifies that the request leads to exceeding the current resource limit in the specified subscription.
The platform figures out all resource rates that can increase the resource limit and prompts the customer to select and buy one of the options.
The Add Users provisioning step of the User Management demo illustrates how it looks like in user panel.
The customer selects one of the options to buy and clicks the Submit
(in a final view of a wizard or in a
standalone view) or Next
(in an intermediate view of a wizard). The respective handler calls the
aps.biz.commit
method to commit the aps.biz.requestUsageChange
request.
UX1 presents an order to purchase the selected option and the customer confirms the purchase.
The platform processes the order payment and completes the provisions operations required by the
aps.biz.requestUsageChange
method.
link
, unlink
, and unprovision
operations are not supported.requestLimitsChange
method does not function in wizards.This example illustrates how to collect commercial data about subscription resources in a model and then to sync the latter with widgets.
Declare a model containing resources filtered by various parameters. You can sync the model with widgets to visualize its contents:
var model = getStateful({
vpsOffers: {},
cpuCores: {},
memory: {}
});
Request for resources in the current subscription filtering them by various parameters and save the returned results in the model:
aps.biz.getResourcesInfo({filter: [{
apsType: "http://aps-standard.org/samples/suwizard1p/offer/1.0"
}, {
apsType: "http://aps-standard.org/samples/suwizard1p/context/1.0",
apsProperty: "cpuusagetotal"
}, {
apsType: "http://aps-standard.org/samples/suwizard1p/context/1.0",
apsProperty: "ramusagetotal"
}]
}).then(function(data) {
model.set("vpsOffers", data.reduce(function(offers, item) {
if (item.apsType === 'http://aps-standard.org/samples/suwizard1p/offer/1.0') {
offers[item.apsId] = item;
}
return offers;
}, {}));
model.set("cpuCores", data.find(function(item) {
return item.apsProperty === 'cpuusagetotal';
}));
model.set("memory", data.find(function(item) {
return item.apsProperty === 'ramusagetotal';
})));
});
The example verifies if a subscription allows assignment of the specified amount of resources.
Declare a model representing availability of resources for upgrade. You can sync the model with widgets to visualize its contents, for example to enable or disable some buttons.
var model = getStateful({
canChangeVPS: "",
canChangeOffer: ""
});
Test the possibility to assign resources filtered by various parameters and collect the returned results in the model:
var subscriptionId = aps.context.vars.context.aps.subscription;
aps.biz.canChangeUsage({
deltas: [{
apsType: "http://aps-standard.org/samples/suwizard1p/vps/1.0",
delta: 3
}]
}).then(function(result) {
model.set("canChangeVPS", result);
}, function() {
console.error("canChangeUsage by APS type failed");
});
aps.biz.canChangeUsage({
deltas: [{
apsId: "78b5e708-5f8a-431b-ba42-9eb63fa09f2e",
delta: 3
}]
}).then(function(result) {
model.set("canChangeOffer", result);
}, function() {
console.error("canChangeUsage by APS ID failed");
});
The example is typical for a view plugged into the user creation wizard. It gets a list of new
users calling the getResourcesToBind
method and requests the application service assignment to each user by
calling the requestUsageChange
method. If the request succeeds the view forwards the customer
to the next step of the wizard. Finally, the wizard must commit all aps.biz
requests for change.
aps.biz.getResourcesToBind().then(function(resources) {
var users = resources.users;
return aps.biz.requestUsageChange({
deltas: [{
apsType: "http://aps-standard.org/samples/suwizard1p/vps/1.0",
delta: users.length
}],
operations: users.map(function(user) {
return {
provision: lang.mixin(getPlainValue(self.model.data), {
user: user,
userName: user.fullName
})
};
}),
subscriptionId: aps.context.vars.context.aps.subscription
});
}).then(function() {
aps.apsc.next();
});
A custom operation that relinks a service from the current user to another one is declared as follows:
{ "operations": {
"relink": {
"path": "/relink",
"verb": "POST",
"response": {
"type": "string"
},
"parameters": {
"user": {
"kind": "body",
"required": true
}
}
}
}
Using Biz API, you can request a call for this operation as follows:
aps.biz.requestUsageChange({
deltas: [{
apsType: "http://aps-standard.org/samples/test001/vps/1.0",
delta: 1
}],
operations: [
{ call: {
resourceId: vps.aps.id,
operation: "relink",
parameters: { myuser: JSON.stringify(myUser) }
}}
});
When this request is committed, the respective REST request to the application will look as follows:
POST http://<app-end-point>/<service-id>/<vps.aps.id>/relink
{ "<myuser>" }
The example illustrates how to use the unprovision
operation in the requestUsageChange
method
to remove the selected services (VPSes) in the following order:
sel
array.deltas
as the number of the selected VPSes
and the list of unprovision
operations
.aps.biz
module for the change by calling the requestUsageChange
method.commit
method to start the requested removal of the VPSes./* The onClick handler for the "Delete" button - "this" object */
var remove = function() {
/* Get confirmation from the user for the delete operation */
if (!confirm("Are you sure you want to delete VPSes?")) {
this.cancel(); // Release the "Delete" button
return;
}
var sel = grid.get("selectionArray"); // All VPSes selected for removal
/* Clear the current messages on the screen */
page.get("messageList").removeAll();
var data = {
deltas: [{
apsType: "http://aps-standard.org/samples/suwizard1p/vps/1.0",
delta: -sel.length // Decreasing the resource amount
}],
operations: sel.map(function(vpsId) {
return {unprovision: {aps: {id: vpsId}}}; // An operation for each VPS
})
};
aps.biz.requestUsageChange(data).then(function() {
return aps.biz.commit();
}).then(function() {
grid.refresh();
}, function() {
aps.apsc.displayMessage("Resources can't be deleted");
}).always(function() {
this.cancel();
sel.set("length", 0); // Make the selected array empty
}.bind(this));
};