Здравствуйте.
Ситуация следующая: есть композитный проект, состоящий из нескольких аддонов. Идея заключается в том, что все аддоны создают разные entity в одном общем main datastore. И один из аддонов содержит конфигурацию ограничивающую количество записей в бд которые может создать пользователь. При этом нужно избежать перекрестных связей между аддонами (по этому идея с созданием анотации уровня entity отпала)
Есть 3 идеи которые позволяют это сделать. И хотелось бы узнать какой вариант предпочтительней или может быть стоит это сделать как-то по другому.
- имплементировать спринговый ApplicationListener c EntitySavingEvent публикуемый JpaDataStore
@Component("lic_AppListenerImpl")
public class AppListenerImpl implements ApplicationListener<EntitySavingEvent>, LicenseConfig {
@Autowired
private LicenseConfigCache licenseConfigCache;
@Autowired
private LicenseAccessService licenseAccessService;
@Autowired
private CurrentUserSubstitution substitution;
@Autowired
private DataManager dataManager;
@Autowired
private Metadata metadata;
@Override
public void onApplicationEvent(EntitySavingEvent event) {
if(event.isNewEntity()) {
MetaClass metaClass = metadata.getClass(event.getEntity());
if(!checkLicenseAccess(metaClass)) {
throw new LicenseException(String.format("Your license does`nt allow to create more objects of type: %s", metaClass.getName()));
}
}
}
private boolean checkLicenseAccess(MetaClass metaClass) {
if(freeAccess(metaClass)) {
return true;
}
String entityName = metaClass.getName();
LoadContext<?> loadContext = new LoadContext<>(metaClass);
long storeCount = dataManager.getCount(loadContext);
User user = (User) substitution.getEffectiveUser();
String owner;
if(user.getAuthorities().stream().anyMatch(authority -> authority.getAuthority().equals("ROLE_system-full-access"))) {
owner = "admin";
} else {
owner = user.getTenant();
}
return licenseAccessService.isAccessGranted(licenseConfigCache.getLicenseCache(), owner, entityName, (int)storeCount);
}
}
- Расширить DataStoreCrudListener и добавить свою проверку в метод beforeEntitySave
public class DataStoreCrudListenerExt extends DataStoreCrudListener implements LicenseConfig {
@Autowired
private LicenseConfigCache licenseConfigCache;
@Autowired
private LicenseAccessService licenseAccessService;
@Autowired
private CurrentUserSubstitution substitution;
@Autowired
private DataManager dataManager;
@Override
public void beforeEntitySave(DataStoreBeforeEntitySaveEvent event) { ......
}
- имплементировать DataStoreCustomizer , зарегистрировать свой лисенер и внутри него обрабатывать DataStoreEntitySavingEvent
@Component("lic_JpaDataStoreCustomizerExt")
@Order(JmixOrder.HIGHEST_PRECEDENCE)
public class JpaDataStoreCustomizerExt implements DataStoreCustomizer {
@Autowired
private CustomCrudListener customCrudListener;
@Override
public void customize(DataStore dataStore) {
if (dataStore instanceof JpaDataStore) {
AbstractDataStore abstractStore = (AbstractDataStore)dataStore;
abstractStore.registerInterceptor(this.customCrudListener);
}
}
}
@Component("lic_CustomCrudListener")
public class CustomCrudListener implements DataStoreEventListener {
@Override
public void beforeEntitySave(DataStoreBeforeEntitySaveEvent event) {
event.getSaveContext();
}
}