How does Milestone’s cache of a users’ personal ACM config work? Right now it seems sporadic… How long is the cache kept for? Is there any way to force it to fetch a new config before it expires? Etc.
I’m running into an issue with my plugin because if I change a users’ permission level in the access control system (ie what doors they are allowed to see/open), which doesn’t change the global ACM config (ie if I refresh the config from mgmt client it says no changes), that change is not visible in the smart client for the user until the cache is expired.
A user’s personal ACM config is saved in the “%ProgramData%\Milestone\XProtect Event Server\config\data” folder. There is a config file for each user. The config filename is a GUID, which corresponds to a key in an internal dictionary. The dictionary maps the GUID (and so the file) to a personalized users configuration.
The user itself, and the users personalized configuration file will not be created unless there is a login request for it. For example, a Smart Client login after you have enabled the “Operator login required” option in the Management Client. Once the user configuration is created, it is added to an internal cache, which has a 30 min cache expiration time. The cache itself can only be reset by restarting the Event Server.
However, changes to a user’s personalized configuration (i.e. what doors they are allowed to see/open) trigger a refresh of that user’s data, no matter the user’s state in the cache. So you should be able to see the changes almost immediately when you do a change in the ACM. I have checked this with the DemoAccessControlPlugin project in the MIP samples, and I get the updates immediately. The sample contains a full implementation, and should be a good source of inspiration for your own plugin.
As a starting point, please check the following in the implementation of your plugin:
The “PersonalizedLoginSupported” property is overwritten and returns “true”.
The “FirePersonalizedConfigurationChanged” event is triggered with the correct username when an ACM user’s personalized config changes.
The “StartFetchPersonalizedConfiguration” method is implemented and returns “true”; at least one FireFetchPersonalizedConfigurationStatusChanged is triggered. The last FireFetchPersonalizedConfigurationStatusChanged that you triggered must be passed an instance of ACFetchPersonalizedConfigurationStatusChangedEventArgs which must contain a valid ACConfiguration.
Also, please debug into your plugin code, and check if the StartFetchPersonalizedConfiguration method is at any point called.
Thanks for the information! My plugin is working (smart client login works), this is just a caching issue.
The problem is not all access control systems provide an event for configuration changes. So if a users’ permission changes then we get nothing. I have the same issue with the photo caching, there is no way to get a notification when a photo changes so we have to wait for that cache to expire or restart the event server.
For my purposes, if I fire the FirePersonalizedConfigurationChanged event from inside of my ValidateUserCredentials method it will at least refresh the config every time a user logs in.
I did put some debugging in and noticed the event server calls my ValidateUserCredentials method on a regular basis (every four minutes while logged into smart client). Could you explain the purpose of this? I’d rather not force the config to refresh every four minutes when someone is logged in.
If the access control system does not provide an event for users’ permission changes, then there’s not a lot to do from the MIP side, other than some workarounds, which may not be desirable / doable:
Keep a local cache of (some) users in your own integration plugin, and periodically download the user information from the ACM system. Compare the two, and fire event as needed
Periodically fire the FirePersonalizedConfigurationChanged event based on a timer
The ValidateUserCredentials method gets called regularly by the smart client as part of a heartbeat event. The heartbeat is there to keep the personalized user session alive – i.e. prevent cache flushing for as long as this particular AC user is logged in to the Smart Client
Oh… so you’re saying that the heartbeat prevents the cache from expiring (so it won’t be refreshed after 30 minutes)?
I’ll have to get a little more complicated and maybe fire the FirePersonalizedConfigurationChanged event from ValidateUserCredentials, but only if that user’s config hasn’t been fetched in the last… say 15 minutes.