How to restrict who can use the service, constrain how much they can use, and charge for use.
Managing use of the service
The simplest way to deploy the service is to let anyone in the world invoke
the createSampleResource operation (this is the default) and not to
require any account or SLA. For more advanced setups, the ability to create
new resources can be constrained in three ways:
- Use a more restrictive access policy
-
The access control settings for the service can be updated to restrict who can call the various
SOAP operations.
- Require a trade account
-
The service can be reconfigured to require a valid trade account when creating a new resource.
This requires clients to get their account approved, which depends on the access control policy of
the trade account service and on the manual checks performed when approving an account. Usage of the
service is recorded and the client can be billed. (note: the client can also use a private account service or registry, but this doesn't affect the service provider)
- Require an SLA
-
The service can be reconfigured to require a valid SLA when creating a new resource. The
SLA can be used to limit how many resources may be created, how much they can be used, and how
much the client should be charged for the usage. The client will usually require a trade account
in order to get an SLA.
These methods are described in the following sections.
Changing the service access policy
Using the web interface, go to Access control, select
http://SAMPLE/2006/SampleServiceResourceType and then select
service:sample.SampleService to change the access rules for the service. This can be used to restrict use of the service
to a certain list of people, or only to people whose certificates are signed by
a particular CA, etc.
When changing the policy using the web interface there are three process roles to which you
can control access: the service-admin role controls who can read the Atom feed of
events from the service, the managing-service role must be held only by the SLA service
(if any) in order to get usage reports, and the world role grants access to all remaining
operations. However, we can add new roles to provide more fine-grained access.
To control access to operations which don't take a context, download and edit
SampleServiceResourceType (not SampleResourceType, which we edited before). Change the process role needed to invoke
createSampleResource to resource-creator and redeploy the service policy (in the same
way as you redeployed the resource policy above). The administration interface's drop-down role menu
will now include the new process role, which you can use to control who can create resources.
Consult the PBAC administrator's guide for more information on controlling
the service policy.
Requiring a trade account
The service can be reconfigured to require a valid trade account when creating a new resource.
This requires clients to get their account approved, which depends on the access control policy of
the trade account service and on the manual checks performed when approving an account. Usage of the
service is recorded and the client can be billed.
Go to the administration page for the sample service and remove the Free entry from the
Trusted management service table. Add the endpoint address of your GRIA trade account
service in its place (note that the default is to add an SLA service, so you'll need to change SLAService to TradeAccountService in the form). Using the client, you should now find that you need an account to create new resources. You can either add an account to the client, or use a client management service. Consult
the GRIA client documentation for details about setting this up.
By default, your account is billed only when creating a new resource, but billing can be added in
other places too. For example, to charge the user for calling the new
check operation, modify the new check function in sample/service/src/java/sample/impl/SampleResourceImpl.java as follows:
SampleResourceBean resource = getResource(session, conversationID);
Conversation managingConversation = getManagingConversation(resource);
if (managingConversation instanceof TradeAccountConversation) {
TradeAccountConversation account = (TradeAccountConversation) managingConversation;
account.bill(getCurrentUser().toID(),
new BigDecimal(1.0), "EUR",
conversationID,
"Invoked check()");
}
Transaction tx = session.beginTransaction();
Notice that we check whether the managing conversation is a trade account. If the resource was created
when the service was free, or using an SLA, then this code will be skipped. The arguments to bill are
the name of the user, the amount to charge, and some information for the
statement (a message and the sample resource's ID).
The bill method does not check against the user's credit limit, since it is typically used after an
expensive operation has already been performed. Use the checkCreditAvailable operation to decide
whether to go ahead with something.
The bill method also does not check that the user has access to the account (although this is checked when the sample resource is created, of course). This is because clients with
access to an account may delegate to other clients who do not have access
(the original client has to pay for the new client's use in this case). Use
checkUser if you wish to check whether the invoking client has
permission to use the account directly.
After recompiling and deploying the new war, and calling check with the client on a
resource managed using a trade account, you should see the usage recorded on your bill:
Requiring an SLA
Managing the sample resources using a trade account, as described above,
provides only limited control of your clients' usage. For maximum
flexibility, the service can be managed using an SLA service instead.
To do this, go to the administration page for the sample service and remove
any existing entries from the Trusted management service table. Add
the endpoint address of your GRIA 5 SLA service in its place. You may be prompted
to set up an access control rule to grant the SLA service access. Using the
client, you should now find that you need an SLA to use the service.
You can either add an SLA to the client directly, or use a client management
service. Consult the GRIA client documentation for details about setting
this up.
When a client tries to create a resource, the sample service calls startActivity
on the SLA provided to decide whether the operation should be permitted (in the
checkCreationOK method in sample/service/src/java/sample/impl/SampleServiceImpl.java):
sla.startActivity(epr,
new Constraint[]{
// SLA must allow a new activity
new Constraint(Metric.CURRENT_ACTIVITIES, UsageType.INSTANTANEOUS, Bound.EQ, 1, now),
// SLA must allow a new sample resource
new Constraint(METRIC_SAMPLE_RESOURCES, UsageType.INSTANTANEOUS, Bound.EQ, 1, now),
},
new UsageReport[] {
new UsageReport(epr, Metric.CURRENT_ACTIVITIES, UsageType.INSTANTANEOUS, now, null, 1),
new UsageReport(epr, METRIC_SAMPLE_RESOURCES, UsageType.INSTANTANEOUS, now, null, 1)
});
This says that the new sample resource will require exactly one 'activity' and exactly
one 'sample resource'. Although a sample resource is a type of activity, the SLA service
doesn't understand this relationship, so we request both. This allows the service administrator
to write SLAs that constrain on either.
We also provide a set of usage reports telling the service what we are actually using now. In our case,
the current usage (one activity and one sample resource) is the same as the levels set in the constraints.
In other cases it may be different. For example, a job service may require "more than ten CPU seconds"
available on the SLA, even though none have been used when the job is created.
If the startActivity operation succeeds then we go ahead with any initialisation of the resource.
When a sample resource is destroyed we send similar reports indicating that usage of activities and sample
resources has dropped to zero (again, in the context of this single resource) in SampleResourceImpl.destroy:
service.pullPoint.addInstantaneousUsageReport(epr, SampleServiceImpl.METRIC_SAMPLE_RESOURCES, 0.0);
service.pullPoint.addInstantaneousUsageReport(epr, Metric.CURRENT_ACTIVITIES, 0.0);
Note: in fact, only CURRENT_ACTIVITIES needs to be set in this case. The SLA service knows that when this falls to zero the activity no longer exists, and all other usage is also zero.
The messages aren't sent immediately, but are queued. After a couple of minutes, the SLA service
will fetch all the messages at once. Note that you must give the SLA service the managing-service
role on the service:sample.SampleService service object in order for it to be able to get
these messages.
You should configure your service to create a rule in this group for the service provider automatically.
This can be done by modifying SampleServiceImpl's ensurePoliciesDeployed() method as follows:
public void ensurePoliciesDeployed() throws GridFailureException {
/* This is called by the web administration code when viewing the main admin page.
* Deploy any PBAC policies and resources we need.
*/
// This policy protects operations in the SampleService interface
PBACUtils.ensureDeployed(SampleService.SAMPLE_SERVICE_RESOURCE_TYPE, "sample-service-policy.xml");
GroupUtils.ensureGroupDeployed(TrustedManagementServices.MANAGEMENT_SERVICES_GROUP, new MatchRule[] {
new MatchRule(getServiceProviderID(), getServiceProviderIssuer(), PDP.GROUP_MEMBER_ROLE)});
// This policy protects operations in the Sample interface
PBACUtils.ensureDeployed(SampleResource.SAMPLE_RESOURCE_TYPE, "sample-policy.xml");
// This object represents the service itself. It will be the only resource of this type.
PBACUtils.ensureServiceResource(this, new MatchRule[] {
MatchRule.createAnyoneRule("world"),
new MatchRule(TrustedManagementServices.MANAGEMENT_SERVICES_GROUP,
TrustedManagementServices.MANAGEMENT_ROLE,
false)
});
}
The two metrics used above are very simple as they only take the values of zero or one. The SLA
service aggregates them across all activities within the user's SLA to work out the total bill. It
may also invoke the destroy operation on sample resources itself if the limits of the SLA are
exceeded and the service provider is running out of capacity. The total number of sample resources
permitted across all SLAs may be set by adding a METRIC_SAMPLE_RESOURCES metric to the SLA service's
capacity XML document. Pricing terms and limits for individual SLAs may be set by creating new SLA
templates in the SLA service. Consult the SLA service's documentation for further information.
Often, more complex metrics are needed, and usage rates change during the lifetime of a resource.
For example, each GRIA data stager has a metric recording the number of bytes stored within the stager
(which changes on each upload or delete operation) and another metric recording the total number of bytes
transferred. In this case, additional rate reports are added in the appropriate
operations. For example, here is an extract from the data service's
save operation:
pullPoint.addCumulativeUsageReport(getEPR(stager), Metric.DATA_TRANSFER, (double) fileBytes);
pullPoint.addInstantaneousUsageReport(getEPR(stager), Metric.DISC, (double) fileBytes);
The difference between these two is that DATA_TRANSFER is charged at the point when
it happens (addCumulativeUsageReport increases the current total), whereas DISC
sets a new level of usage (addInstantaneousUsageReport); the longer
the data is stored, the more the client pays.