<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>Managing Physical File Storage</title><link>https://community.telligent.com/community/11/w/developer-training/65120/managing-physical-file-storage</link><description /><dc:language>en-US</dc:language><generator>14.0.0.586 14</generator><item><title>Managing Physical File Storage</title><link>https://community.telligent.com/community/11/w/developer-training/65120/managing-physical-file-storage</link><pubDate>Tue, 04 Aug 2020 21:55:57 GMT</pubDate><guid isPermaLink="false">526ce0d7-4b48-49b6-aad2-7fc7347892bd</guid><dc:creator>Former Member</dc:creator><comments>https://community.telligent.com/community/11/w/developer-training/65120/managing-physical-file-storage#comments</comments><description>Current Revision posted to Developer Training by Former Member on 08/04/2020 21:55:57&lt;br /&gt;
&lt;p&gt;The Verint Community platform&amp;#39;s [[Centralized File Storage|Centralized File Storage System]] abstracts physical file storage from [[Interacting With Files|logical file storage]] and includes support for physically storing files on the operation system&amp;#39;s file system or Amazon S3. Additional physical file storage providers can be added to support storing files elsewhere.&lt;/p&gt;
&lt;p&gt;[toc]&lt;/p&gt;
&lt;h2&gt;&lt;a id="Why_Should_I_Create_a_New_File_Storage_Provider" name="Why_Should_I_Create_a_New_File_Storage_Provider"&gt;&lt;/a&gt;Why Should I Create a New File Storage Provider?&lt;/h2&gt;
&lt;p&gt;A new file storage provider should only be required to physically store files on a new physical technology or service. Verint Community includes support for operating system file storage (local hard drive or UNC share) and Amazon S3. If another storage system, for example, a different cloud storage provider must be used, a new file storage provider can be used and configured to be used by [[Centralized File Storage|the centralized file system]].&lt;/p&gt;
&lt;h2&gt;&lt;a id="File_Storage_Provider_Considerations" name="File_Storage_Provider_Considerations"&gt;&lt;/a&gt;File Storage Provider Considerations&lt;/h2&gt;
&lt;p&gt;When developing new file storage providers, it is important to ensure that [[Centralized File Storage|CFS]] expectations are supported. Key considerations include:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The provider implementation must have a public, parameterless constructor.&lt;/li&gt;
&lt;li&gt;File store keys must be between 1 and 255 characters (each character must be supported by the Windows file system)&lt;/li&gt;
&lt;li&gt;Paths must be between 0 and 769 characters (each character must be supported by the Windows file system)&lt;/li&gt;
&lt;li&gt;File names must be between 1 and 255 characters (each character must be supported by the Windows file system)&lt;/li&gt;
&lt;li&gt;Paths should be considered as prefixes, not delimited &amp;quot;folders&amp;quot; when searching for sub-folders.&lt;/li&gt;
&lt;li&gt;Paths created with the &lt;code&gt;AddPath()&lt;/code&gt; method are expected to be returned by &lt;code&gt;GetPaths()&lt;/code&gt; calls even if the path contains no files.&lt;/li&gt;
&lt;li&gt;The provider is responsible for removing unused paths if a physical representation of the path (without respect to files) is required by the underlying physical implementation.&lt;/li&gt;
&lt;li&gt;The provider is responsible for checking permissions on secured file stores ([[api-documentation:ISecuredCentralizedFileStore Plugin Type|ISecuredFileStore]] and [[api-documentation:IGloballySecuredCentralizedFileStore Plugin Type|IGloballySecuredFileStore]]) before serving files (if the provider serves files directly).&lt;/li&gt;
&lt;li&gt;The provider is responsible for interacting with &amp;quot;findable&amp;quot; file stores when a file cannot be found when serving file contents ([[api-documentation:IFindableCentralizedFileStore Plugin Type|IFindableCentralizedFileStore]]).&lt;/li&gt;
&lt;li&gt;The provider is responsible for providing an implementation of [[api-documentation:ICentralizedFile Plugin Supplementary Type|ICentralizedFile]] for files returned by the provider which includes a full implementation, including a custom, direct HTTP handler for the &lt;code&gt;GetDownloadUrl()&lt;/code&gt; result.&lt;/li&gt;
&lt;li&gt;Any [[api-documentation:ICentralizedFile Plugin Supplementary Type|ICentralizedFile]] instances returned must exist in underlying storage. &amp;nbsp;If the files does not exist, a null value must be returned.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;&lt;a id="Provider_Interface_Types" name="Provider_Interface_Types"&gt;&lt;/a&gt;Provider Interface Types&lt;/h2&gt;
&lt;p&gt;File storage providers are defined using the [[api-documentation:ICentralizedFileStorageProvider Provider Type|ICentralizedFileStorageProvider]] interface. A new instance of the implementation will be created for each CFS file store configured to use the provider. For each file store,&amp;nbsp;the provider will be instantiated and the instance will be notified of the file store it represents via the &lt;code&gt;Initialize()&lt;/code&gt; method, which provides the file store key and the XML node defined in the communityserver.config file which&amp;nbsp;can be used to provide configuration information to the provider.&amp;nbsp;The members required by ICentralizedFileStorageProvider should be self-descriptive with respect to the considerations listed above.&lt;/p&gt;
&lt;p&gt;Individual providers can expose additional/optional functionality by implementing additional extension interfaces to ICentralizedFileStorageProvider:&lt;/p&gt;
&lt;h3&gt;&lt;a id="Exposing_Events" name="Exposing_Events"&gt;&lt;/a&gt;Exposing Events&lt;/h3&gt;
&lt;p&gt;All file storage providers should support events, but events are technically optional. To expose file manipulation events, the provider should implement [[api-documentation:IEventEnabledCentralizedFileStorageProvider Provider Type|IEventEnabledCentralizedFileStorageProvider]]. This interface adds a set-only property, &lt;code&gt;EventExecutor&lt;/code&gt;, to receive the [[api-documentation:ICentralizedFileEventExecutor Plugin Supplementary Type|ICentralizedFileEventExecutor]] implementation from the Verint Community platform which can be used by the provider to fire CFS-related events.&lt;/p&gt;
&lt;p&gt;When firing events from a custom provider, ensure that when a global change is made that event parameters that don&amp;#39;t apply are set to null and not an empty string. For example, when a complete file store is deleted, the &lt;code&gt;OnBeforeDelete()&lt;/code&gt; and &lt;code&gt;OnAfterDelete()&lt;/code&gt; parameters for &lt;code&gt;path&lt;/code&gt; and &lt;code&gt;fileName&lt;/code&gt; should be null, because the deletion affects all paths and files.&lt;/p&gt;
&lt;h3&gt;&lt;a id="Direct_HTTP_Handling" name="Direct_HTTP_Handling"&gt;&lt;/a&gt;Direct HTTP Handling&lt;/h3&gt;
&lt;p&gt;By default the generic download URL for CFS files will issue an HTTP redirect to the provider specific download URL for a file (via the provider&amp;#39;s implementation of [[api-documentation:ICentralizedFile Plugin Supplementary Type|ICentralizedFile.GetDownloadUrl()]]). Extensions to &lt;code&gt;ICentralizedFileStorageProvider&lt;/code&gt; enable direct HTTP handling without a client-based redirect which can improve end-user performance.&lt;/p&gt;
&lt;p&gt;[[api-documentation:IHttpRenderableCentralizedFileStorageProvider Provider Type|IHttpRenderableCentralizedFileStorageProvider]] extends &lt;code&gt;ICentralizedFileStorageProvider&lt;/code&gt; and adds the &lt;code&gt;HandleHttpRequest()&lt;/code&gt; method. This method is called by the generic CFS HTTP handler and allows the custom provider to handle the existing request directly. If the method returns &lt;code&gt;true&lt;/code&gt;, the platform assumes the request is fully handled. If the provider returns &lt;code&gt;false&lt;/code&gt;, the default behavior will be processed likely resulting in an HTTP redirect.&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;&lt;a id="Persistent_URL_Generation" name="Persistent_URL_Generation"&gt;&lt;/a&gt;Persistent URL Generation&lt;/h3&gt;
&lt;p&gt;Persistent URLs&amp;nbsp;to CFS-stored files are embedded in content that is dynamically generated, but cached for a potentially long time, such as HTML output from a widget or processed LESS files. By default, persistent URLs generated by the CFS use the generic URL format. If a custom provider can provide a long-term URL (one that is not time-bombed), it can identify this capability to the Verint Community platform by implementing the [[api-documentation:IPersistentUrlGeneratingFileStorageProvider Provider Type|IPersistentUrlGeneratingFileStorageProvider]] interface and implementing the &lt;code&gt;GetPersistentDownloadUrl()&lt;/code&gt; method.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;When a file storage provider supports persistent URLs, the provider&amp;#39;s persistent URL will be used instead of the generic URL when a persistent URL is requested for a CFS-stored file.&lt;/p&gt;
&lt;h2&gt;&lt;a id="Configuration" name="Configuration"&gt;&lt;/a&gt;Configuration&lt;/h2&gt;
&lt;p&gt;The mapping of file storage providers to file stores is defined within the communityserver.config file. To use a custom provider, this configuration will need to be updated. See installation and configuration documentation to update the configuration of the CFS appropriately.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;

&lt;div style="font-size: 90%;"&gt;Tags: files, CFS, Centralized File Storage&lt;/div&gt;
</description></item><item><title>Managing Physical File Storage</title><link>https://community.telligent.com/community/11/w/developer-training/65120/managing-physical-file-storage/revision/1</link><pubDate>Thu, 13 Jun 2019 19:28:56 GMT</pubDate><guid isPermaLink="false">526ce0d7-4b48-49b6-aad2-7fc7347892bd</guid><dc:creator>Ben Tiedt</dc:creator><comments>https://community.telligent.com/community/11/w/developer-training/65120/managing-physical-file-storage#comments</comments><description>Revision 1 posted to Developer Training by Ben Tiedt on 06/13/2019 19:28:56&lt;br /&gt;
&lt;p&gt;The Telligent Community platform&amp;#39;s [[Centralized File Storage|Centralized File Storage System]] abstracts physical file storage from [[Interacting With Files|logical file storage]] and includes support for physically storing files on the operation system&amp;#39;s file system or Amazon S3. Additional physical file storage providers can be added to support storing files elsewhere.&lt;/p&gt;
&lt;p&gt;[toc]&lt;/p&gt;
&lt;h2&gt;&lt;a id="Why_Should_I_Create_a_New_File_Storage_Provider" name="Why_Should_I_Create_a_New_File_Storage_Provider"&gt;&lt;/a&gt;Why Should I Create a New File Storage Provider?&lt;/h2&gt;
&lt;p&gt;A new file storage provider should only be required to physically store files on a new physical technology or service. Telligent Community includes support for operating system file storage (local hard drive or UNC share) and Amazon S3. If another storage system, for example, a different cloud storage provider must be used, a new file storage provider can be used and configured to be used by [[Centralized File Storage|the centralized file system]].&lt;/p&gt;
&lt;h2&gt;&lt;a id="File_Storage_Provider_Considerations" name="File_Storage_Provider_Considerations"&gt;&lt;/a&gt;File Storage Provider Considerations&lt;/h2&gt;
&lt;p&gt;When developing new file storage providers, it is important to ensure that [[Centralized File Storage|CFS]] expectations are supported. Key considerations include:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The provider implementation must have a public, parameterless constructor.&lt;/li&gt;
&lt;li&gt;File store keys must be between 1 and 255 characters (each character must be supported by the Windows file system)&lt;/li&gt;
&lt;li&gt;Paths must be between 0 and 769 characters (each character must be supported by the Windows file system)&lt;/li&gt;
&lt;li&gt;File names must be between 1 and 255 characters (each character must be supported by the Windows file system)&lt;/li&gt;
&lt;li&gt;Paths should be considered as prefixes, not delimited &amp;quot;folders&amp;quot; when searching for sub-folders.&lt;/li&gt;
&lt;li&gt;Paths created with the &lt;code&gt;AddPath()&lt;/code&gt; method are expected to be returned by &lt;code&gt;GetPaths()&lt;/code&gt; calls even if the path contains no files.&lt;/li&gt;
&lt;li&gt;The provider is responsible for removing unused paths if a physical representation of the path (without respect to files) is required by the underlying physical implementation.&lt;/li&gt;
&lt;li&gt;The provider is responsible for checking permissions on secured file stores ([[api-documentation:ISecuredCentralizedFileStore Plugin Type|ISecuredFileStore]] and [[api-documentation:IGloballySecuredCentralizedFileStore Plugin Type|IGloballySecuredFileStore]]) before serving files (if the provider serves files directly).&lt;/li&gt;
&lt;li&gt;The provider is responsible for interacting with &amp;quot;findable&amp;quot; file stores when a file cannot be found when serving file contents ([[api-documentation:IFindableCentralizedFileStore Plugin Type|IFindableCentralizedFileStore]]).&lt;/li&gt;
&lt;li&gt;The provider is responsible for providing an implementation of [[api-documentation:ICentralizedFile Plugin Supplementary Type|ICentralizedFile]] for files returned by the provider which includes a full implementation, including a custom, direct HTTP handler for the &lt;code&gt;GetDownloadUrl()&lt;/code&gt; result.&lt;/li&gt;
&lt;li&gt;Any [[api-documentation:ICentralizedFile Plugin Supplementary Type|ICentralizedFile]] instances returned must exist in underlying storage. &amp;nbsp;If the files does not exist, a null value must be returned.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;&lt;a id="Provider_Interface_Types" name="Provider_Interface_Types"&gt;&lt;/a&gt;Provider Interface Types&lt;/h2&gt;
&lt;p&gt;File storage providers are defined using the [[api-documentation:ICentralizedFileStorageProvider Provider Type|ICentralizedFileStorageProvider]] interface. A new instance of the implementation will be created for each CFS file store configured to use the provider. For each file store,&amp;nbsp;the provider will be instantiated and the instance will be notified of the file store it represents via the &lt;code&gt;Initialize()&lt;/code&gt; method, which provides the file store key and the XML node defined in the communityserver.config file which&amp;nbsp;can be used to provide configuration information to the provider.&amp;nbsp;The members required by ICentralizedFileStorageProvider should be self-descriptive with respect to the considerations listed above.&lt;/p&gt;
&lt;p&gt;Individual providers can expose additional/optional functionality by implementing additional extension interfaces to ICentralizedFileStorageProvider:&lt;/p&gt;
&lt;h3&gt;&lt;a id="Exposing_Events" name="Exposing_Events"&gt;&lt;/a&gt;Exposing Events&lt;/h3&gt;
&lt;p&gt;All file storage providers should support events, but events are technically optional. To expose file manipulation events, the provider should implement [[api-documentation:IEventEnabledCentralizedFileStorageProvider Provider Type|IEventEnabledCentralizedFileStorageProvider]]. This interface adds a set-only property, &lt;code&gt;EventExecutor&lt;/code&gt;, to receive the [[api-documentation:ICentralizedFileEventExecutor Plugin Supplementary Type|ICentralizedFileEventExecutor]] implementation from the Telligent Community platform which can be used by the provider to fire CFS-related events.&lt;/p&gt;
&lt;p&gt;When firing events from a custom provider, ensure that when a global change is made that event parameters that don&amp;#39;t apply are set to null and not an empty string. For example, when a complete file store is deleted, the &lt;code&gt;OnBeforeDelete()&lt;/code&gt; and &lt;code&gt;OnAfterDelete()&lt;/code&gt; parameters for &lt;code&gt;path&lt;/code&gt; and &lt;code&gt;fileName&lt;/code&gt; should be null, because the deletion affects all paths and files.&lt;/p&gt;
&lt;h3&gt;&lt;a id="Direct_HTTP_Handling" name="Direct_HTTP_Handling"&gt;&lt;/a&gt;Direct HTTP Handling&lt;/h3&gt;
&lt;p&gt;By default the generic download URL for CFS files will issue an HTTP redirect to the provider specific download URL for a file (via the provider&amp;#39;s implementation of [[api-documentation:ICentralizedFile Plugin Supplementary Type|ICentralizedFile.GetDownloadUrl()]]). Extensions to &lt;code&gt;ICentralizedFileStorageProvider&lt;/code&gt; enable direct HTTP handling without a client-based redirect which can improve end-user performance.&lt;/p&gt;
&lt;p&gt;[[api-documentation:IHttpRenderableCentralizedFileStorageProvider Provider Type|IHttpRenderableCentralizedFileStorageProvider]] extends &lt;code&gt;ICentralizedFileStorageProvider&lt;/code&gt; and adds the &lt;code&gt;HandleHttpRequest()&lt;/code&gt; method. This method is called by the generic CFS HTTP handler and allows the custom provider to handle the existing request directly. If the method returns &lt;code&gt;true&lt;/code&gt;, the platform assumes the request is fully handled. If the provider returns &lt;code&gt;false&lt;/code&gt;, the default behavior will be processed likely resulting in an HTTP redirect.&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;&lt;a id="Persistent_URL_Generation" name="Persistent_URL_Generation"&gt;&lt;/a&gt;Persistent URL Generation&lt;/h3&gt;
&lt;p&gt;Persistent URLs&amp;nbsp;to CFS-stored files are embedded in content that is dynamically generated, but cached for a potentially long time, such as HTML output from a widget or processed LESS files. By default, persistent URLs generated by the CFS use the generic URL format. If a custom provider can provide a long-term URL (one that is not time-bombed), it can identify this capability to the Telligent Community platform by implementing the [[api-documentation:IPersistentUrlGeneratingFileStorageProvider Provider Type|IPersistentUrlGeneratingFileStorageProvider]] interface and implementing the &lt;code&gt;GetPersistentDownloadUrl()&lt;/code&gt; method.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;When a file storage provider supports persistent URLs, the provider&amp;#39;s persistent URL will be used instead of the generic URL when a persistent URL is requested for a CFS-stored file.&lt;/p&gt;
&lt;h2&gt;&lt;a id="Configuration" name="Configuration"&gt;&lt;/a&gt;Configuration&lt;/h2&gt;
&lt;p&gt;The mapping of file storage providers to file stores is defined within the communityserver.config file. To use a custom provider, this configuration will need to be updated. See installation and configuration documentation to update the configuration of the CFS appropriately.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item></channel></rss>