Skip to main content
Version: 2.0.1

Feature Evaluation

Since the primary goal of the Pricing4Java is to automatically manage the access of an user to a feature, Pricing2Yaml allows to define an evaluation expression within each feature through the expression and serverExpression fields.

The expression field must contain a string SPEL expression that will be used to evaluate wether the feature is available for an user or not. It can access the data of the user context using the userContext variable, while the plan's is available through planContext.For example, considering a user context that contains the following information:

{
"username": "John",
"feature1use": 2
}

If we want to check if the use of the feature exceeds its limit, the SPEL expression should be:

# ...
feature1:
description: ""
valueType: NUMERIC
defaultValue: 10
type: DOMAIN
expression: userContext['feature1use'] < planContext['features']['feature1']
serverExpression: userContext['feature1use'] <= planContext['features']['feature1']
# ...
info

As the planContext utilized within the expression repressents as a map the current plan of the user, you should be aware of using either features or usageLimits to access the atribute you want to evaluate. The features key will have the value or defaultValue of the feature with the given key, while usageLimits will return the equivalent of a declared usage limit.

Similarly, the serverExpresion field can handle expressions with the same syntax, but its specification will only be used to evaluate the system's consistency using @PricingPlanAware annotation. This use can be interesting on NUMERIC features, let's see an example.

If we have a button on the UI to add items to a list, it should be only available while the amount of products is under the feature limit, so when it is reached, the button disapears. The expression that models this behaviour will be the following:

# ...
feature1:
# ...
expression: userContext['feature1use'] < planContext['features']['feature1']
# ...

However, on the server side, we should consider that the application has a valid state if the limit is not exceeded, which is evaluated with the following expression:

# ...
feature1:
# ...
serverExpression: userContext['feature1use'] <= planContext['features']['feature1']
# ...

To handle this type of situations, the use of the field serverExpression is necessary, as its expression will be used to evaluate the feature on the server side (when using @PricingPlanAware annotation). If serverEspression is not defined, the expression will be used instead on any evaluation context. The snippet below shows how to define the situation described above:

# ...
feature1:
# ...
expression: userContext['feature1use'] < planContext['features']['feature1']
serverExpression: userContext['feature1use'] <= planContext['features']['feature1']
# ...
warning

About SPEL

In SPEL if you access a key that doesn't exist will be null by default. In our expression:

userContext['feature1uses'] <= planContext['features']['feature1']

will be substituted with

# userContext['feature1uses'] doesn't exist, I misspell it so null
# planContext['features']['feature1'] is equal to 10

null <= 10

The latter expression will evaluate to false meaning that feature1 will always be DISABLED

Conclusions

  • Double check the writting of expressions in your yaml, look for misspellings and access the correspoding section of planContext which are features or usageLimits
  • Keep in sync the yaml and the Java map that you pass in the PricingConfiguration.java file