SAP Report
InTouch JAR plugin tool (IToolConnector) that fetches a report dataset from an
SAP OData service over HTTP. No vendor SDK — no SAP JCo — just
java.net.http.HttpClient + Jackson, so it builds with the same dependency set
as the other Blue Isle tools.
- name:
sap-report - displayName: SAP
- provider: Blue Isle Software
- version: 1.1.0
- category: Reporting
- credentialBased: true
- license: none (non-enterprise —
licenseRequired()is false)
Two operations, selected by the operation field on the task (odata-report
is the default when operation is absent, so existing tasks keep working):
Operations
odata-report
Fetches a report dataset from an SAP OData service over HTTP with basic auth:
GET {serviceUrl}/{entitySet}?$format=json[&$filter=...][&$top=...].
Task fields
| Field | Description |
|---|---|
entitySet |
Entity set to read, e.g. SalesOrderSet (required). |
filter |
Optional OData $filter expression. |
top |
Optional $top row cap (0 = no cap). |
format |
json (default) or xml. |
serviceUrl |
OData service base URL. Leave blank to use the credential's serviceUrl; set it when using an oauth-type credential (which carries only the token). |
outputPath |
Optional file to write the payload to. |
Published: rowCount, bytes, entitySet, and outputPath or inline payload.
Row counting handles OData v2 (d.results) and v4 (value) shapes.
run-report
Executes an SAP OData function import / action — i.e. a report program the
SAP system exposes over the Gateway. Use GET for read-only function imports
(parameters become query-string args) or POST for actions (parameters become
a JSON body):
GET {serviceUrl}/{functionName}?$format=json&Param=value...POST {serviceUrl}/{functionName}?$format=jsonwith the parameter JSON as the body
CSRF: On POST, the tool performs the SAP Gateway CSRF handshake
automatically — it first does a GET {serviceUrl}?$format=json with header
X-CSRF-Token: Fetch, then replays the returned token (and the session cookie,
held in the client's cookie store) on the write request. If the server issues
no token (CSRF protection off, or the fetch fails) the POST proceeds without
one. The csrfToken published field reports fetched or none.
Scope: this runs whatever SAP surfaces as an OData function import/action (or a custom RFC web service). Classic ABAP report programs are not reachable over plain HTTP unless they are exposed that way — there is no JCo / RFC path in this tool by design.
Task fields
| Field | Description |
|---|---|
operation |
Must be run-report to select this mode. |
functionName |
OData function import / action name to execute (required). |
method |
GET (default, params → query string) or POST (params → JSON body). |
parameters |
Parameters as a JSON object string, e.g. {"CompanyCode":"1000","FiscalYear":2026}. For OData v2 string params, include quotes if your Gateway requires them: {"CompanyCode":"'1000'"}. |
serviceUrl |
OData service base URL. Leave blank to use the credential's serviceUrl; set it when using an oauth-type credential (which carries only the token). |
outputPath |
Optional file to write the result payload to. |
Published: functionName, method, httpStatus, bytes, rowCount
(best-effort, for collection-returning functions), csrfToken (fetched/none,
POST only), and outputPath or inline payload.
Authentication
The tool auto-selects auth from the credential it receives: if an access_token
is present it sends Authorization: Bearer <token>, otherwise it falls back to
HTTP basic auth. Two ways to authenticate:
Basic auth (sap-type credential)
| Field | Description |
|---|---|
serviceUrl |
SAP OData service base URL (e.g. https://sap.acme.com/sap/opu/odata/sap/ZSALES_SRV). |
login |
SAP OData service username (HTTP basic auth). |
secret |
SAP OData service password (HTTP basic auth). |
access_token |
(optional) A bearer token to use as-is. Not server-refreshed — for refresh use OAuth mode below. |
testCredential does a reachability/auth GET against the service root URL.
Platform-refreshed OAuth (recommended for production)
SAP Gateway accepts OAuth 2.0 bearer tokens. To get a token the server keeps fresh automatically:
- Mint an
oauth-type credential (e.g.itcli.py /oauthdevice-code flow). - Link that
oauthcredential to the SAP task. - Set the task's
serviceUrlfield to the OData base URL (theoauthcredential carries the token, not the SAP URL).
At execution the server refreshes the token (OAuthTokenService.ensureFreshToken,
gated on the credential's type being oauth) and injects the current
access_token into the credential JSON the tool receives — so the tool always
sends a valid Authorization: Bearer. A token pasted into a sap-type
credential's access_token field is used as-is and is not refreshed.
Server-side refresh is keyed on the credential type being
oauth. A sap-type credential with a pasted token will not be refreshed — link a realoauthcredential for that.
Example task JSON
SAP OData report → JSON on disk:
{
"entitySet": "SalesOrderSet",
"filter": "NetAmount gt 1000",
"top": 500,
"format": "json",
"outputPath": "/data/reports/sales-orders.json"
}
SAP OData report → inline payload published (no outputPath):
{
"entitySet": "SalesOrderSet",
"top": 50
}
Run a report (read-only function import via GET):
{
"operation": "run-report",
"functionName": "RunSalesReport",
"method": "GET",
"parameters": "{\"CompanyCode\":\"'1000'\",\"FiscalYear\":2026}",
"outputPath": "/data/reports/sales-report.json"
}
Run a report (action via POST):
{
"operation": "run-report",
"functionName": "GenerateInvoiceBatch",
"method": "POST",
"parameters": "{\"BillingDate\":\"2026-06-19\",\"SalesOrg\":\"1000\"}"
}
OAuth mode — link an oauth credential and pass serviceUrl on the task:
{
"operation": "run-report",
"functionName": "RunSalesReport",
"method": "GET",
"serviceUrl": "https://sap.acme.com/sap/opu/odata/sap/ZSALES_SRV",
"parameters": "{\"FiscalYear\":2026}"
}
Build
./gradlew :intouchtools:tools:sap-report:build
Self-Contained JAR
The jar bundles all runtime dependencies; only intouch-tool-api is provided by the server.
Publishes
The keys a later task may reference as {{taskName.key}}. Referencing anything not listed here resolves to nothing at run time.
bytescsrfTokenentitySetfunctionNamehttpStatusmethodoutputPathpayloadrowCount