-
Notifications
You must be signed in to change notification settings - Fork 3
Open
Description
Given the following Pricing2Yaml file:
syntaxVersion: 2.1
saasName: PetClinic SaaS
createdAt: "2025-04-21"
version: "1.0.0"
currency: EUR
features:
hotel:
description: Acceso al hotel de mascotas
valueType: BOOLEAN
defaultValue: false
expression: planContext['features']['hotel']
type: DOMAIN
adoptions:
description: Acceso al sistema de adopciones
valueType: BOOLEAN
defaultValue: false
expression: planContext['features']['adoptions']
type: DOMAIN
onlineConsultation:
description: Consultas online con veterinarios
valueType: BOOLEAN
defaultValue: false
expression: planContext['features']['onlineConsultation']
type: DOMAIN
pets:
description: Control de mascotas por usuario
valueType: BOOLEAN
defaultValue: true
expression: userContext['pets'] < planContext['usageLimits']['maxPets']
type: DOMAIN
visits:
description: Control de número de visitas por mes
valueType: BOOLEAN
defaultValue: true
expression: userContext['monthlyVisits'] < planContext['usageLimits']['maxVisits']
type: DOMAIN
usageLimits:
maxPets:
description: Número máximo de mascotas por usuario
valueType: NUMERIC
defaultValue: 50
unit: pet
type: NON_RENEWABLE
linkedFeatures: [pets]
maxVisits:
description: Número máximo de visitas por mes
valueType: NUMERIC
defaultValue: 100
unit: visit
type: NON_RENEWABLE
linkedFeatures: [visits]
plans:
BASIC:
description: Plan gratuito sin SLA
price: 0.0
unit: user/month
features:
hotel: { value: false }
adoptions: { value: false }
onlineConsultation: { value: false }
usageLimits:
maxPets: { value: 50 }
maxVisits: { value: 100 }
GOLD:
description: Plan con soporte extendido y servicios adicionales
price: 5.0
unit: user/month
features:
hotel: { value: true }
adoptions: { value: true }
onlineConsultation: { value: false }
usageLimits:
maxPets: { value: 200 }
maxVisits: { value: 400 }
PLATINUM:
description: Plan premium con todas las funcionalidades y SLA completo
price: 10.0
unit: user/month
features:
hotel: { value: true }
adoptions: { value: true }
onlineConsultation: { value: true }
usageLimits:
maxPets: { value: 100000 } # equivalente a "ilimitado"
maxVisits: { value: 100000 }And the follwing dummy implementation of PricingContext interface (Notice the empty map of getUserContext):
package org.springframework.samples.petclinic.configuration;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.samples.petclinic.owner.Owner;
import org.springframework.samples.petclinic.user.User;
import org.springframework.samples.petclinic.user.UserService;
import org.springframework.stereotype.Component;
import io.github.isagroup.PricingContext;
@Component
public class PricingConfiguration extends PricingContext {
@Autowired
private UserService userService;
@Value("${petclinic.app.jwtSecret}") private String secret;
@Override
public String getJwtSecret() {
return secret;
}
@Override
public String getConfigFilePath() {
return "pricing/pricing.yml";
}
@Override
public Map<String, Object> getUserContext() {
Map<String, Object> userContext = new HashMap<>();
// Add the logic to retrieve all the data needed within the user context,
// such as his current usage of the feature XXX.
return userContext;
}
@Override
public String getUserPlan() {
try{
// Get the current user from the context
User user = userService.findCurrentUser();
Owner owner = userService.findOwnerByUser(user.getId());
return owner.getClinic().getPlan().toString();
} catch (Exception e) {
// Handle the case where the user is not found or any other exception
return "BASIC";
}
}
}Doing any call to some endpoint of an API, take as an example Petclinic endpoint
POST http://example.org/api/v1/pets
Content-Type: application/json
Accept: application/json
uthorization: Bearer {{login.response.body.$.token}}
//Pricing-Token: {{login.response.body.$.pricingToken}}
{
"id": null,
"name": "Example",
"birthDate": "2025-03-27",
"type": {
"id": 5,
"name": "bird"
},
"owner": {}
}The filter RenewTokenFilter surprisingly answers with a Pricing-Token:
Pricing-Token: eyJhbGciOiJIUzUxMiJ9.eyJmZWF0dXJlcyI6eyJwZXRzIjp7ImV2YWwiOnRydWUsInVzZWQiOm51bGwsImxpbWl0IjoxMDAwMDB9LCJhZG9wdGlvbnMiOnsiZXZhbCI6dHJ1ZSwidXNlZCI6bnVsbCwibGltaXQiOm51bGx9LCJ2aXNpdHMiOnsiZXZhbCI6dHJ1ZSwidXNlZCI6bnVsbCwibGltaXQiOjEwMDAwMH0sImhvdGVsIjp7ImV2YWwiOnRydWUsInVzZWQiOm51bGwsImxpbWl0IjpudWxsfSwib25saW5lQ29uc3VsdGF0aW9uIjp7ImV2YWwiOnRydWUsInVzZWQiOm51bGwsImxpbWl0IjpudWxsfX0sInN1YiI6IkRlZmF1bHQiLCJleHAiOjE3NDU1MDIwMTIsInVzZXJDb250ZXh0Ijp7fSwiaWF0IjoxNzQ1NDE1NjEyLCJwbGFuQ29udGV4dCI6eyJuYW1lIjoiUExBVElOVU0iLCJkZXNjcmlwdGlvbiI6IlBsYW4gcHJlbWl1bSBjb24gdG9kYXMgbGFzIGZ1bmNpb25hbGlkYWRlcyB5IFNMQSBjb21wbGV0byIsInByaWNlIjoxMC4wLCJ1bml0IjoidXNlci9tb250aCIsImlzUHJpdmF0ZSI6ZmFsc2UsImZlYXR1cmVzIjp7InBldHMiOnRydWUsImFkb3B0aW9ucyI6dHJ1ZSwidmlzaXRzIjp0cnVlLCJob3RlbCI6dHJ1ZSwib25saW5lQ29uc3VsdGF0aW9uIjp0cnVlfSwidXNhZ2VMaW1pdHMiOnsibWF4VmlzaXRzIjoxMDAwMDAsIm1heFBldHMiOjEwMDAwMH19fQ.UOLBaz7CVGbVG5cIv2FsovCQVsY25M54C9C5asP03dPNHHypX43lrPtbzSId0n3K0WUkZHAtRXnKKqxF0QAIFwFurther investigation needs to be done. This is a remainder for mantainers
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels