Go to file
2025-10-17 17:19:55 +07:00
.devcontainer Initial Project 2025-10-17 16:01:56 +07:00
.sonarqube Initial Project 2025-10-17 16:01:56 +07:00
.vscode Initial Project 2025-10-17 16:01:56 +07:00
Auth Initial Project 2025-10-17 16:01:56 +07:00
Configuration Initial Project 2025-10-17 16:01:56 +07:00
docker/odbc Initial Project 2025-10-17 16:01:56 +07:00
drivers Initial Project 2025-10-17 16:01:56 +07:00
Endpoints Initial Project 2025-10-17 16:01:56 +07:00
Infrastructure Initial Project 2025-10-17 16:01:56 +07:00
k8s Initial Project 2025-10-17 16:01:56 +07:00
scripts Initial Project 2025-10-17 16:01:56 +07:00
.dockerignore Initial Project 2025-10-17 16:01:56 +07:00
.gitignore Initial Project 2025-10-17 16:01:56 +07:00
appsettings.json Initial Project 2025-10-17 16:01:56 +07:00
AS400API.csproj Initial Project 2025-10-17 16:01:56 +07:00
AS400API.sln Initial Project 2025-10-17 16:01:56 +07:00
docker-compose.yml Initial Project 2025-10-17 16:01:56 +07:00
Dockerfile Initial Project 2025-10-17 16:01:56 +07:00
Jenkinsfile add Jenkinfile 2025-10-17 17:19:55 +07:00
Program.cs Initial Project 2025-10-17 16:01:56 +07:00
README.md first commit 2025-10-17 15:57:18 +07:00

AS400API (.NET 9 + ODBC + Dev Container)

Quick start

  1. Put IBM i Access ODBC RPM into drivers/ and rename it to end with .rpm.disabled (e.g. ibm-iaccess-1.1.x.x86_64.rpm.disabled). The build converts it back to .rpm but the suffix prevents Apple Silicon devcontainer scaffolding from trying to install the amd64-only driver.
  2. Build & run:
docker compose up --build
  1. Open http://localhost:8080/swagger

VS Code / F5

  • Launch profile AS400API runs dotnet run with hot reload-ready JWT setup.

Environment

  • Uses System.Data.Odbc
  • Driver name: IBM i Access ODBC Driver (from ACS). Adjust AS400_DRIVER_NAME if your driver name differs.
  • Credentials are passed via env vars in docker-compose.yml.

Authentication & Authorization

  • POST /api/auth/login (anonymous) → request body { "username": "admin", "password": "Pass@123" }.
  • Demo identities live in-memory so you can plug in real IdP/Keycloak later.
  • Default accounts:
    • admin / Pass@123 → roles: Admin, Operator
    • operator / Pass@123 → role: Operator
  • Copy the accessToken from the response and send it as: Authorization: Bearer <token>.
  • Override JWT issuer/audience/secret via appsettings.json or environment variables (Jwt__Key, etc.).

Endpoints (role scoped)

  • GET /api/v1/health → anonymous AS/400 ping via SYSIBM.SYSDUMMY1
  • GET /api/v1/users/me → requires any authenticated user; echoes claims
  • GET /api/v1/as400/databases → requires Operator or Admin
  • GET /api/v1/as400/query?sql=... → requires Admin
  • GET /api/v1/as400/tables?libraryName=LIB → requires Operator or Admin
  • GET /api/v1/as400/table-structure?libraryName=LIB&tableName=TBL → requires Operator or Admin

Logging

  • Serilog writes rolling files by default to Logs/as400-api-.log (configurable in appsettings.json:Serilog:WriteTo:0:Args:path).
  • Override at runtime with environment variables, e.g. Serilog__WriteTo__0__Args__path=/var/log/as400/api-.log.
  • Request logging middleware is enabled; application-specific events (query counts, failures, etc.) are captured with structured properties to aid analysis.

SonarQube analysis

  • Install or provision a SonarQube/SonarCloud server and generate a project token.
  • Set environment variables (SONAR_HOST_URL, SONAR_TOKEN, optionally SONAR_PROJECT_KEY, SONAR_PROJECT_NAME; defaults are as400api / AS400API, plus SONAR_ORGANIZATION for SonarCloud).
  • Run scripts/run-sonar.sh; the script builds the solution, runs tests with Coverlet coverage (when *Tests.csproj projects exist), and publishes results.
  • Provide branch and pull request details with SONAR_BRANCH_NAME, SONAR_PULL_REQUEST_KEY, SONAR_PULL_REQUEST_BRANCH, and SONAR_PULL_REQUEST_BASE when needed.

Notes

  • On first build, if no RPM exists in drivers/, the image will build but ODBC won't work until you add the RPM and rebuild.

Kubernetes deployment

Use the manifests in k8s/ when running the API on Kubernetes.

  1. Create a secret with the AS/400 password (and optional JWT key) so it stays separate from the rest of the configuration:
    cp k8s/secret-example.yaml k8s/secret.yaml
    # edit k8s/secret.yaml and set real values
    kubectl apply -f k8s/secret.yaml
    
    Alternatively create the secret imperatively: kubectl create secret generic as400api-secrets --from-literal=AS400_PASSWORD=... --from-literal=JWT__KEY=....
  2. Apply the non-sensitive settings:
    kubectl apply -f k8s/configmap.yaml
    
  3. Deploy the workload and service:
    kubectl apply -f k8s/deployment.yaml
    kubectl apply -f k8s/service.yaml
    

The deployment imports the configuration via envFrom so the password is sourced from the secret while everything else comes from the config map. Update image names, probes, and resource requests to fit your environment.