Tenant Based Usage Collection
In order for CPBM to accurately bill a customer for usage of resources from an underlying cloud service, CPBM needs to periodically collect usage from the cloud service and be able to understand and mediate it. Mediation is the process by which CPBM identifies the product corresponding to usage received from an underlying cloud service. CPBM does this based on a set of mediation rules attached to a product. A usage record is matched to a product based on its usage type and matching discriminator values between what is collected for the usage record and what is specified in a mediation rule for the product.
As described earlier, in order for this to happen, CPBM periodically collects usage in a well-defined format that is understood by CPBM's mediation engine. It is the responsibility of the Usage collector implementation to transform usage from the underlying resource to the standard format recognized by CPBM. Connectors can split collecting usage by tenant, to help improve performance and efficiency. This collector is designed to support regular metered and discrete usage types. A discrete usage type generates only whole number usage. An example of the discrete usage type is a mailbox, which will be billed for the whole billing period even though it is used partially. This is a crucial difference between metered usage type and discrete usage type.
A connector must implement a Tenant Based Usage collector for its underlying cloud service. The connector (i.e., the Usage collector implementation) shall return usage in terms of UsageData objects. Each UsageData object describes a distinct usage record and should include values for all discriminators described in the product metadata (this includes resource type, filter, and additional discriminator values).
UsageData
public class UsageData { /* the usage type for this resource. Should match the type specified in the metadata */ String getUsageType(); /* The tenant handle if any. Should match the handle for owning tenant associated in the account lifecycle handler */ String getTenantHandle(); /* The user handle if any. Should match the handle for the owning user associated in the user lifecycle handler */ String getUserHandle(); /* The resource handle, if any. Should match the handle for this tenant associated in the subscription lifecycle handler */ String getResourceHandle(); /* Start date/time for this usage record */ Date getStartDate(); /* End Date/Time for this usage record */ Date getEndDate(); /* service specific reference id for this usage record. This should be the same format used by the markers. */ String getReferenceId(); /* Discriminator values for *all* declared discriminators for this usage. This includes resouce type ids, filter values and other discriminators declared for this usage type in the metadata */ Map<String, String> getDisriminators (); /* Raw usage. Actual usage consumed, in the unit of measure described in metadata */ Double getUsage(); }
TenantBasedUsageCollector
- collect(...) - This method is called all the time for usage collection, except at the beginning of the billing period for the tenant given
- inventory(...) - This method is only called at the beginning of a billing period for the given tenant.
public interface TenantBasedUsageCollector { public UsageResultSet collect(Tenant tenant, String startMarker, Date endDate); public UsageResultSet inventory(Tenant tenant, String startMarker, Date billingPeriodStartDate); }
- should start from after the startMarker and it must be generated on or before the passed endDate. For better performance, we recommend all implementations of the UsageCollector return usage data in small batches. The batch size should typically be in hundreds. Any subsequent call to UsageCollector.collect() should return the next batch of usageData. In case there is no usageData left, return UsageResultSet with the input startMarker as the marker and null usageData list. CPBM will continuously call UsageCollector.collect() for a given endDate, until all data is exhausted for this time range.
- In case of conflicting usageData (i.e., duplicate referenceId) CPBM will resolve the conflict by using the first record received.
- The UsageResultSet object contains List of UsageData. This list should be sorted by UsageData.endDate from oldest to newest. Also, for any two calls to UsageCollector.collect, all of UsageData collected in the later call should be newer (have later UsageData.endDate, than the data collected in the earlier call).
Collect method
com.citrix.cpbm.platform.model.UsageResultSet collect(com.vmops.model.Tenant tenant, java.lang.String startMarker, java.util.Date endDate) throws UsageCollectionException
- Parameters:
- tenant - Tenant object for which usage needs to collected
- startMarker - marker information specific to an implementor, which could be used to mark the boundary for usage collected so far and helps define starting point for usage to be collected. For example, time last collected.
- endDate - time up to which billing needs to be collected. This will always be the previous evening 23:59:59
- Returns: UsageResultSet - Consist of lastMarker and UsageData list
- Throws: UsageCollectionException
Inventory method
- metered usage types, this could be the same as the collect(Tenant, String, Date) call
- discrete usages, this could be used to recalculate stocks in the inventory
com.citrix.cpbm.platform.model.UsageResultSet inventory(com.vmops.model.Tenant tenant, java.lang.String startMarker, java.util.Date billingPeriodStartDate) throws UsageCollectionException
- Parameters:
- tenant - Tenant object for which usage needs to collected
- startMarker - marker information specific to an implementor, which could be used to mark the boundary for usage collected so far and helps define starting point for usage to be collected. For example, time last collected.
- billingPeriodStartDate - the start date of the current billing period for the tenant
- Returns: UsageResultSet - Consist of lastMarker and UsageData list
- Throws: UsageCollectionException
Comments