Skip to content
Pedro González Marcos edited this page Jan 12, 2024 · 2 revisions

Usage

The package provides up to three different main classes to manage pricing inside our application:

PricingContext

This abstract class is the key to manage the YAML configuration inside a spring app. It provides a set of configurable methods that need to be implemented inside a new component that extends this class to use other classes of the package. Inside your spring project, create the following component:

import io.github.isagroup.PricingContext;

@Component
public class PricingConfiguration extends PricingContext {

    @Override
    public String getJwtSecret(){
        /* This method must return the JWT secret that should be used to
        create tokens */
    }

    @Override
    public String getConfigFilePath(){
        /* This method must return the configuration file path relative to the
        resources folder */
    }

    @Override
    public Object getUserAuthorities() {
        // This method should return the object used inside the application to
        // determine the authority of the user inside the JWT.
    }

    @Override
    public Map<String, Object> getUserContext() {
        /* This method should return the user context that will be used to
        evaluate the pricing plan. It should be considered which users has
        accessed the service and what information is available. */
    }

    @Override
    public String getUserPlan() {
        /* This method should return the plan name of the current user. With
        this information, the library will be able to build the Plan object of
        the user from the configuration.*/
    }

}

By creating this component inside your project, spring will be able to use this information wherever it is needed.

The class also provides a set of methods that can be used to retrieve information about the pricing configuration anywhere in the app. By injecting the component in any class, the following methods can be used:

  • getPlanContext: Returns a Map<String, Plan> that represents the plan context that is going to be evaluated.

  • getFeatures: Returns the features declared on the pricing configuration.

  • getPricingManager: Maps the information of the YAML configuration file to a PricingManager object to easily operate with pricing properties.

PricingEvaluatorUtil

It can be used to evaluate the context of an user compared to his plan and generate a JWT with the results, using a single java method. This class consumes the information of the configured PricingContext to perform its operations.

Once a class that extends from PricingContext exists inside the spring app, PricingEvaluatorUtil can be injected in any bean by using @Autowired. Once declared, the token can be generated using the generateUserToken method anywhere. It requires no parameters and returns a String with the JWT token. This is an example:

import io.github.isagroup.PricingEvaluatorUtil;

@Component
public class MyComponent {

    @Autowired
    private PricingEvaluatorUtil pricingEvaluatorUtil;

    public String myMethod() {
        String token = pricingEvaluatorUtil.generateUserToken();
        return token;
    }
}

The class also contains a method that modifies a given JWT by changing the evaluation of the given feature by a String expression that will be evaluated on the client side of the application and returns the new version. The following snippet is an example of this method:

String token = pricingEvaluatorUtil.generateUserToken();
String newToken = pricingEvaluatorUtil.addExpressionToToken(token,
                  "feature1",
                  "userContext['feature1use'] < planContext['feature1']");

Map<String, Map<String, Object>> features = jwtUtils.getFeaturesFromJwtToken(newToken);

Considering just two NUMERIC features, this function could have generated a JWT that has the following payload:

{
  "features": {
    "feature1": {
      "eval": "userContext['feature1use'] < planContext['feature1']",
      "limit": 2,
      "used": 2
    },
    "feature2": {
      "eval": true,
      "limit": 5,
      "used": 1
    },
  },
  "sub": "admin1",
  "exp": 1687705951,
  "userContext": {
    ...
  },
  "iat": 1687705864,
  "authorities": {
    "password": "4dm1n",
    "role": "admin",
    "username": "admin1"
  },
  "planContext": {
    ...
  }
}

PricingService

This class offers a set of methods that can be used to manage the pricing configuration without manually modifying the YAML file. It can be used to retrieve, add, remove or modify plans and features.

As any other spring service, to use this class it must be injected in any bean using @Autowired. Once declared, the methods can be used to manage the pricing configuration.

Get pricing plan

Plan getPlanFromName(String name)

Return the plan of the configuration that matches the given name.

Add a plan pricing plan

void addPlanToConfiguration(String name, Plan plan)

Adds a new plan to the current pricing configuration.

Restrictions:

  • The plan must not exist in the configuration.
  • The plan must contain all the features defined in the configuration.

It is recommended to use the PricingContext.getFeatures() method to get the list of features that appear in the configuration.

Add a Feature to configuration

void addFeatureToConfiguration(String name, Feature feature)

Creates a new global feature in the pricing configuration and adds it to all the plans using its default value.

Update a Feature value type of the given Plan

void setPlanFeatureValue(String planName, String featureName, Object value)

Modifies a plan's feature value.

Restrictions:

  • The plan must exist in the PricingContext that is being used.
  • The given feature must exist in the configuration.

Update price of a Plan

void setPlanPrice(String planName, Double newPrice)

Modifies a plan's price.

Restriction:

  • Given plan must exist in the PricingContext that is being used.

Update a feature expression

void setFeatureExpression(String featureName, String expression)

Modifies a feature's expression. In order to do that,

Restriction:

  • Given feature must exist in the PricingContext that is being used.

Update type of a feature

void setFeatureType(String featureName, FeatureType newType)

Modifies a feature's type.

Restriction:

  • Given feature must exist in the PricingContext that is being used.

Update all pricing configuration

void setPricingConfiguration(PricingManager pricingManager)

Given a PricingManager writes it to the pricing configuration file.

Delete a plan from configuration

void removePlanFromConfiguration(String name)

Removes a plan from the pricing configuration.

Restriction:

  • Given plan must exist in the PricingContext that is being used.

Delete a feature from configuration

void removeFeatureFromConfiguration(String name)

Removes a feature from the pricing configuration. It also removes the feature from all the plans that include it.

Restriction:

  • Given feature must exist in the PricingContext that is being used.