Skip to content

Integration examples

These examples assume Central has already issued an acugis_session value through its login flow. They use the reserved documentation host https://reports.example.test and placeholders only. Keep the token in an environment variable or cookie jar, never in source control.

The workflow is: discover permitted reports, load one report's expanded configuration, then execute it. Replace sales-summary, ReportingDB, and region with values returned by your service.

curl

export BASE_URL='https://reports.example.test'
export ACUGIS_SESSION='<opaque-session-token>'

# Public registry (no authentication gate).
curl --fail-with-body \
  "$BASE_URL/jasper-report-services/api/reports"

# Session-filtered discovery.
curl --fail-with-body \
  --cookie "acugis_session=$ACUGIS_SESSION" \
  "$BASE_URL/jasper-report-services/api/discovery"

# Expanded definition and dynamic parameter options.
curl --fail-with-body \
  --cookie "acugis_session=$ACUGIS_SESSION" \
  --get \
  --data-urlencode 'report=sales-summary' \
  "$BASE_URL/jasper-report-services/reports/get_report_config.php"

# Execute to PDF. Repeat --data-urlencode for multi-value parameters.
curl --fail-with-body --location \
  --cookie "acugis_session=$ACUGIS_SESSION" \
  --get \
  --data-urlencode '_repName=sales-summary' \
  --data-urlencode '_dataSource=ReportingDB' \
  --data-urlencode '_repFormat=pdf' \
  --data-urlencode 'region=North' \
  --output sales-summary.pdf \
  "$BASE_URL/jasper-report-services/reports/execute_report.php"

For a cookie jar populated by an existing Central login exchange, replace each --cookie with --cookie cookie.jar --cookie-jar cookie.jar.

JavaScript (Node.js 18+)

import { writeFile } from "node:fs/promises";

const base = process.env.BASE_URL ?? "https://reports.example.test";
const token = process.env.ACUGIS_SESSION;
if (!token) throw new Error("Set ACUGIS_SESSION");

const headers = { Cookie: `acugis_session=${token}` };
const service = `${base}/jasper-report-services`;

async function checkedJson(url) {
  const response = await fetch(url, { headers });
  if (!response.ok) throw new Error(`${response.status}: ${await response.text()}`);
  return response.json();
}

const discovery = await checkedJson(`${service}/api/discovery`);
const item = discovery.items.find(({ id }) => id === "sales-summary");
if (!item) throw new Error("Report is not visible");

const configUrl = new URL(`${service}/reports/get_report_config.php`);
configUrl.searchParams.set("report", item.id);
const config = await checkedJson(configUrl);

const executeUrl = new URL(`${service}/reports/execute_report.php`);
executeUrl.searchParams.set("_repName", config.report);
executeUrl.searchParams.set("_dataSource", config.datasource);
executeUrl.searchParams.set("_repFormat", "pdf");
executeUrl.searchParams.append("region", "North");

const output = await fetch(executeUrl, { headers });
if (!output.ok) throw new Error(`${output.status}: ${await output.text()}`);
await writeFile("sales-summary.pdf", Buffer.from(await output.arrayBuffer()));
console.log("saved sales-summary.pdf");

In browser code use same-origin URLs and credentials: "same-origin"; JavaScript cannot set the Cookie header itself.

Python

import os
from pathlib import Path

import requests

base = os.getenv("BASE_URL", "https://reports.example.test")
token = os.environ["ACUGIS_SESSION"]
service = f"{base}/jasper-report-services"

session = requests.Session()
session.cookies.set("acugis_session", token)

discovery = session.get(f"{service}/api/discovery", timeout=30)
discovery.raise_for_status()
item = next(row for row in discovery.json()["items"] if row["id"] == "sales-summary")

config_response = session.get(
    f"{service}/reports/get_report_config.php",
    params={"report": item["id"]},
    timeout=30,
)
config_response.raise_for_status()
config = config_response.json()

# A list of tuples preserves repeated keys for multi-value Jasper parameters.
params = [
    ("_repName", config["report"]),
    ("_dataSource", config["datasource"]),
    ("_repFormat", "pdf"),
    ("region", "North"),
]
with session.get(
    f"{service}/reports/execute_report.php",
    params=params,
    timeout=600,
    stream=True,
) as response:
    response.raise_for_status()
    with Path("sales-summary.pdf").open("wb") as output:
        for chunk in response.iter_content(1024 * 64):
            output.write(chunk)

