Skip to content
This repository has been archived by the owner on Jan 21, 2022. It is now read-only.

Commit

Permalink
Minor improvements and additions to the README and FAQ
Browse files Browse the repository at this point in the history
Minor doc consistency improvements.
Move the FAQ to its own file under doc.
Add a few useful steps to the development section.
  • Loading branch information
jsdelfino committed Oct 7, 2015
1 parent 2272036 commit 5ac78db
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 94 deletions.
161 changes: 68 additions & 93 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,77 +10,19 @@ Overview

Abacus provides usage metering and aggregation for [Cloud Foundry (CF)](https://www.cloudfoundry.org) services. It is implemented as a set of REST micro-services that collect usage data, apply metering formulas, and aggregate usage at several levels within a Cloud Foundry organization.

Abacus provides a REST API allowing Cloud service providers to submit usage data, and a REST API allowing usage dashboards, and billing systems to retrieve usage reports.

Abacus is implemented in Node.js and the different micro-services can run as CF apps.

The Abacus REST API is described in [doc/api.md](doc/api.md).
Abacus provides a REST API allowing Cloud service providers to submit usage data, and a REST API allowing usage dashboards, and billing systems to retrieve usage reports. The Abacus REST API is described in [doc/api.md](doc/api.md).

Frequently Asked Questions (FAQs)
---

1. How to get Usage Data from CF?

We are currently building a prototype for reporting CF apps usage data to Abacus. You can have a look at the [bridge source](https://github.com/cloudfoundry-incubator/cf-abacus/tree/master/lib/cf/bridge).

What we currently do is to:
* obtain oauth token
* list app usage events
* report linux-container metrics

For now we basically report the memory used.

The same approach can be applied to service usage events. However I'm not aware of any useful metrics (besides the number of instances) present in the service usage events. This is due to the fact that CF does not (and should not) have an idea what the service actually does.

Instead the service providers can report the metrics they want to charge for to Abacus. This can happen in the service broker itself or in dedicated bridge that takes care to fetch the metrics from the broker and report the usage to Abacus.

2. Is there an API to cancel or correct entries?

Our current strategy is to have the service or runtime provider submit compensating usage (e.g. if that service provider thinks it has submitted too much GB hours for example, he can always compensate that with a negative/credit usage later). If there's a mistake, it's compensated later, we don't rewrite history, for many reasons including auditing, potentially legal reasons etc...

The other thing to consider is that even if there was a way to rewrite history, that wouldn't handle the cases where the mistaken usage would have already been shown to the customer (as customers are typically able to see their usage in close to real time) or, even more difficult... the cases where that usage would have already been billed to that customer (e.g. the mistake happened on 08/31 23:30pm and only got discovered on 09/01 after a bill was produced and sent to the customer...)

3. Can one configure CF-Abacus for a trial period?

Abacus allows you to completely control how usage and costs are accumulated over time, and aggregated at various levels inside an organization using Javascript functions that you can define yourself for each resource, so yes you should be able to implement that kind of logic.

We are actually in the middle of implementing time windows (sec, min, hour, day, month, year) for usage accumulation so when that's in place it'll be even easier to do it.

Another thing to consider is that Abacus doesn't do billing/invoicing. We meter, aggregate and rate usage to produce usage and charge summary reports that can then be fed to a billing system. Your particular billing system can eventually decide to apply discounts or 'just make it free for that customer' for example on top of the usage and rating data that Abacus provided.

4. How does the report generated by the demo relate to the entered usage and rate data?

In a nutschell:

* a resource provider controls how usage is metered, accumulated, aggregated, rated, summarized and charged through a set of Javascript functions (meter, accumulate, aggregate, rate, summarize, charge) that can be configured in a resource configuration JSON doc (see examples [1][2]); these functions are called to process submitted usage as it flows through the Abacus meter, accumulator, aggregator and reporting services;

* the resource provider submits usage docs containing usage measures (e.g. number of API calls, or bytes of storage or memory);

* the resource provider's meter() function is called, given the usage measures, and is responsible for converting them to the metrics relevant for the particular resource (e.g. thousands of API calls, GB of storage, MB of memory);

* the provider's accumulate() function is called, responsible for accumulating (usually a simple sum) the particular metric over time (per sec, min, hour, day, month etc);

* the provider's aggregate() function is called next, responsible for aggregating (usually a sum as well) the particular metric at different levels under an organization;

* next, the provider's rate() function is called, responsible for computing the cost of the metric given the usage and the price of the particular metric;

* finally the summarize() and charge() functions are called to compute the final usage summary and corresponding charges, at the time the usage summary report gets produced.

* one final note, usage measures and metrics can be expressed as simple numbers (e.g. a decimal number representing a number of API calls) or compound data structures for more sophisticated usage metering schemes (e.g the ability to represent something like 'already consumed 153GB of memory and now consuming 3GB since 9:32am today'); the provider's meter, accumulate, aggregate etc functions are then free to interpret the data structure representing the metric however they want.

[1] https://github.com/cloudfoundry-incubator/cf-abacus/blob/master/lib/config/resource/src/resources/storage.js
[2] https://github.com/cloudfoundry-incubator/cf-abacus/blob/master/lib/config/resource/src/resources/container.js

5. Can we set different prices for different customers?

The pricing is currently loaded from a simple JSON configuration file, but the intent is to convert that to a service that an integrator of Abacus can implement to control what price is used for a particular resource, plan, organization, time (as prices evolve over time), country, currency etc.

That service will need to implement a REST API that Abacus will call to get the price to use to rate the usage. So, yes, with that you'll be able to return a different pricing per customer (i.e. per organization).
The Abacus FAQ can be found in [doc/faq.md](doc/faq.md).

Building
---

Abacus requires Npm >= 2.10.1 and Node.js >= 0.10.36 or io.js >= 2.3.0.
Abacus requires Npm >= 2.10.1 and Node.js >= 0.10.36.

```sh
cd cf-abacus
Expand Down Expand Up @@ -112,7 +54,7 @@ This diagram shows the main Abacus apps and their role in the processing of usag

![Abacus flow diagram](doc/flow.png)

The following steps assume a local Cloud Foundry deployment created using [Bosh-lite](https://github.com/cloudfoundry/bosh-lite) and running on the default local IP 10.244.0.34 assigned to that deployment. Please adjust to your particular Cloud Foundry deployment environment.
The following steps assume a local Cloud Foundry deployment created using [Bosh-lite](https://github.com/cloudfoundry/bosh-lite), running on the default local IP 10.244.0.34 assigned by the Bosh-lite CF installation script, and have been tested on CF v210. Please adjust to your particular Cloud Foundry deployment environment.

```sh
cd cf-abacus
Expand All @@ -122,15 +64,7 @@ cf api --skip-ssl-validation https://api.10.244.0.34.xip.io
cf login -o <your organization> -s <your space>

# Create a CF security group for the Abacus apps
cat >abacus_group.json <<EOF
[
{
"destination": "10.0.0.0-10.255.255.255",
"protocol": "all"
}
]
EOF
cf create-security-group abacus abacus_group.json
cf create-security-group abacus etc/secgroup.json
cf bind-security-group abacus <your organization> <your space>

# Run cf push on the Abacus apps to deploy them to Cloud Foundry
Expand All @@ -148,7 +82,10 @@ abacus-usage-collector started 1/1 512M 512M abacus-
abacus-usage-meter started 1/1 512M 512M abacus-usage-meter.10.244.0.34.xip.io
abacus-usage-accumulator started 1/1 512M 512M abacus-usage-accumulator.10.244.0.34.xip.io
abacus-usage-aggregator started 1/1 512M 512M abacus-usage-aggregator.10.244.0.34.xip.io
abacus-usage-rate started 1/1 512M 512M abacus-usage-rate.10.244.0.34.xip.io
abacus-usage-reporting started 1/1 512M 512M abacus-usage-reporting.10.244.0.34.xip.io
abacus-provisioning-stub started 1/1 512M 512M abacus-provisioning-stub.10.244.0.34.xip.io
abacus-account-stub started 1/1 512M 512M abacus-account-stub.10.244.0.34.xip.io
abacus-dbserver started 1/1 1G 512M abacus-dbserver.10.244.0.34.xip.io
```

Expand Down Expand Up @@ -193,10 +130,12 @@ npm run demo
npm stop
```

Meter Cloud Foundry App Usage
Meter Cloud Foundry app usage
---

Abacus comes with a [bridge](lib/cf/bridge) that acts as a Service Provider. It reads Cloud Foundry's [App Usage Events](http://apidocs.cloudfoundry.org/runtime-passed/app_usage_events/list_all_app_usage_events.html) and reports usage to the `abacus-usage-collector`. In the end it enables you to see usage reports for your Cloud Foundry instance. In order to start the bridge follow its [readme](lib/cf/bridge/README.md)
Abacus comes with a CF [bridge](lib/cf/bridge) that acts as a resource provider for Cloud Foundry app runtime usage, reads Cloud Foundry [app usage events](http://apidocs.cloudfoundry.org/runtime-passed/app_usage_events/list_all_app_usage_events.html) and reports usage to the Abacus usage [collector](lib/metering/collector).

In the end the Abacus CF bridge enables you to see runtime usage reports for the apps running on your Cloud Foundry instance. In order to start the bridge follow its [README](lib/cf/bridge/README.md).

Layout
---
Expand Down Expand Up @@ -224,14 +163,15 @@ lib/ - Abacus modules

accumulator - accumulates usage over time
aggregator - aggregates usage within an organization
rating - applies pricing to usage
reporting - returns usage reports

config/ - Usage formula configuration

rating/ - Rating services

rate - applies pricing formulas to usage
cf/ - CF platform integration

bridge - collects CF app usage data

config/ - Usage formula and pricing configuration

utils/ - Utility modules used by the above

stubs/ - Test stubs for provisioning and account services
Expand All @@ -246,44 +186,79 @@ etc/ - Misc build scripts

```

People
Developing individual Abacus modules
---

[List of all contributors](https://github.com/cloudfoundry-incubator/cf-abacus/graphs/contributors)
As shown in the above Layout section, Abacus consists of a number of Node.js modules under the [lib](lib) directory.

Development
---
When developing on Abacus you may want to quickly iterate through changes to a single module, and run the tests only for that module rather than rebuilding the whole project each time.

The Abacus project has a tree structure that can be seen above. It is a module consisting of submodules. These submodules are located under the `lib` directory. When developing locally you often need to make changes to one submodule only, build and run the tests, rather than rebuilding all submodules.
Here are the steps most of us follow when we work on a single module, using the [collector](lib/metering/collector) module as an example.

Let's take the metering collector module as an example. First you have to build all modules:
First, bootstrap your Abacus development environment:

```
```sh
cd cf-abacus
npm run build

# Setup the base Node.js tools and dependencies used by the Abacus build
npm run bootstrap
```

Then you have to install your submodule's dependencies
Then install your module's dependencies as usual with npm:

```
```sh
cd cf-abacus/lib/metering/collector
npm install
```

At this point your dev cycle boils down to:
At this point your development cycle boils down to:

```
```sh
cd cf-abacus/lib/metering/collector
npm run babel && npm run lint && npm test
```

If you want to run the collector app you can run:
# Run Babel.js to translate EcmaScript6 Javascript to ES5
npm run babel

# Run ESLint on your code and run the module's unit tests
npm test
```

To run the collector app you can do this:

```sh
cd cf-abacus/lib/metering/collector
npm start
```

To push the app to your Cloud Foundry instance, do this:

```sh
cd cf-abacus/lib/metering/collector
npm run cfpush
```

Finally, to rebuild everything once you're happy with your module:
```sh
cd cf-abacus

# Important to do at this point as the next step does a git clean
git add <your changes>

# Does a git clean to make sure the build starts fresh
npm run clean

# Build and unit test all the modules
npm run build

# Or to run what our Travis-CI build runs, including integration tests
npm run cibuild
```

People
---

[List of all contributors](https://github.com/cloudfoundry-incubator/cf-abacus/graphs/contributors)

License
---

Expand Down
1 change: 1 addition & 0 deletions doc/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
api.html
faq.html
57 changes: 57 additions & 0 deletions doc/faq.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
Frequently Asked Questions (FAQ)
===

### How does the report generated by the demo relate to the submitted usage and rate data?

A resource provider controls how usage is metered, accumulated, aggregated, rated, summarized and charged through a set of Javascript functions (meter, accumulate, aggregate, rate, summarize, charge) that can be configured in a resource configuration JSON document.

These functions are called to process submitted usage as it flows through the Abacus meter, accumulator, aggregator and reporting services in the following sequence:

- the resource provider submits usage docs containing usage measures (e.g. number of API calls, or bytes of storage or memory);

- the resource provider's meter() function is called, given the usage measures, and is responsible for converting them to the metrics relevant for the particular resource (e.g. thousands of API calls, GB of storage, MB of memory);

- the provider's accumulate() function is called, responsible for accumulating (usually a simple sum) the particular metric over time (per sec, min, hour, day, month etc);

- the provider's aggregate() function is called next, responsible for aggregating (usually a sum as well) the particular metric at different levels under an organization;

- next, the provider's rate() function is called, responsible for computing the cost of the metric given the usage and the price of the particular metric;

- finally the summarize() and charge() functions are called to compute the final usage summary and corresponding charges, at the time the usage summary report gets produced.

On a final note, usage measures and metrics can be expressed as simple numbers (e.g. a decimal number representing a number of API calls) or compound data structures for more sophisticated usage metering schemes (e.g the ability to represent something like 'already consumed 153GB of memory and now consuming 3GB since 9:32am today'); the provider's meter, accumulate, aggregate etc functions are then free to interpret the data structure representing the metric however they want.

### How to get Usage Data from CF?

We are currently building a prototype for reporting Cloud Foundry app runtime usage data to Abacus. You can have a look at the CF bridge [source](../lib/cf/bridge).

What we currently do is to:
- obtain an oauth token from CF
- list app usage events
- report linux-container metrics

For now we basically report the memory used.

The same approach can be applied to service usage events. However we're not aware of any useful metrics (besides the number of instances) present in the service usage events. This is due to the fact that CF does not know what the service actually does. Instead the service providers can report the metrics they want to charge for to Abacus. This can happen in the service broker itself or in dedicated bridge that fetches the metrics from the broker and reports the usage to Abacus.


### Is there an API to cancel or correct entries?

Our current strategy is to have the service or runtime provider submit compensating usage (e.g. if that service provider thinks it has submitted too much GB hours for example, he can always compensate that with a negative/credit usage later). If there's a mistake, it's compensated later, we don't rewrite history, for many reasons including auditing, potentially legal reasons etc...

The other thing to consider is that even if there was a way to rewrite history, that wouldn't handle the cases where the mistaken usage would have already been shown to the customer (as customers are typically able to see their usage in close to real time) or, even more difficult... the cases where that usage would have already been billed to that customer (e.g. the mistake happened on 08/31 23:30pm and only got discovered on 09/01 after a bill was produced and sent to the customer...)

### Can one configure CF-Abacus for a trial period?

Abacus allows you to completely control how usage and costs are accumulated over time, and aggregated at various levels inside an organization using Javascript functions that you can define yourself for each resource, so yes you should be able to implement that kind of logic.

We are actually in the middle of implementing time windows (sec, min, hour, day, month, year) for usage accumulation so when that's in place it'll be even easier to do it.

Another thing to consider is that Abacus doesn't do billing/invoicing. We meter, aggregate and rate usage to produce usage and charge summary reports that can then be fed to a billing system. Your particular billing system can eventually decide to apply discounts or 'just make it free for that customer' for example on top of the usage and rating data that Abacus provided.

### Can we set different prices for different customers?

The pricing is currently loaded from a simple JSON configuration file, but the intent is to convert that to a service that an integrator of Abacus can implement to control what price is used for a particular resource, plan, organization, time (as prices evolve over time), country, currency etc.

That service will need to implement a REST API that Abacus will call to get the price to use to rate the usage. So, yes, with that you'll be able to return a different pricing per customer (i.e. per organization).

2 changes: 1 addition & 1 deletion doc/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"flow.png"
],
"scripts": {
"doc": "cat api.md | mddoc >api.html",
"doc": "cat api.md | mddoc >api.html && cat faq.md | mddoc >faq.html",
"babel": "true",
"test": "true",
"lint": "true",
Expand Down
File renamed without changes.

0 comments on commit 5ac78db

Please sign in to comment.