Custom file system providers
| Release: |
• 4.6 • 5.0 • 5.1 • 5.2 • 5.3 • 5.4 • 6.0 • 6.1 • 6.2 • 6.3 • 6.4 • 6.5 • • 6.6 • 7.0 • 7.1 • 7.2 |
|---|
New in Analytica 7.2
Requires Analytica Developer edition or better. It is always available in the Analytica Decision Engine, in ACP, and in AMP (the Analytica MCP Platform). In a lesser edition, a «scheme»:// path reports that the feature is not available in this edition.
What a custom file system provider is
A file provider makes a URI-style path
«scheme»://«root»/«path»
for example repo://Sales/Q3.csv, work anywhere the Analytica engine accepts a file name. That includes opening a model and the modules that model links to or includes, ReadTextFile, ReadBinaryFile, FileSystemListing, FileFullPath, FilePathPart, and the internal file-exists tests that model loading uses.
The scheme prefix -- repo in that example -- is configuration, not code. Providers are registered when the engine starts up, from a plain text file named FileProviders.config, so one deployment can define several prefixes, each backed by a different storage service. Behind each prefix is an HTTP service that speaks a deliberately tiny protocol. You can write that service yourself: see Custom file system providers/API spec.
Things this is used for:
- A cloud object store, so that models and data live in a bucket rather than on a file server or on each analyst's own disk.
- A document management system, so that reading a file goes through the same access control and audit trail as every other document in the organization.
- A version-controlled model repository, so that a run can name the exact models and data it used and those names keep meaning the same thing.
- A corporate content API that already knows where the authoritative copy of a data set lives.
The point of doing it this way is that nothing else in the model changes. The model author writes
ReadTextFile( "repo://Sales/Q3.csv" )
and every other part of the model, and every function that takes a file name, behaves exactly as it does with a local path.
URI paths
- The form is
«scheme»://«rest». A scheme starts with a letter, continues with letters, digits,+,.or-, and is at least two characters long. The two-character minimum is deliberate: it keepsC://fooa Windows drive path rather than a URI. - Scheme matching is not case-sensitive.
repo://andRepo://reach the same provider. - A backslash is accepted inside a URI path and treated as
/. So a model atrepo://models/Main.anathat includessub\Child.anaresolves torepo://models/sub/Child.ana. .and..segments resolve textually when a relative path is joined onto a URI folder, and..can never pop above«scheme»://«root». A..segment that would still reach the provider is refused outright.- A URI is treated as an absolute path, so relative-path resolution against a model that was opened from a URI works normally.
- The path utilities keep a syntactic URI intact even when no provider is registered for its scheme, so an unknown scheme fails with a clear message instead of being mangled into a Windows path.
FileProviders.config
FileProviders.config is a plain text file with one setting per line. A # starts a comment, blank lines are ignored, and each setting has the form
«key» «scheme» = «value»
Key names are not case-sensitive.
# scheme prefix -> store service. Several FileStore lines define several schemes. FileStore repo = http://mystore.internal:8080 FileStoreToken repo = «bearer-token» # literal token FileStoreTokenFile repo = C:\secrets\repo-token # OR read the token from this file FileStoreMaxMB repo = 256 # optional fetch size cap (default 256) FileStoreTimeoutS repo = 60 # optional read timeout (default 60)
| Setting | Meaning |
|---|---|
FileStore «scheme» = «url» |
Declares «scheme» and gives the base URL of the store service that serves it. Required, and it must be the first line for that scheme. |
FileStoreToken «scheme» = «token» |
A bearer token, written literally, that is sent with every request to that store. |
FileStoreTokenFile «scheme» = «path» |
Reads the bearer token from this file instead. Surrounding white space in the file is trimmed. When both are given, FileStoreTokenFile wins.
|
FileStoreMaxMB «scheme» = «n» |
The largest file, in megabytes, that will be fetched from this store. Default 256. A fetch that exceeds it is aborted with an error that names this setting. |
FileStoreTimeoutS «scheme» = «n» |
The read timeout, in seconds. Default 60. The connect timeout is fixed at 5 seconds. |
The FileStore line must come first for a scheme. Any of the other keys naming a scheme that has not been declared yet is ignored, with a warning on stderr.
The URL may include a path prefix, as in http://host:port/prefix. A trailing / is dropped, and the endpoints the engine calls are appended to what remains.
The URL must be http://. An https:// URL is refused when the provider is registered, with a warning on stderr, because TLS is not compiled into the engine's HTTP client. The deployments this supports are a store service on localhost, or one inside the same private network or cluster. See Security below.
The configuration is read once per process, during engine initialization. Editing FileProviders.config has no effect until Analytica is restarted.
Where Analytica looks for FileProviders.config
Three locations are consulted in this order, and the first one that names a file wins.
- The host's own command line option,
/stores:«path»-- see Analytica Command Line. - The
FileProvidersConfigregistry value. Two keys are consulted, and each is looked for underHKEY_CURRENT_USERfirst and then underHKEY_LOCAL_MACHINE:HKCU\Software\Lumina Decision Systems\«product»\«version»\FileProvidersConfig-- per product and per version, for example...\Analytica\7.2or...\ADEW\7.2. Use this when you want one product to see a different set of stores from the others.HKCU\SOFTWARE\Lumina Decision Systems\FileProvidersConfig-- product-independent. One value here serves Analytica, ADE and ADEW, ACP and AMP alike. This is the usual choice, and it is the only way to set the location for ADE and ADEW, which have no command line of their own.
- A value that names a file which does not exist produces a warning on
stderr, rather than quietly registering nothing.
FileProviders.configin the same folder as the engine binary -- the deployed default.
When none of these finds a file, no providers are registered and nothing is reported.
Using a provider from a model
Once repo has been declared, use it as an ordinary file name.
ReadTextFile( "repo://data/Sales.csv" )ReadBinaryFile( "repo://data/logo.png" )
FileSystemListing returns the names, sizes and modification dates that the store reports:
FileSystemListing( "repo://models/", recurse: true )FileSystemListing( "repo://data/*.csv", ['Name', 'Size', 'DateLastModified'] )
A wildcard in the last segment of the path filters the listing, as it does for a local folder.
You can open a model whose path is a URI. Modules that the model links to or includes resolve relative to the model's own URI, so a model at repo://models/Main.ana that includes sub\Child.ana loads repo://models/sub/Child.ana from the same store. FileFullPath joins a relative name onto a URI folder the same way:
FileFullPath( "Q3.csv", "repo://Sales" ) → 'repo://Sales/Q3.csv'
An obfuscated model works over a provider scheme exactly as it does from a local file.
A long transfer stays cancellable. Ctrl+Break, or a cancellation from an ACP or AMP client, interrupts a fetch that is in progress instead of waiting for it to finish.
Existence checks
Testing whether a file exists asks the store, using an HTTP HEAD request. What happens when the store answers neither yes nor no is deliberate: if the store cannot be reached, or rejects the credentials, the existence test reports True -- it cannot prove absence. Control then reaches the code that actually opens the file, and that reports the real transport or authentication problem, instead of a misleading "file not found".
Restrictions in Analytica 7.2
- Read-only. Every write path refuses a URI path with a clean error: saving a model to a URI, WriteTextFile, WriteBinaryFile, FileSystemCopy, FileSystemMove, FileSystemDelete and FileSystemNewFolder. Write-back is planned, but is not in 7.2.
- Whole-file fetch. A read pulls the entire file, subject to
FileStoreMaxMB. It is not a seekable remote stream, so a provider path is not a good way to peek at a few bytes of a very large file. - One short fetch cache. The URI most recently fetched is cached for 10 seconds, because opening a model reads the same file two or three times. Past that, every read goes to the store.
- No file browser. A URI path never poses a "locate the file" dialog. A file that is not there is reported as not found.
Diagnostics
Everything the provider layer reports itself goes to stderr, which the server products capture in their logs and which the desktop application does not display.
On start-up, each registered provider prints one line:
[FileProviders] repo:// -> http://mystore.internal:8080
Unrecognized lines, unusable scheme names, an https:// URL, a token file that could not be read, and a FileProvidersConfig registry value naming a file that is not there, each produce their own warning there. An absent configuration file is silent: no providers are registered and nothing is written.
Errors that reach the model are reported as The file '...' could not be opened, with one of these explanations:
| Situation | What it says |
|---|---|
| No provider is registered for that scheme | no file provider is registered for the scheme 'repo'
|
| The edition does not include the feature | 'repo://' paths require the Developer edition or better, also naming the edition you do have
|
| The store rejected the credentials (HTTP 401 or 403) | the repo:// file store rejected the credentials (HTTP 401)
|
| Any other unexpected HTTP status | HTTP «n» from the repo:// file store
|
| The service could not be reached | could not reach the repo:// file store (...)
|
| The file is larger than the cap | the file exceeds the «n» MB fetch limit (FileStoreMaxMB in FileProviders.config)
|
A .. segment in the path |
'..' is not allowed in a repo:// path
|
| Writing to a URI | repo:// locations are read-only in this version of Analytica
|
HTTP 404 is not an error. It means the file is not there, and the caller then reports a missing file in its usual way.
Security
The connection between Analytica and a store service is plain HTTP, with no TLS. That is a deliberate limitation of this release, and you have to design around it:
- The bearer token, and the file contents, travel in the clear over that hop. Run the store service on
localhost, or on a private network or cluster network that you already trust with that traffic. Do not put a store service anywhere you would not be willing to send the token in plain text. FileProviders.configcan hold a token, so protect it like any other file holding a secret. Restrict who can read it, and keep it out of version control and out of model archives.- Prefer
FileStoreTokenFiletoFileStoreToken. It keeps the token out of the file that gets copied from machine to machine, and it lets the token live somewhere with tighter permissions -- or, in a container, be a mounted secret. - A store service should authenticate every request, and should reject path traversal itself. The engine refuses a
..segment before any request is sent, but a service must not rely on that.
See Also
- Custom file system providers/API spec -- the HTTP API that a store service must implement
- Analytica Command Line -- the
/stores:«path»option - ReadTextFile
- ReadBinaryFile
- FileSystemListing
- FileFullPath
- FilePathPart
- Category:File system functions