Go

package main

import (
    "encoding/json"
    "fmt"
    "io"
    "net/http"
    "net/url"
    "os"
)

type discovery struct {
    Items []struct{ ID string `json:"id"` } `json:"items"`
}

type reportConfig struct {
    Report     string `json:"report"`
    Datasource string `json:"datasource"`
}

func request(client *http.Client, token, rawURL string) (*http.Response, error) {
    req, err := http.NewRequest(http.MethodGet, rawURL, nil)
    if err != nil { return nil, err }
    req.AddCookie(&http.Cookie{Name: "acugis_session", Value: token})
    return client.Do(req)
}

func main() {
    base := os.Getenv("BASE_URL")
    if base == "" { base = "https://reports.example.test" }
    token := os.Getenv("ACUGIS_SESSION")
    if token == "" { panic("set ACUGIS_SESSION") }
    service := base + "/jasper-report-services"
    client := &http.Client{}

    res, err := request(client, token, service+"/api/discovery")
    if err != nil { panic(err) }
    defer res.Body.Close()
    if res.StatusCode != http.StatusOK { panic(res.Status) }
    var catalog discovery
    if err := json.NewDecoder(res.Body).Decode(&catalog); err != nil { panic(err) }

    reportID := ""
    for _, item := range catalog.Items {
        if item.ID == "sales-summary" { reportID = item.ID }
    }
    if reportID == "" { panic("report is not visible") }

    configURL := service + "/reports/get_report_config.php?report=" + url.QueryEscape(reportID)
    res, err = request(client, token, configURL)
    if err != nil { panic(err) }
    defer res.Body.Close()
    if res.StatusCode != http.StatusOK { panic(res.Status) }
    var config reportConfig
    if err := json.NewDecoder(res.Body).Decode(&config); err != nil { panic(err) }

    query := url.Values{}
    query.Set("_repName", config.Report)
    query.Set("_dataSource", config.Datasource)
    query.Set("_repFormat", "pdf")
    query.Add("region", "North")
    res, err = request(client, token, service+"/reports/execute_report.php?"+query.Encode())
    if err != nil { panic(err) }
    defer res.Body.Close()
    if res.StatusCode != http.StatusOK {
        body, _ := io.ReadAll(res.Body)
        panic(fmt.Sprintf("%s: %s", res.Status, body))
    }

    file, err := os.Create("sales-summary.pdf")
    if err != nil { panic(err) }
    defer file.Close()
    if _, err := io.Copy(file, res.Body); err != nil { panic(err) }
}

PHP

<?php
declare(strict_types=1);

$base = getenv('BASE_URL') ?: 'https://reports.example.test';
$token = getenv('ACUGIS_SESSION');
if (!$token) {
    throw new RuntimeException('Set ACUGIS_SESSION');
}
$service = rtrim($base, '/') . '/jasper-report-services';

function get(string $url, string $token): string {
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_FOLLOWLOCATION => false,
        CURLOPT_TIMEOUT => 600,
        CURLOPT_HTTPHEADER => ['Cookie: acugis_session=' . $token],
    ]);
    $body = curl_exec($ch);
    $status = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $error = curl_error($ch);
    curl_close($ch);
    if ($body === false || $status < 200 || $status >= 300) {
        throw new RuntimeException($error !== '' ? $error : "HTTP $status: $body");
    }
    return $body;
}

$discovery = json_decode(get("$service/api/discovery", $token), true, flags: JSON_THROW_ON_ERROR);
$item = null;
foreach ($discovery['items'] as $candidate) {
    if (($candidate['id'] ?? '') === 'sales-summary') {
        $item = $candidate;
        break;
    }
}
if ($item === null) {
    throw new RuntimeException('Report is not visible');
}

$config = json_decode(
    get("$service/reports/get_report_config.php?" . http_build_query(['report' => $item['id']]), $token),
    true,
    flags: JSON_THROW_ON_ERROR
);

$query = http_build_query([
    '_repName' => $config['report'],
    '_dataSource' => $config['datasource'],
    '_repFormat' => 'pdf',
    'region' => 'North',
]);
$pdf = get("$service/reports/execute_report.php?$query", $token);
if (file_put_contents('sales-summary.pdf', $pdf) === false) {
    throw new RuntimeException('Could not write output');
}

PHP's http_build_query() does not represent repeated keys conveniently. For multi-value parameters, build and URL-encode each key=value pair separately.