Article Centralized File Storage

The Centralized File Storage System (CFS) is a special In-Process API that orchestrates all file management within Verint Community. It is used by plugins and external applications to interact with files (create, update, delete, retrieve, list, etc) within one or more file stores with files stored via a specific provider in one or more physical locations

When Would I use the CFS?

Oftentimes, interaction with the CFS is indirect. Uploading a file into a media gallery, for example, is an abstraction of basic CFS interaction for media galleries. Custom integrated extensions to the Verint Community platform may require a location to store files directly as part of their implementation can can interact with the CFS more directly by defining new file stores. It is also possible to change where the CFS physically stores files by implementing a custom file storage provider.

Creating New File Stores

New file stores are created by implementing the ICentralizedFileStore plugin type. See the tutorial for more details and extensions. Generally plugins or sets of plugins should only interact with file stores they directly define and any general-purpose access should be exposed as a new APIs.

Creating New File Storage Providers

The CFS can be configured to store files physically on the file system (either local or on a UNC share) or on Amazon S3 by default. New providers can be defined to enable physically storing files using other services as well. See the tutorial for more details and extensions.

CFS Concepts

File Stores

A file store is a collection of files that serve a common purpose. Examples of a file store would include user avatars, media gallery files, or widget source files. File stores are created by implementing ICentralizedFileStore and its extensions and is identified within the CFS API via its file store key, a string name that uniquely identifies the file store.

Within file stores, files are stored using a path and a file name.

The path can have multiple components, separated by periods. Paths must be between 0 and 769 characters and cannot contain characters that are invalid on Windows file systems. A path must not exist prior to being used (unlike windows file systems) and, when it contains no files, the CFS will generally remove all references to empty paths.

File names uniquely identify files within a path in a file store. File names must be between 1 and 255 characters and cannot contain characters that are invalid on Windows file systems.

File Storage Providers

A file storage provider enables the CFS to store one or more file stores at a new physical location. Verint Community, by default, has support for local filesystem storage and storage in Amazon's S3 service. New file storage providers can be created to support storing files elsewhere, if desired.

The association of a provider to one or more file stores is defined within the communityserver.config file.

Interacting With Files

Within plugins, the CFS is exposed by the CentralizedFileStorage API. This API provides events, properties and methods to:

  • Validate paths, file names, and file access
  • Retrieve file stores
  • Format paths
  • Handle file-related events
  • Generate URLs to files and determine which file is identified by a URL

Adding, updating, deleting, and retrieving files is exposed through a specific file store which is represented using a configured CFS providerfor the file store. Files retrieved from the CFS are implementations of ICentralizedFile which provides files details such as the name, URL, stream, and length.

Adding a File

Generally, you would not add a file directly to a CFS file store unless your code also defined the file store. Usually a more use-specific API is exposed on top of a file store. However, if you want to use a file store that you also defined, you can use code like the following:

ICentralizedFileStorageProvider fileStore = CentralizedFileStorage.GetFileStore("myfilestorekey");
ICentralizedFile file = null;
if (fileStore != null)
    file = fileStore.AddUpdateFile("path.to.file", "fileName.txt", new MemoryStream(System.Text.Encoding.UTF8.GetBytes("Content of the file")));

First, we retrieve the file store implementation by name (where we've first created a file store named "myfilestorekey"). If the file store can be retrieved, the result will be an ICentralizedFileStorageProvider instance. Using the fileStore instance, we can call AddUpdateFile() with a path ("path.to.file"), file name ("fileName.txt"), and content (the resulting stream of the UTF8 bytes representing "Content of the file").

Listing Files

As with adding a file, listing files is a function of the file store's implementation. To list the file we added (and any other files in the same path):

ICentralizedFileStorageProvider fileStore = CentralizedFileStorage.GetFileStore("myfilestorekey");
IEnumerable<ICentralizedFile> files = null;
if (fileStore != null)
    files = fileStore.GetFiles("path.to.file", PathSearchOption.TopLevelPathOnly);

When listing files, the GetFiles() method supports filtering to a specific path and including either files directly in that path only (PathSearchOption.TopLevelPathOnly) or all files in that path or sub-paths (PathSearchOption.AllPaths).

Deleting a File

To delete a file, again we use the file store instance:

ICentralizedFileStorageProvider fileStore = CentralizedFileStorage.GetFileStore("myfilestorekey");
if (fileStore != null)
    fileStore.Delete("path.to.file", "fileName.txt");

Note that no exception will be raised if the file doesn't exist. If the file exists, it is deleted. If it doesn't exist, the method returns normally. The Delete() method also has an override that takes no parameters or a path. When deleting without parameters, the entire file store is emptied. When deleting a path, any files matching that path as a prefix are deleted (for example, deleting the path "path.t" would delete the path "path.to" as well as "path.two", if both existed).

Generating a URL to a File

When generating a URL to a file, the use and duration of the URL should be considered. URLs can be retrieved one of three ways:

Generic URLs

Generic URLs are suitable for persisting within content for long periods of time (for example, saving to a database) and are not directly related to the currently-configured file storage provider. These URLs reference the CFS system and will redirect (either internally or via HTTP) to the currently-configured file store provider associated to the file if the accessing user has permission to access the file. To get a generic URL:

ICentralizedFileStorageProvider fileStore = CentralizedFileStorage.GetFileStore("myfilestorekey");
ICentralizedFile file = null;
string genericUrl = null;

if (fileStore != null)
    file = fileStore.GetFiles("path.to.file", "fileName.txt");
    
if (file != null)
    genericUrl = CentralizedFileStorage.GetGenericDownloadUrl(file);

Persistent URLs

Persistent URLs are suitable for persisting within dynamic content (for example, rendered to the UI, stored in a generated file, sent in an email, etc). These URLs reference the CFS provider (so they will no longer work if the provider is changed) but also bypass the processing redirect that occurs with generic URLs. To get a persistent URL:

ICentralizedFileStorageProvider fileStore = CentralizedFileStorage.GetFileStore("myfilestorekey");
ICentralizedFile file = null;
string persistentUrl = null;

if (fileStore != null)
    file = fileStore.GetFiles("path.to.file", "fileName.txt");
    
if (file != null)
    persistentUrl = CentralizedFileStorage.GetPersistentDownloadUrl(file);

Direct URLs

Direct URLs are suitable only for immediate rendering. That is, when the URL will be accessed soon. Direct URLs can include timestamps that will authorize access to the file only for a limited period of time (for example, when using a file store physically located on Amazon S3, the resulting URL will only be valid for 30 minutes). Dynamic UI rendering may use direct URLs, but otherwise, direct URLs should be avoided. A direct URL can be retrieved from the ICentralizedFile directly:

ICentralizedFileStorageProvider fileStore = CentralizedFileStorage.GetFileStore("myfilestorekey");
ICentralizedFile file = null;
string directUrl = null;

if (fileStore != null)
    file = fileStore.GetFiles("path.to.file", "fileName.txt");
    
if (file != null)
    directUrl = file.GetDownloadUrl();

Retrieving a File using its URL

When you have a URL and want to check if it is stored in the CFS, the IsCentralizedFile() and GetCentralizedFileByUrl() methods are useful:

string url = "http://example.com/cfs-file/myfilestorekey/path-to-file/fileName.txt";
ICentralizedFile file = null;

if (CentralizedFileStorage.IsCentralizedFileUrl(url))
    file = CentralizedFileStorage.GetCentralizedFileByUrl(url);

Note that these methods only work when the URL is of the generic format (see Generating a URL to a File above).