Odyssey Manager Administrator Guide
This guide is for ILLiad system administrators who install, configure, and maintain the Odyssey Manager service. It covers the .NET implementation that ships with ILLiad 10 — what's new, how the service works, and the full configuration and troubleshooting reference.
You should be comfortable installing a Windows Service, editing a JSON configuration file, and setting ILLiad customization keys. Beyond a small amount of startup configuration, everything the service needs is read from ILLiad customization keys at run time — so most day-to-day tuning happens in the ILLiad Customization Manager, not in a config file.
What's new in the .NET Odyssey Manager
In ILLiad 10, Odyssey Manager was rewritten from Delphi as a .NET 10 Windows Service. It does the same core job as before — moving scanned documents between libraries over the Odyssey protocol (and OCLC Article Exchange when a library can't be reached over Odyssey) — but runs on an entirely new foundation. For most libraries, your existing Odyssey workflows keep working; what changes is how the service is deployed and configured.
Notable new features:
- Built-in PDF processing. PDF merge and TIFF-to-PDF conversion are now built in, replacing the external AtlasPDF tool — with better handling of multi-page TIFFs and large scans, and preservation of a document's accessibility features when a cover sheet is added.
- Automatic billing. Odyssey billing now runs inside the service as part of delivery, using your existing billing configuration — Document Delivery is billed on receive, Lending on send.
- Odyssey language header. When a lending library sends a document, its language now travels with it so the borrowing library can OCR in the right language automatically.
- Empty-file protection. A missing or zero-byte incoming file is caught before delivery and flagged, instead of delivering an empty document.
- More resilient delivery. Once a document is written to the patron's location, the follow-up bookkeeping steps can't strand an otherwise-completed delivery.
- Updating an existing ILLiad site to ILLiad 10? See Upgrading the Odyssey Manager.
- Installing ILLiad or setting up the service for the first time? See Setting up the Odyssey Manager.
- The rest of this guide is the full reference.
How it works
Odyssey Manager is a background service on the ILLiad server that moves scanned articles and book chapters between ILLiad sites over the Odyssey protocol — and, where a library can't be reached over Odyssey, over OCLC Article Exchange. It runs three background workers in one process:
- Inbound (Odyssey server). Listens on a TCP port for incoming connections, accepts documents, checks the file type, merges a cover sheet, writes the finished PDF to the patron-visible location, and advances the matching ILLiad request to Delivered to Web.
- Outbound send. Checks the outgoing queue on a timer, sends each staged document to the borrowing library's Odyssey listener (or to Article Exchange), and retries failed sends.
- Article Exchange inbound watcher. Watches a drop folder for documents delivered through OCLC Article Exchange and runs them through the same inbound finish path. This worker is optional and stays idle unless its directory key is set.
Unlike the EDU, Odyssey Manager connects directly to the ILLiad database, using the standard ILLiad logon database (the .dbc connection), which it finds automatically on a normal ILLiad server.
Runtime identity
| Property | Value |
|---|---|
| Executable name | ILLiadOdysseyManager.exe |
| Target framework | .NET 10 |
| Windows Service name | ILLiad Odyssey Manager |
The file the build produces is ILLiadOdysseyManager.exe. Some older install snippets reference AtlasSystems.ILLiad.OdysseyManager.exe — use ILLiadOdysseyManager.exe.
Prerequisites
- .NET 10 runtime available on the ILLiad server.
- Database access. The service reads its SQL Server connection string from the standard ILLiad logon database, which it finds automatically on a normal ILLiad server — you don't need to place a logon database file next to the executable. The service account must be able to reach the SQL Server named there.
- A data directory the service account can read and write (the
DataPath, below). The service creates and manages its Odyssey subfolders (Incoming, Outgoing, and so on) beneath it. - OCLC Article Exchange credentials — if you use Article Exchange, all four must be set (see Customization keys); authentication fails if any is empty.
Installation and service registration
- Updating an existing site to ILLiad 10? Use Upgrading the Odyssey Manager.
- Fresh install? Use Setting up the Odyssey Manager.
The rest of this section is reference — service registration commands and command-line options.
Odyssey Manager runs as a Windows Service. In production it's registered by the standard ILLiad installer. To register it by hand on a test host, run from an elevated prompt:
sc.exe create "ILLiad Odyssey Manager" binPath= "C:\Path\To\ILLiadOdysseyManager.exe" start= auto
sc.exe start "ILLiad Odyssey Manager"
To remove the service: sc.exe delete "ILLiad Odyssey Manager"
Command-line options
| Option | Effect |
|---|---|
--console | Run in the foreground with console logging added on top of the file log. Use this for diagnostics. |
--dbc=<path> | Point at a specific ILLiad logon database instead of finding one automatically. Must use the --dbc=<path> form. |
--dbc must point at a real file when suppliedIf you pass --dbc=<path> and the file doesn't exist, the service reports an error and exits. When --dbc is omitted, the service finds the logon database automatically, so a file next to the executable isn't required.
What the service account needs
- Full control on the
DataPathdirectory and its children (Incoming, Outgoing, and the other Odyssey subfolders). - Read access to the cover-sheet file in use.
- Write access to the
logsdirectory next to the executable. - Network and authentication access to the SQL Server named in the logon database.
Configuration
The service has a deliberately small startup configuration in appsettings.json. Almost all behavior — trust policy, retry timing, cover-sheet paths, billing gates, OCLC credentials — comes from ILLiad customization keys read at run time (see Customization keys).
appsettings.json
All keys live under the OdysseyManager section. The service checks this section at startup; an invalid value produces a short "cannot start — invalid configuration" message and a non-zero exit code rather than a stack trace.
| Key | Required | Default | Range | Purpose |
|---|---|---|---|---|
ListenPort | no | 7968 | 1–65535 | TCP port the Odyssey server listens on. |
DataPath | yes | — | non-empty | Root directory for the Odyssey-managed folders. Must exist or be creatable. |
MaxConcurrentProcessing | no | 20 | 1–1000 | Most documents processed at once after receipt. |
OutboundPollIntervalSeconds | no | 60 | 1–3600 | How often the outbound worker checks the outgoing queue. |
ArticleExchangePollIntervalSeconds | no | 30 | 1–3600 | How often the Article Exchange watcher checks its drop folder. |
View the shipped appsettings.json:
{
"OdysseyManager": {
"ListenPort": 7968,
"DataPath": "C:\\ILLiad\\Odyssey",
"MaxConcurrentProcessing": 20
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}
DataPath is requiredIf DataPath is missing or blank, the service won't start. It has no default.
Poll interval isn't retry timing. OutboundPollIntervalSeconds only controls how often the outbound worker wakes to look at the queue. How many times a document is retried, and how long between tries, come from customization keys (OdysseyMaxSendTries, OdysseySendInterval).
The Logging section doesn't drive the file log. The service uses log4net for its rolling file and Event Log output; the Logging entries in appsettings.json don't govern it — see Monitoring and Troubleshooting.
Customization keys
The service reads these ILLiad customization keys at run time. Unless noted, string keys are read for the ILL NVTGC or the request's own NVTGC. Set them in the ILLiad Customization Manager.
Inbound processing
| Key | Default | Purpose |
|---|---|---|
OdysseyServerReceiveDir | — (unset idles the AE watcher) | Root of the Article Exchange inbound drop directory. The watcher watches <value>/ArticleExchange. Read for NVTGC ILL. |
WebPDFPath | — | Directory where the delivered PDF is written as <TN>.pdf. If unset, delivery fails with "PDF Conversion Failed". |
OdysseyAutoElecDel | Trusted | Trust policy deciding automatic vs. manual handling of inbound electronic delivery. |
AlwaysTrustLocalDelivery | — | Inbound local-delivery trust override. |
ArticleExchangeTrusted | Trusted | Trust policy for inbound Article Exchange deliveries. |
OdysseySystemID | — | Canonical local Odyssey system ID (per parent NVTGC); used to rewrite receiver identifiers in the header. |
Cover sheets
| Key | Purpose |
|---|---|
OdysseyPDFCoverSheetLocation / OdysseyPDFCoverSheetFileName | Folder and filename of the cover-sheet PDF for non-Doc Del deliveries. |
DocDelPDFCoverSheetLocation / DocDelPDFCoverSheetFileName | Folder and filename of the cover-sheet PDF for Doc Del deliveries. |
Article Exchange OCR & OCLC credentials
| Key | Default | Purpose |
|---|---|---|
ArticleExchangeOCREnabled | No | Per-receiving-site toggle for the Article Exchange OCR handoff. |
OCLCWebServiceV2APIKey, OCLCWebServiceV2APISecret, OCLCILLAuthorization, OCLCILLPassword | empty | The four OCLC Article Exchange credentials, read at the parent site. If any is empty, Article Exchange uploads fail authentication (documents then deliver without OCR) and a one-time warning is logged. |
Outbound send & retry
| Key | Default | Purpose |
|---|---|---|
OdysseyMaxSendTries | 4 | Attempts per document before terminal failure or Article Exchange fallback. Read for NVTGC ILL. |
OdysseySendInterval | 300 | Seconds to wait before the next attempt after a failed send. Read for NVTGC ILL. |
SharedServerSupport | No | In shared-server mode, resolves SendArticleExchangeOnOdysseyFailure per request NVTGC instead of ILL. |
SendArticleExchangeOnOdysseyFailure | No | When on, a TCP send that exhausts its retries falls back to Article Exchange instead of failing. |
Billing gates
| Key | Purpose |
|---|---|
BillingActive | Borrowing billing-active gate used in the inbound routing decision. Routing-only for this service — it creates no Borrowing charges. |
BillingActiveDocDel | Enables Doc Del automatic billing (bills on receive). |
BillingActiveLending | Enables Lending automatic billing (bills on send). |
Local system-ID detection
| Key | Default | Purpose |
|---|---|---|
UseOdyssey | Yes | Whether a site participates in Odyssey. |
OdysseyReceive | No | Whether a site receives via Odyssey. |
OdysseySend | Yes | Whether a site sends via Odyssey. |
OdysseySystemIDAlt | — | Alternate local Odyssey system ID matched during detection. |
OdysseyLocalReceiverIDs / OdysseyLocalSenderIDs | — | Delimited lists of additional local receiver/sender IDs treated as local. |
Inbound processing
Incoming documents arrive two ways, and both end at the same Delivered to Web finish:
- Odyssey server (TCP). The inbound worker accepts a document over the listen port.
- Article Exchange watcher. When
OdysseyServerReceiveDiris set, the watcher picks up documents dropped into<OdysseyServerReceiveDir>/ArticleExchange. When the key is unset, this worker stays idle.
Each entry point first decides between automatic and manual handling (based on your trust-policy keys), then runs that path.
File-type check (automatic path only)
On the automatic path, the service accepts only TIFF (application/tiff or application/tif) and PDF (application/pdf). Anything else — including image/tiff from non-ILLiad senders — is rejected: the files are moved to the Incoming backup and the request is stamped with an "Unrecognized file type" note. Empty or zero-byte files are caught first and stamped "Empty File."
The manual path skips this check — those documents go to the Awaiting Odyssey Processing queue for staff to handle.
Finishing the delivery
Once the finished PDF is written to the patron-visible location, the request reaches Delivered to Web and the document is available to the patron. The remaining housekeeping — updating lender info, updating OCLC, Doc Del billing, and patron notification — runs after that, and a problem with any of those steps can't stop the request from reaching Delivered to Web. A notification failure, for example, becomes a "Notification Failed" note rather than blocking delivery.
Lender conflict
If a document arrives for a request that's already Delivered to Web or Request Finished, the service flags a lender conflict — it marks the request with a "Lender Conflict" note, removes the incoming files, and does not deliver again. (This check is skipped for Doc Del and for the electronic-delivery-after-processing path.)
Article Exchange OCR handoff
After a cover sheet is merged, the service can hand a document to OCLC's Article Exchange OCR instead of delivering an image-only PDF. This happens only when both are true:
ArticleExchangeOCREnabledis on for the receiving site, and- the merged PDF is not fully searchable (it has at least one image-only page).
In that case, the service uploads the PDF for OCR, sets the request to Awaiting Article Exchange OCR, and waits. The OCR'd file returns through the Article Exchange watcher, which replaces the delivered PDF and completes delivery. If the OCR handoff can't be completed — an upload error or missing credentials — the service logs it and delivers the original PDF instead. For more on OCR, see OCR functionality in ILLiad.
Cover sheets and accessibility preservation
Before delivery, the service merges a cover sheet in front of the document and preserves the document's accessibility features through the merge. How cover sheets are configured, the built-in PDF/TIFF conversion, and the accessibility preservation are covered in Built-in PDF Processing.
Outbound send
The outbound worker wakes every OutboundPollIntervalSeconds and scans the Outgoing folder for staged documents. For each one that's due, it counts the attempt, bills where applicable, and sends it. Two delivery channels are available, chosen per document:
- Odyssey (TCP) — the default; a direct push to the library's Odyssey listener.
- OCLC Article Exchange — used when selected; a successful upload returns both a URL and a password.
Retry and fallback
Each failed attempt (under the cap) schedules the next one for OdysseySendInterval seconds later. When attempts reach OdysseyMaxSendTries, the service either:
- Falls back to Article Exchange, if the document is still on the Odyssey path and
SendArticleExchangeOnOdysseyFailureis on (in shared-server mode,SharedServerSupportdecides whether that key is read per site or forILL). The fallback resets the attempt count and switches the channel to Article Exchange; or - Fails for good, if there's no fallback left. The request is stamped "Sending Failed," its status becomes Odyssey Sending Failed, and the files move to the Failed folder.
On a successful Odyssey send, the request moves from Odyssey Complete to Request Finished, and the service records the Odyssey protocol version it negotiated (kept purely for reference — it never changes send behavior, and there's no equivalent for Article Exchange).
Document language header
When Odyssey Manager sends a document, it now includes the document's language in the Odyssey header. The borrowing library can use that to OCR the document in the correct language automatically, instead of guessing. If the borrowing library already has a language set on its transaction, the lending library's value takes precedence — the lender knows the actual language of what they're sending.
This is backward-compatible: libraries on older versions of ILLiad simply ignore the new header, with no errors in either direction.
Billing
Odyssey Manager now applies billing automatically as part of delivery. The details — which paths are billed, the gate keys, and how exemptions work — are in their own article: see Automatic Billing.
Monitoring and logging
The service writes a heartbeat you can check, and logs every document's path through the system. That plus the troubleshooting table lives in its own article: see Monitoring and Troubleshooting.
What changed from the Delphi Odyssey Manager
For the step-by-step cutover, see Upgrading the Odyssey Manager. At a glance:
| Area | Delphi Odyssey Manager | .NET Odyssey Manager |
|---|---|---|
| Platform | Delphi program | .NET 10 Windows Service (ILLiadOdysseyManager.exe, service ILLiad Odyssey Manager) |
| Configuration | INI-style | appsettings.json (small) + ILLiad customization keys (most behavior) |
| PDF processing | External AtlasPDF tool | Built in — AtlasPDF no longer required |
| Odyssey billing | Applied by the EDU or done manually | Built into the service (Doc Del on receive, Lending on send) |
| Cover-sheet accessibility | Lost on merge | Preserved (tags, language, title) |
| Empty-file handling | Delivered empty documents | Caught and flagged "Empty File" on the automatic path |
| Heartbeat | Odyssey Manager row in SystemInformation | Same heartbeat, so existing dashboards keep working |