class FileUserGroupProvider implements ConfigurableUserGroupProvider {

    @Override
    public void onConfigured(AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
        try {
            final PropertyValue tenantsPath = configurationContext.getProperty(PROP_TENANTS_FILE);
            if (StringUtils.isBlank(tenantsPath.getValue())) {
                throw new AuthorizerCreationException("The users file must be specified.");
            }

            // get the tenants file and ensure it exists
            tenantsFile = new File(tenantsPath.getValue());
            if (!tenantsFile.exists()) {
                logger.info("Creating new users file at {}", new Object[] {tenantsFile.getAbsolutePath()});
                saveTenants(new Tenants());
            }

            final File tenantsFileDirectory = tenantsFile.getAbsoluteFile().getParentFile();

            // the restore directory is optional and may be null
            final File restoreDirectory = properties.getRestoreDirectory();
            if (restoreDirectory != null) {
                // sanity check that restore directory is a directory, creating it if necessary
                FileUtils.ensureDirectoryExistAndCanAccess(restoreDirectory);

                // check that restore directory is not the same as the user's directory
                if (tenantsFileDirectory.getAbsolutePath().equals(restoreDirectory.getAbsolutePath())) {
                    throw new AuthorizerCreationException(String.format("Users file directory '%s' is the same as restore directory '%s' ",
                            tenantsFileDirectory.getAbsolutePath(), restoreDirectory.getAbsolutePath()));
                }

                // the restore copy will have same file name, but reside in a different directory
                restoreTenantsFile = new File(restoreDirectory, tenantsFile.getName());

                try {
                    // sync the primary copy with the restore copy
                    FileUtils.syncWithRestore(tenantsFile, restoreTenantsFile, logger);
                } catch (final IOException | IllegalStateException ioe) {
                    throw new AuthorizerCreationException(ioe);
                }
            }

            // extract the identity and group mappings from nifi.properties if any are provided
            identityMappings = Collections.unmodifiableList(IdentityMappingUtil.getIdentityMappings(properties));
            groupMappings = Collections.unmodifiableList(IdentityMappingUtil.getGroupMappings(properties));

            // get the value of the legacy authorized users file
            final PropertyValue legacyAuthorizedUsersProp = configurationContext.getProperty(FileAuthorizer.PROP_LEGACY_AUTHORIZED_USERS_FILE);
            legacyAuthorizedUsersFile = legacyAuthorizedUsersProp.isSet() ? legacyAuthorizedUsersProp.getValue() : null;

            // extract any node identities
            initialUserIdentities = new HashSet<>();
            for (Map.Entry<String,String> entry : configurationContext.getProperties().entrySet()) {
                Matcher matcher = INITIAL_USER_IDENTITY_PATTERN.matcher(entry.getKey());
                if (matcher.matches() && !StringUtils.isBlank(entry.getValue())) {
                    initialUserIdentities.add(IdentityMappingUtil.mapIdentity(entry.getValue(), identityMappings));
                }
            }

            load();

            // if we've copied the authorizations file to a restore directory synchronize it
            if (restoreTenantsFile != null) {
                FileUtils.copyFile(tenantsFile, restoreTenantsFile, false, false, logger);
            }

            logger.info(String.format("Users/Groups file loaded at %s", new Date().toString()));
        } catch (IOException | AuthorizerCreationException | JAXBException | IllegalStateException | SAXException e) {
            throw new AuthorizerCreationException(e);
        }
    }

}