You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by ya...@apache.org on 2026/03/26 20:41:37 UTC
(airavata) 10/10: chore: final cleanup — gitignore docs/superpowers, fix health endpoint format
This is an automated email from the ASF dual-hosted git repository.
yasith pushed a commit to branch AIRAVATA-3981/integration-health-check
in repository https://gitbox.apache.org/repos/asf/airavata.git
commit a25464a1c31d93f04a33c8f78e57d7a9cc625f09
Author: yasithdev <ya...@icloud.com>
AuthorDate: Thu Mar 26 15:41:00 2026 -0500
chore: final cleanup — gitignore docs/superpowers, fix health endpoint format
- Wrap /health/services response in {"services": {...}} per spec
- Update ServiceHealthEndpointTest and BackgroundServiceHealthTest to
unwrap the "services" key before asserting on service entries
- Add docs/superpowers/ to .gitignore and remove already-committed files
from git tracking (local copies preserved)
---
.gitignore | 2 +
.../patform/monitoring/MonitoringServer.java | 2 +-
...2026-03-26-airavata-thrift-server-extraction.md | 1090 --------------------
...-26-airavata-thrift-server-extraction-design.md | 190 ----
.../integration/BackgroundServiceHealthTest.java | 4 +-
.../integration/ServiceHealthEndpointTest.java | 8 +-
6 files changed, 12 insertions(+), 1284 deletions(-)
diff --git a/.gitignore b/.gitignore
index 6a9a2b896a..a9c37a7d2d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -66,3 +66,5 @@ keystores/airavata.p12
keystores/aes.p12
modules/*/distribution/
modules/*/*/distribution/
+
+docs/superpowers/
diff --git a/airavata-api/src/main/java/org/apache/airavata/patform/monitoring/MonitoringServer.java b/airavata-api/src/main/java/org/apache/airavata/patform/monitoring/MonitoringServer.java
index 1f7bac390d..43fa6f7afe 100644
--- a/airavata-api/src/main/java/org/apache/airavata/patform/monitoring/MonitoringServer.java
+++ b/airavata-api/src/main/java/org/apache/airavata/patform/monitoring/MonitoringServer.java
@@ -137,7 +137,7 @@ public class MonitoringServer implements IServer {
try {
Map<String, ServiceStatus> statuses =
serviceRegistry != null ? serviceRegistry.getStatuses() : Map.of();
- sendJson(exchange, 200, statuses);
+ sendJson(exchange, 200, Map.of("services", statuses));
} catch (Exception e) {
logger.error("Error serving /health/services", e);
sendResponse(exchange, 500, "Internal Server Error");
diff --git a/docs/superpowers/plans/2026-03-26-airavata-thrift-server-extraction.md b/docs/superpowers/plans/2026-03-26-airavata-thrift-server-extraction.md
deleted file mode 100644
index 837d304414..0000000000
--- a/docs/superpowers/plans/2026-03-26-airavata-thrift-server-extraction.md
+++ /dev/null
@@ -1,1090 +0,0 @@
-# Airavata Thrift Server Extraction Implementation Plan
-
-> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
-
-**Goal:** Extract all thrift server concerns from `airavata-api` into a new `airavata-thrift-server` Maven module, introduce proto DTOs in `airavata-api`, and set up MapStruct mapping at the thrift handler boundary.
-
-**Architecture:** `airavata-thrift-server` depends on `airavata-api`. Thrift IDL lives in `airavata-thrift-server/src/main/thrift/`. Server bootstrap (AiravataServer), the main API handler (AiravataServerHandler), profile handlers, OrchestratorServerHandler, ThriftAdapter, and Constants move to `airavata-thrift-server`. Data-access handlers (RegistryServerHandler, SharingRegistryServerHandler, CredentialStoreServerHandler) stay in `airavata-api` because services depend on them directly — [...]
-
-**Tech Stack:** Maven, Apache Thrift 0.22.0, Protocol Buffers 4.30.1, MapStruct 1.6.3, protobuf-maven-plugin 3.10.2
-
-**Spec:** `docs/superpowers/specs/2026-03-26-airavata-thrift-server-extraction-design.md`
-
----
-
-## File Structure
-
-### New files (airavata-thrift-server)
-
-| File | Responsibility |
-|------|---------------|
-| `airavata-thrift-server/pom.xml` | Module POM — depends on airavata-api, libthrift, MapStruct |
-| `airavata-thrift-server/src/main/thrift/**` | Moved from `thrift-interface-descriptions/` — all IDL files |
-| `airavata-thrift-server/src/main/java/org/apache/airavata/api/server/AiravataServer.java` | Moved — thrift server bootstrap |
-| `airavata-thrift-server/src/main/java/org/apache/airavata/api/server/util/Constants.java` | Moved — server config constants |
-| `airavata-thrift-server/src/main/java/org/apache/airavata/api/server/handler/AiravataServerHandler.java` | Moved — main API thrift handler |
-| `airavata-thrift-server/src/main/java/org/apache/airavata/api/server/handler/ThriftAdapter.java` | Moved — thrift error translation |
-| `airavata-thrift-server/src/main/java/org/apache/airavata/service/profile/handlers/UserProfileServiceHandler.java` | Moved |
-| `airavata-thrift-server/src/main/java/org/apache/airavata/service/profile/handlers/TenantProfileServiceHandler.java` | Moved |
-| `airavata-thrift-server/src/main/java/org/apache/airavata/service/profile/handlers/IamAdminServicesHandler.java` | Moved |
-| `airavata-thrift-server/src/main/java/org/apache/airavata/service/profile/handlers/GroupManagerServiceHandler.java` | Moved |
-| `airavata-thrift-server/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java` | Moved |
-
-### New files (airavata-api — proto)
-
-| File | Responsibility |
-|------|---------------|
-| `airavata-api/src/main/proto/org/apache/airavata/model/workspace/workspace.proto` | Proto mirror of workspace_model.thrift |
-| `airavata-api/src/main/proto/org/apache/airavata/model/experiment/experiment.proto` | Proto mirror of experiment_model.thrift |
-| `airavata-api/src/main/proto/org/apache/airavata/model/status/status.proto` | Proto mirror of status_models.thrift |
-| ... (one proto per thrift data-model file — 28 total) | Mechanical 1:1 translation |
-| `airavata-api/src/main/proto/org/apache/airavata/model/security/security.proto` | Proto mirror of security_model.thrift |
-| `airavata-api/src/main/proto/org/apache/airavata/model/error/errors.proto` | Proto mirror of airavata_errors.thrift |
-| `airavata-api/src/main/proto/org/apache/airavata/model/commons/commons.proto` | Proto mirror of airavata_commons.thrift |
-
-### Modified files
-
-| File | Change |
-|------|--------|
-| `pom.xml` (root) | Add `airavata-thrift-server` module before `airavata-api` in module order |
-| `airavata-api/pom.xml` | Update thrift compiler path, add protobuf-java + protobuf-maven-plugin, add MapStruct deps |
-
-### Deleted files (from airavata-api)
-
-| File | Reason |
-|------|--------|
-| `airavata-api/src/main/java/org/apache/airavata/api/server/AiravataServer.java` | Moved |
-| `airavata-api/src/main/java/org/apache/airavata/api/server/util/Constants.java` | Moved |
-| `airavata-api/src/main/java/org/apache/airavata/api/server/handler/AiravataServerHandler.java` | Moved |
-| `airavata-api/src/main/java/org/apache/airavata/api/server/handler/ThriftAdapter.java` | Moved |
-| `airavata-api/src/main/java/org/apache/airavata/service/profile/handlers/UserProfileServiceHandler.java` | Moved |
-| `airavata-api/src/main/java/org/apache/airavata/service/profile/handlers/TenantProfileServiceHandler.java` | Moved |
-| `airavata-api/src/main/java/org/apache/airavata/service/profile/handlers/IamAdminServicesHandler.java` | Moved |
-| `airavata-api/src/main/java/org/apache/airavata/service/profile/handlers/GroupManagerServiceHandler.java` | Moved |
-| `airavata-api/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java` | Moved |
-| `thrift-interface-descriptions/` | Moved to airavata-thrift-server/src/main/thrift/ |
-
----
-
-### Task 1: Create git worktree
-
-**Files:**
-- None (git operation)
-
-- [ ] **Step 1: Create worktree branch**
-
-```bash
-cd /Users/yasith/code/artisan/airavata
-git worktree add ../airavata-thrift-extraction -b feat/thrift-server-extraction
-```
-
-- [ ] **Step 2: Verify worktree**
-
-```bash
-cd /Users/yasith/code/artisan/airavata-thrift-extraction
-git branch --show-current
-```
-
-Expected: `feat/thrift-server-extraction`
-
-All subsequent tasks run inside `/Users/yasith/code/artisan/airavata-thrift-extraction/`.
-
----
-
-### Task 2: Create airavata-thrift-server Maven module
-
-**Files:**
-- Create: `airavata-thrift-server/pom.xml`
-- Modify: `pom.xml` (root)
-
-- [ ] **Step 1: Create module directory**
-
-```bash
-mkdir -p airavata-thrift-server/src/main/java
-```
-
-- [ ] **Step 2: Write airavata-thrift-server/pom.xml**
-
-```xml
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.apache.airavata</groupId>
- <artifactId>airavata</artifactId>
- <version>0.21-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>airavata-thrift-server</artifactId>
- <packaging>jar</packaging>
- <name>Airavata Thrift Server</name>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.airavata</groupId>
- <artifactId>airavata-api</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.thrift</groupId>
- <artifactId>libthrift</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- </dependencies>
-</project>
-```
-
-- [ ] **Step 3: Add module to root pom.xml**
-
-In `pom.xml`, add `airavata-thrift-server` AFTER `airavata-api` in the `<modules>` block (it depends on airavata-api):
-
-```xml
- <modules>
- <module>airavata-api</module>
- <module>airavata-thrift-server</module>
- <module>modules/file-server</module>
- <module>modules/agent-framework/agent-service</module>
- <module>modules/research-framework/research-service</module>
- <module>modules/restproxy</module>
- <module>modules/ide-integration</module>
- </modules>
-```
-
-- [ ] **Step 4: Verify module resolves**
-
-```bash
-mvn validate -pl airavata-thrift-server -am --quiet
-```
-
-Expected: BUILD SUCCESS (no compilation yet, just POM validation)
-
-- [ ] **Step 5: Commit**
-
-```bash
-git add airavata-thrift-server/pom.xml pom.xml
-git commit -m "feat: add airavata-thrift-server Maven module scaffold"
-```
-
----
-
-### Task 3: Move thrift IDL files
-
-**Files:**
-- Move: `thrift-interface-descriptions/` → `airavata-thrift-server/src/main/thrift/`
-- Modify: `airavata-api/pom.xml` (update thrift compiler path)
-
-- [ ] **Step 1: Move the directory**
-
-```bash
-git mv thrift-interface-descriptions airavata-thrift-server/src/main/thrift
-```
-
-- [ ] **Step 2: Update thrift compiler path in airavata-api/pom.xml**
-
-In `airavata-api/pom.xml`, find the `maven-antrun-plugin` execution `generate-thrift-sources` and change the thrift input path from:
-
-```xml
-<arg value="${project.basedir}/../thrift-interface-descriptions/stubs_java.thrift" />
-```
-
-to:
-
-```xml
-<arg value="${project.basedir}/../airavata-thrift-server/src/main/thrift/stubs_java.thrift" />
-```
-
-- [ ] **Step 3: Verify thrift compilation still works**
-
-```bash
-mvn generate-sources -pl airavata-api --quiet
-ls airavata-api/target/generated-sources/thrift/org/apache/airavata/api/Airavata.java
-```
-
-Expected: file exists (thrift compiler found the moved IDL and generated code)
-
-- [ ] **Step 4: Commit**
-
-```bash
-git add -A
-git commit -m "refactor: move thrift IDL to airavata-thrift-server/src/main/thrift"
-```
-
----
-
-### Task 4: Move server bootstrap to airavata-thrift-server
-
-**Files:**
-- Move: `airavata-api/src/main/java/org/apache/airavata/api/server/AiravataServer.java` → `airavata-thrift-server/src/main/java/org/apache/airavata/api/server/AiravataServer.java`
-- Move: `airavata-api/src/main/java/org/apache/airavata/api/server/util/Constants.java` → `airavata-thrift-server/src/main/java/org/apache/airavata/api/server/util/Constants.java`
-
-- [ ] **Step 1: Create target directories**
-
-```bash
-mkdir -p airavata-thrift-server/src/main/java/org/apache/airavata/api/server/util
-```
-
-- [ ] **Step 2: Move AiravataServer.java**
-
-```bash
-git mv airavata-api/src/main/java/org/apache/airavata/api/server/AiravataServer.java \
- airavata-thrift-server/src/main/java/org/apache/airavata/api/server/AiravataServer.java
-```
-
-- [ ] **Step 3: Move Constants.java**
-
-```bash
-git mv airavata-api/src/main/java/org/apache/airavata/api/server/util/Constants.java \
- airavata-thrift-server/src/main/java/org/apache/airavata/api/server/util/Constants.java
-```
-
-Note: `Constants.java` contains `API_SERVER_PORT`, `API_SERVER_HOST`, `API_SERVER_MIN_THREADS` — used only by `AiravataServer.java`. The `ThriftAdapter.java` imports `org.apache.airavata.common.utils.Constants` (a different class in commons), NOT this one.
-
-- [ ] **Step 4: Commit**
-
-```bash
-git add -A
-git commit -m "refactor: move AiravataServer and Constants to airavata-thrift-server"
-```
-
----
-
-### Task 5: Move AiravataServerHandler and ThriftAdapter
-
-**Files:**
-- Move: `airavata-api/src/main/java/org/apache/airavata/api/server/handler/AiravataServerHandler.java` → `airavata-thrift-server/...`
-- Move: `airavata-api/src/main/java/org/apache/airavata/api/server/handler/ThriftAdapter.java` → `airavata-thrift-server/...`
-
-- [ ] **Step 1: Create target directory**
-
-```bash
-mkdir -p airavata-thrift-server/src/main/java/org/apache/airavata/api/server/handler
-```
-
-- [ ] **Step 2: Move both files**
-
-```bash
-git mv airavata-api/src/main/java/org/apache/airavata/api/server/handler/AiravataServerHandler.java \
- airavata-thrift-server/src/main/java/org/apache/airavata/api/server/handler/AiravataServerHandler.java
-
-git mv airavata-api/src/main/java/org/apache/airavata/api/server/handler/ThriftAdapter.java \
- airavata-thrift-server/src/main/java/org/apache/airavata/api/server/handler/ThriftAdapter.java
-```
-
-No import changes needed — packages stay the same, and `airavata-thrift-server` depends on `airavata-api` which provides all service classes and handler classes they reference.
-
-- [ ] **Step 3: Commit**
-
-```bash
-git add -A
-git commit -m "refactor: move AiravataServerHandler and ThriftAdapter to airavata-thrift-server"
-```
-
----
-
-### Task 6: Move profile handlers and OrchestratorServerHandler
-
-**Files:**
-- Move: `airavata-api/src/main/java/org/apache/airavata/service/profile/handlers/UserProfileServiceHandler.java`
-- Move: `airavata-api/src/main/java/org/apache/airavata/service/profile/handlers/TenantProfileServiceHandler.java`
-- Move: `airavata-api/src/main/java/org/apache/airavata/service/profile/handlers/IamAdminServicesHandler.java`
-- Move: `airavata-api/src/main/java/org/apache/airavata/service/profile/handlers/GroupManagerServiceHandler.java`
-- Move: `airavata-api/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java`
-
-- [ ] **Step 1: Create target directories**
-
-```bash
-mkdir -p airavata-thrift-server/src/main/java/org/apache/airavata/service/profile/handlers
-mkdir -p airavata-thrift-server/src/main/java/org/apache/airavata/orchestrator/server
-```
-
-- [ ] **Step 2: Move profile handlers**
-
-```bash
-git mv airavata-api/src/main/java/org/apache/airavata/service/profile/handlers/UserProfileServiceHandler.java \
- airavata-thrift-server/src/main/java/org/apache/airavata/service/profile/handlers/UserProfileServiceHandler.java
-
-git mv airavata-api/src/main/java/org/apache/airavata/service/profile/handlers/TenantProfileServiceHandler.java \
- airavata-thrift-server/src/main/java/org/apache/airavata/service/profile/handlers/TenantProfileServiceHandler.java
-
-git mv airavata-api/src/main/java/org/apache/airavata/service/profile/handlers/IamAdminServicesHandler.java \
- airavata-thrift-server/src/main/java/org/apache/airavata/service/profile/handlers/IamAdminServicesHandler.java
-
-git mv airavata-api/src/main/java/org/apache/airavata/service/profile/handlers/GroupManagerServiceHandler.java \
- airavata-thrift-server/src/main/java/org/apache/airavata/service/profile/handlers/GroupManagerServiceHandler.java
-```
-
-- [ ] **Step 3: Move OrchestratorServerHandler**
-
-```bash
-git mv airavata-api/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java \
- airavata-thrift-server/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
-```
-
-- [ ] **Step 4: Commit**
-
-```bash
-git add -A
-git commit -m "refactor: move profile handlers and OrchestratorServerHandler to airavata-thrift-server"
-```
-
----
-
-### Task 7: Verify full build compiles
-
-**Files:**
-- Possibly modify: `airavata-thrift-server/pom.xml` (if missing deps surface)
-
-- [ ] **Step 1: Build airavata-api (should still compile — only lost handler classes it no longer owns)**
-
-```bash
-mvn compile -pl airavata-api --quiet 2>&1 | tail -5
-```
-
-Expected: BUILD SUCCESS. If any code in `airavata-api` still imports the moved handler classes, identify the files and update imports or remove dead references.
-
-- [ ] **Step 2: Build airavata-thrift-server**
-
-```bash
-mvn compile -pl airavata-thrift-server -am 2>&1 | tail -20
-```
-
-Expected: BUILD SUCCESS. If compilation fails due to missing dependencies, add them to `airavata-thrift-server/pom.xml`. Likely candidates:
-- Profile service CPI constants (thrift generated — already available via airavata-api dependency)
-- Helix/ZooKeeper classes used by OrchestratorServerHandler
-- Messaging classes used by AiravataServerHandler
-- Monitoring/background service classes used by AiravataServer
-
-For each missing dependency, add it to `airavata-thrift-server/pom.xml`:
-
-```xml
-<!-- Add as needed based on compilation errors -->
-<dependency>
- <groupId>org.apache.helix</groupId>
- <artifactId>helix-core</artifactId>
-</dependency>
-<dependency>
- <groupId>io.prometheus</groupId>
- <artifactId>simpleclient</artifactId>
-</dependency>
-<!-- etc. -->
-```
-
-- [ ] **Step 3: Fix any compilation errors**
-
-Iterate: read error → add dependency or fix import → rebuild. Continue until BUILD SUCCESS for both modules.
-
-- [ ] **Step 4: Run tests**
-
-```bash
-mvn test -pl airavata-api --quiet 2>&1 | tail -5
-```
-
-Expected: Tests pass (no behavioral changes, only file moves).
-
-- [ ] **Step 5: Commit**
-
-```bash
-git add -A
-git commit -m "fix: resolve airavata-thrift-server compilation dependencies"
-```
-
----
-
-### Task 8: Create proto files — workspace model (representative example)
-
-**Files:**
-- Create: `airavata-api/src/main/proto/org/apache/airavata/model/workspace/workspace.proto`
-
-This task demonstrates the proto translation pattern. All subsequent proto files follow the same rules.
-
-**Translation rules (thrift → proto):**
-- `namespace java X` → `option java_package = "X"; option java_outer_classname = "XProtos";`
-- `struct` → `message`
-- `enum` → `enum` (add `UNKNOWN = 0` sentinel as proto3 requires 0-value)
-- `required/optional` qualifiers are dropped (proto3 has no required/optional)
-- Field numbers match thrift field IDs
-- `string` → `string`, `i32` → `int32`, `i64` → `int64`, `bool` → `bool`, `double` → `double`, `binary` → `bytes`
-- `list<T>` → `repeated T`
-- `map<K,V>` → `map<K,V>`
-- `set<T>` → `repeated T` (proto has no set; enforce uniqueness in application code)
-- Cross-file references: use `import` and fully qualified message names
-
-- [ ] **Step 1: Create directory**
-
-```bash
-mkdir -p airavata-api/src/main/proto/org/apache/airavata/model/workspace
-```
-
-- [ ] **Step 2: Write workspace.proto**
-
-```protobuf
-syntax = "proto3";
-
-package org.apache.airavata.model.workspace;
-
-option java_package = "org.apache.airavata.model.workspace";
-option java_outer_classname = "WorkspaceProtos";
-option java_multiple_files = true;
-
-import "org/apache/airavata/model/commons/commons.proto";
-
-message Group {
- string group_name = 1;
- string description = 2;
-}
-
-message Project {
- string project_id = 1;
- string owner = 2;
- string gateway_id = 3;
- string name = 4;
- string description = 5;
- int64 creation_time = 6;
- repeated string shared_users = 7;
- repeated string shared_groups = 8;
-}
-
-message User {
- string airavata_internal_user_id = 1;
- string user_name = 2;
- string gateway_id = 3;
- string first_name = 4;
- string last_name = 5;
- string email = 6;
-}
-
-enum GatewayApprovalStatus {
- GATEWAY_APPROVAL_STATUS_UNKNOWN = 0;
- REQUESTED = 1;
- APPROVED = 2;
- ACTIVE = 3;
- DEACTIVATED = 4;
- CANCELLED = 5;
- DENIED = 6;
- CREATED = 7;
- DEPLOYED = 8;
-}
-
-message Gateway {
- string airavata_internal_gateway_id = 1;
- string gateway_id = 2;
- GatewayApprovalStatus gateway_approval_status = 3;
- string gateway_name = 4;
- string domain = 5;
- string email_address = 6;
- string gateway_acronym = 7;
- string gateway_url = 8;
- string gateway_public_abstract = 9;
- string review_proposal_description = 10;
- string gateway_admin_first_name = 11;
- string gateway_admin_last_name = 12;
- string gateway_admin_email = 13;
- string identity_server_user_name = 14;
- string identity_server_password_token = 15;
- string declined_reason = 16;
- string oauth_client_id = 17;
- string oauth_client_secret = 18;
- int64 request_creation_time = 19;
- string requester_username = 20;
-}
-
-message GatewayUsageReportingCommand {
- string gateway_id = 1;
- string compute_resource_id = 2;
- string command = 3;
-}
-
-enum NotificationPriority {
- NOTIFICATION_PRIORITY_UNKNOWN = 0;
- LOW = 1;
- NORMAL = 2;
- HIGH = 3;
-}
-
-message Notification {
- string notification_id = 1;
- string gateway_id = 2;
- string title = 3;
- string notification_message = 4;
- int64 creation_time = 5;
- int64 published_time = 6;
- int64 expiration_time = 7;
- NotificationPriority priority = 8;
-}
-```
-
-- [ ] **Step 3: Commit**
-
-```bash
-git add airavata-api/src/main/proto/
-git commit -m "feat: add workspace proto definitions"
-```
-
----
-
-### Task 9: Create proto files — commons and security
-
-**Files:**
-- Create: `airavata-api/src/main/proto/org/apache/airavata/model/commons/commons.proto`
-- Create: `airavata-api/src/main/proto/org/apache/airavata/model/security/security.proto`
-
-These are foundational protos referenced by many others.
-
-- [ ] **Step 1: Create directories**
-
-```bash
-mkdir -p airavata-api/src/main/proto/org/apache/airavata/model/commons
-mkdir -p airavata-api/src/main/proto/org/apache/airavata/model/security
-```
-
-- [ ] **Step 2: Write commons.proto**
-
-Read `airavata-thrift-server/src/main/thrift/airavata-apis/airavata_commons.thrift` to get the exact constants and types. Translate to:
-
-```protobuf
-syntax = "proto3";
-
-package org.apache.airavata.model.commons;
-
-option java_package = "org.apache.airavata.model.commons";
-option java_outer_classname = "CommonsProtos";
-option java_multiple_files = true;
-
-// DEFAULT_ID is a compile-time constant in thrift; in proto it becomes a convention.
-// Consumers should use "DO_NOT_SET_AT_CLIENTS" as the default for ID fields.
-
-message ValidationResults {
- bool validation_state = 1;
- repeated ValidationResult validation_result_list = 2;
-}
-
-message ValidationResult {
- bool result = 1;
- string error_details = 2;
-}
-```
-
-- [ ] **Step 3: Write security.proto**
-
-Read `airavata-thrift-server/src/main/thrift/airavata-apis/security_model.thrift` and translate:
-
-```protobuf
-syntax = "proto3";
-
-package org.apache.airavata.model.security;
-
-option java_package = "org.apache.airavata.model.security";
-option java_outer_classname = "SecurityProtos";
-option java_multiple_files = true;
-
-message AuthzToken {
- string access_token = 1;
- map<string, string> claims_map = 2;
-}
-```
-
-- [ ] **Step 4: Commit**
-
-```bash
-git add airavata-api/src/main/proto/
-git commit -m "feat: add commons and security proto definitions"
-```
-
----
-
-### Task 10: Create proto files — status and experiment models
-
-**Files:**
-- Create: `airavata-api/src/main/proto/org/apache/airavata/model/status/status.proto`
-- Create: `airavata-api/src/main/proto/org/apache/airavata/model/experiment/experiment.proto`
-
-- [ ] **Step 1: Create directories**
-
-```bash
-mkdir -p airavata-api/src/main/proto/org/apache/airavata/model/status
-mkdir -p airavata-api/src/main/proto/org/apache/airavata/model/experiment
-```
-
-- [ ] **Step 2: Write status.proto**
-
-Read `airavata-thrift-server/src/main/thrift/data-models/status_models.thrift` and translate all enums/structs. Example structure:
-
-```protobuf
-syntax = "proto3";
-
-package org.apache.airavata.model.status;
-
-option java_package = "org.apache.airavata.model.status";
-option java_outer_classname = "StatusProtos";
-option java_multiple_files = true;
-
-enum ExperimentState {
- EXPERIMENT_STATE_UNKNOWN = 0;
- CREATED = 1;
- VALIDATED = 2;
- SCHEDULED = 3;
- LAUNCHED = 4;
- EXECUTING = 5;
- CANCELING = 6;
- CANCELED = 7;
- COMPLETED = 8;
- FAILED = 9;
-}
-
-message ExperimentStatus {
- ExperimentState state = 1;
- int64 time_of_state_change = 2;
- string reason = 3;
- int64 status_id = 4;
-}
-
-enum JobState {
- JOB_STATE_UNKNOWN = 0;
- SUBMITTED = 1;
- QUEUED = 2;
- ACTIVE = 3;
- COMPLETE = 4;
- CANCELED = 5;
- FAILED = 6;
- SUSPENDED = 7;
- NON_CRITICAL_FAIL = 8;
-}
-
-message JobStatus {
- JobState job_state = 1;
- int64 time_of_state_change = 2;
- string reason = 3;
- int64 status_id = 4;
-}
-
-enum ProcessState {
- PROCESS_STATE_UNKNOWN = 0;
- CREATED = 1;
- VALIDATED = 2;
- STARTED = 3;
- PRE_PROCESSING = 4;
- CONFIGURING_WORKSPACE = 5;
- INPUT_DATA_STAGING = 6;
- EXECUTING = 7;
- MONITORING = 8;
- OUTPUT_DATA_STAGING = 9;
- POST_PROCESSING = 10;
- COMPLETED = 11;
- FAILED = 12;
- CANCELLING = 13;
- CANCELED = 14;
-}
-
-message ProcessStatus {
- ProcessState state = 1;
- int64 time_of_state_change = 2;
- string reason = 3;
- int64 status_id = 4;
-}
-
-enum TaskState {
- TASK_STATE_UNKNOWN = 0;
- CREATED = 1;
- EXECUTING = 2;
- COMPLETED = 3;
- FAILED = 4;
- CANCELED = 5;
-}
-
-message TaskStatus {
- TaskState state = 1;
- int64 time_of_state_change = 2;
- string reason = 3;
- int64 status_id = 4;
-}
-
-message QueueStatusModel {
- string host_name = 1;
- string queue_name = 2;
- bool queue_up = 3;
- int32 running_jobs = 4;
- int32 queued_jobs = 5;
- int64 time = 6;
-}
-```
-
-- [ ] **Step 3: Write experiment.proto**
-
-Read `airavata-thrift-server/src/main/thrift/data-models/experiment_model.thrift` and translate. Use imports for cross-references:
-
-```protobuf
-syntax = "proto3";
-
-package org.apache.airavata.model.experiment;
-
-option java_package = "org.apache.airavata.model.experiment";
-option java_outer_classname = "ExperimentProtos";
-option java_multiple_files = true;
-
-import "org/apache/airavata/model/commons/commons.proto";
-import "org/apache/airavata/model/status/status.proto";
-// import other model protos as needed for cross-references
-
-enum ExperimentType {
- EXPERIMENT_TYPE_UNKNOWN = 0;
- SINGLE_APPLICATION = 1;
- WORKFLOW = 2;
-}
-
-enum ExperimentSearchFields {
- EXPERIMENT_SEARCH_FIELDS_UNKNOWN = 0;
- EXPERIMENT_NAME = 1;
- EXPERIMENT_DESC = 2;
- APPLICATION_ID = 3;
- FROM_DATE = 4;
- TO_DATE = 5;
- STATUS = 6;
- PROJECT_ID = 7;
- USER_NAME = 8;
- JOB_ID = 9;
-}
-
-enum ProjectSearchFields {
- PROJECT_SEARCH_FIELDS_UNKNOWN = 0;
- PROJECT_NAME = 1;
- PROJECT_DESCRIPTION = 2;
-}
-
-// Continue translating all structs from experiment_model.thrift:
-// UserConfigurationDataModel, ExperimentModel, ExperimentSummaryModel, ExperimentStatistics
-// Follow the same field-number and naming conventions as workspace.proto
-```
-
-- [ ] **Step 4: Commit**
-
-```bash
-git add airavata-api/src/main/proto/
-git commit -m "feat: add status and experiment proto definitions"
-```
-
----
-
-### Task 11: Create remaining proto files
-
-**Files:**
-- Create: one `.proto` file per thrift data-model file (approximately 25 more)
-
-This is mechanical translation work. For each thrift file in `airavata-thrift-server/src/main/thrift/data-models/`, create a corresponding proto file following the exact pattern from Tasks 8-10.
-
-- [ ] **Step 1: Create all remaining proto files**
-
-Complete checklist of thrift files to translate (check off each):
-
-| Thrift File | Proto Output Path |
-|-------------|------------------|
-| `account_provisioning_model.thrift` | `org/apache/airavata/model/appcatalog/accountprovisioning/account_provisioning.proto` |
-| `application_deployment_model.thrift` | `org/apache/airavata/model/appcatalog/appdeployment/app_deployment.proto` |
-| `application_interface_model.thrift` | `org/apache/airavata/model/appcatalog/appinterface/app_interface.proto` |
-| `application_io_models.thrift` | `org/apache/airavata/model/application/io/application_io.proto` |
-| `compute_resource_model.thrift` | `org/apache/airavata/model/appcatalog/computeresource/compute_resource.proto` |
-| `credential_store_models.thrift` | `org/apache/airavata/model/credential/store/credential_store.proto` |
-| `data_movement_models.thrift` | `org/apache/airavata/model/data/movement/data_movement.proto` |
-| `gateway_groups_model.thrift` | `org/apache/airavata/model/appcatalog/gatewaygroups/gateway_groups.proto` |
-| `gateway_resource_profile_model.thrift` | `org/apache/airavata/model/appcatalog/gatewayprofile/gateway_profile.proto` |
-| `group_manager_model.thrift` | `org/apache/airavata/model/group/group_manager.proto` |
-| `group_resource_profile_model.thrift` | `org/apache/airavata/model/appcatalog/groupresourceprofile/group_resource_profile.proto` |
-| `job_model.thrift` | `org/apache/airavata/model/job/job.proto` |
-| `parallelism_model.thrift` | `org/apache/airavata/model/parallelism/parallelism.proto` |
-| `parser_model.thrift` | `org/apache/airavata/model/appcatalog/parser/parser.proto` |
-| `process_model.thrift` | `org/apache/airavata/model/process/process.proto` |
-| `replica_catalog_models.thrift` | `org/apache/airavata/model/data/replica/replica_catalog.proto` |
-| `scheduling_model.thrift` | `org/apache/airavata/model/scheduling/scheduling.proto` |
-| `sharing_models.thrift` | `org/apache/airavata/model/sharing/sharing.proto` |
-| `storage_resource_model.thrift` | `org/apache/airavata/model/appcatalog/storageresource/storage_resource.proto` |
-| `task_model.thrift` | `org/apache/airavata/model/task/task.proto` |
-| `tenant_profile_model.thrift` | `org/apache/airavata/model/tenant/tenant_profile.proto` |
-| `user_profile_model.thrift` | `org/apache/airavata/model/user/user_profile.proto` |
-| `user_resource_profile_model.thrift` | `org/apache/airavata/model/appcatalog/userresourceprofile/user_resource_profile.proto` |
-| `workflow_data_model.thrift` | `org/apache/airavata/model/workflow/data/workflow_data.proto` |
-| `workflow_model.thrift` | `org/apache/airavata/model/workflow/workflow.proto` |
-
-Also translate API-level thrift files:
-
-| Thrift File | Proto Output Path |
-|-------------|------------------|
-| `airavata_errors.thrift` | `org/apache/airavata/model/error/errors.proto` |
-| `db_event_model.thrift` | `org/apache/airavata/model/dbevent/db_event.proto` |
-| `messaging_events.thrift` | `org/apache/airavata/model/messaging/messaging_events.proto` |
-
-For each file:
-1. Read the thrift file
-2. Create the proto file following translation rules from Task 8
-3. Match field numbers to thrift field IDs
-4. Add `UNKNOWN = 0` sentinel to every enum
-5. Use `import` for cross-file references
-6. Set `java_package` matching the thrift `namespace java`
-
-- [ ] **Step 2: Commit**
-
-```bash
-git add airavata-api/src/main/proto/
-git commit -m "feat: add all remaining proto definitions mirroring thrift IDL"
-```
-
----
-
-### Task 12: Set up protoc compilation in airavata-api
-
-**Files:**
-- Modify: `airavata-api/pom.xml`
-
-- [ ] **Step 1: Add protobuf-java dependency**
-
-In `airavata-api/pom.xml` `<dependencies>` section, add:
-
-```xml
- <dependency>
- <groupId>com.google.protobuf</groupId>
- <artifactId>protobuf-java</artifactId>
- </dependency>
-```
-
-- [ ] **Step 2: Add protobuf-maven-plugin**
-
-In `airavata-api/pom.xml` `<build><plugins>` section, add the protobuf-maven-plugin (already in root POM's pluginManagement):
-
-```xml
- <plugin>
- <groupId>io.github.ascopes</groupId>
- <artifactId>protobuf-maven-plugin</artifactId>
- <executions>
- <execution>
- <id>generate-proto-sources</id>
- <goals>
- <goal>generate</goal>
- </goals>
- <configuration>
- <sourceDirectories>
- <sourceDirectory>${project.basedir}/src/main/proto</sourceDirectory>
- </sourceDirectories>
- </configuration>
- </execution>
- </executions>
- </plugin>
-```
-
-- [ ] **Step 3: Verify proto compilation**
-
-```bash
-mvn generate-sources -pl airavata-api --quiet 2>&1 | tail -10
-ls airavata-api/target/generated-sources/protobuf/java/org/apache/airavata/model/workspace/
-```
-
-Expected: generated Java files for the proto messages (Project.java, Gateway.java, etc.)
-
-- [ ] **Step 4: Full compile**
-
-```bash
-mvn compile -pl airavata-api --quiet 2>&1 | tail -5
-```
-
-Expected: BUILD SUCCESS — both thrift generated code and proto generated code compile.
-
-- [ ] **Step 5: Commit**
-
-```bash
-git add airavata-api/pom.xml
-git commit -m "build: add protobuf-java dependency and protoc compilation to airavata-api"
-```
-
----
-
-### Task 13: Add MapStruct to airavata-thrift-server
-
-**Files:**
-- Modify: `airavata-thrift-server/pom.xml`
-- Modify: `pom.xml` (root — add MapStruct to dependency management)
-
-- [ ] **Step 1: Add MapStruct to root pom.xml dependency management**
-
-In `pom.xml` root, add to `<dependencyManagement><dependencies>`:
-
-```xml
- <dependency>
- <groupId>org.mapstruct</groupId>
- <artifactId>mapstruct</artifactId>
- <version>1.6.3</version>
- </dependency>
- <dependency>
- <groupId>org.mapstruct</groupId>
- <artifactId>mapstruct-processor</artifactId>
- <version>1.6.3</version>
- </dependency>
-```
-
-- [ ] **Step 2: Add MapStruct dependency to airavata-thrift-server/pom.xml**
-
-Add to `<dependencies>`:
-
-```xml
- <dependency>
- <groupId>org.mapstruct</groupId>
- <artifactId>mapstruct</artifactId>
- </dependency>
-```
-
-Add to `<build><plugins>`:
-
-```xml
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <annotationProcessorPaths>
- <path>
- <groupId>org.mapstruct</groupId>
- <artifactId>mapstruct-processor</artifactId>
- <version>1.6.3</version>
- </path>
- </annotationProcessorPaths>
- </configuration>
- </plugin>
- </plugins>
- </build>
-```
-
-- [ ] **Step 3: Verify build**
-
-```bash
-mvn compile -pl airavata-thrift-server -am --quiet 2>&1 | tail -5
-```
-
-Expected: BUILD SUCCESS
-
-- [ ] **Step 4: Commit**
-
-```bash
-git add pom.xml airavata-thrift-server/pom.xml
-git commit -m "build: add MapStruct dependency to airavata-thrift-server"
-```
-
----
-
-### Task 14: Create representative MapStruct mapper
-
-**Files:**
-- Create: `airavata-thrift-server/src/main/java/org/apache/airavata/api/server/mapper/WorkspaceMapper.java`
-
-This establishes the mapper pattern. Full mapper coverage is built incrementally as services are converted to proto types (follow-up work).
-
-- [ ] **Step 1: Create mapper directory**
-
-```bash
-mkdir -p airavata-thrift-server/src/main/java/org/apache/airavata/api/server/mapper
-```
-
-- [ ] **Step 2: Write WorkspaceMapper.java**
-
-```java
-package org.apache.airavata.api.server.mapper;
-
-import org.apache.airavata.model.workspace.Gateway;
-import org.apache.airavata.model.workspace.Notification;
-import org.apache.airavata.model.workspace.Project;
-import org.mapstruct.Mapper;
-import org.mapstruct.Mapping;
-import org.mapstruct.factory.Mappers;
-
-/**
- * Maps between thrift-generated workspace types and proto-generated workspace types.
- *
- * <p>Thrift types use camelCase field accessors (getGatewayId()).
- * Proto types use snake_case with standard proto getters (getGatewayId()).
- * MapStruct handles the mapping automatically when accessor names match.
- */
-@Mapper
-public interface WorkspaceMapper {
- WorkspaceMapper INSTANCE = Mappers.getMapper(WorkspaceMapper.class);
-
- // --- Project ---
- org.apache.airavata.model.workspace.ProjectProtos.Project toProto(Project thrift);
- Project toThrift(org.apache.airavata.model.workspace.ProjectProtos.Project proto);
-
- // --- Gateway ---
- org.apache.airavata.model.workspace.WorkspaceProtos.Gateway toProtoGateway(Gateway thrift);
- Gateway toThriftGateway(org.apache.airavata.model.workspace.WorkspaceProtos.Gateway proto);
-}
-```
-
-Note: The exact proto class names depend on how protoc generates them (based on `java_multiple_files`, `java_outer_classname`). Adjust class references after verifying proto compilation output from Task 12.
-
-- [ ] **Step 3: Verify compilation**
-
-```bash
-mvn compile -pl airavata-thrift-server -am --quiet 2>&1 | tail -10
-```
-
-If proto class names don't match, check `airavata-api/target/generated-sources/` for exact class names and update mapper imports.
-
-- [ ] **Step 4: Commit**
-
-```bash
-git add airavata-thrift-server/src/main/java/org/apache/airavata/api/server/mapper/
-git commit -m "feat: add representative MapStruct mapper for workspace types"
-```
-
----
-
-### Task 15: Final build verification and cleanup
-
-**Files:**
-- None (verification only)
-
-- [ ] **Step 1: Full project build**
-
-```bash
-mvn clean compile -T4 2>&1 | tail -20
-```
-
-Expected: BUILD SUCCESS for all modules
-
-- [ ] **Step 2: Run tests**
-
-```bash
-mvn test -pl airavata-api,airavata-thrift-server 2>&1 | tail -20
-```
-
-Expected: All tests pass
-
-- [ ] **Step 3: Verify no remaining handler references in airavata-api**
-
-```bash
-grep -r "AiravataServer\b" airavata-api/src/main/java/ --include="*.java" | grep -v "import"
-grep -r "AiravataServerHandler\b" airavata-api/src/main/java/ --include="*.java" | grep -v "import"
-```
-
-Expected: No matches (these classes have moved). If there are stale references, remove them.
-
-- [ ] **Step 4: Commit**
-
-```bash
-git add -A
-git commit -m "chore: final cleanup after thrift server extraction"
-```
-
----
-
-## Deferred Work (Future Plans)
-
-These items are explicitly out of scope for this plan but are required for full thrift removal from `airavata-api`:
-
-1. **Extract data access from Registry/Sharing/Credential handlers** — Create non-thrift interfaces in `airavata-api`, refactor services to use them, move handler implementations to `airavata-thrift-server`
-2. **Convert service signatures to proto types** — Change all 14 service classes to accept/return proto types instead of thrift types
-3. **Move thrift code generation to airavata-thrift-server** — Once `airavata-api` no longer imports any thrift types
-4. **Remove libthrift dependency from airavata-api** — Final step after all thrift references are eliminated
-5. **Full MapStruct mapper coverage** — One mapper per domain (experiment, credential, sharing, etc.)
diff --git a/docs/superpowers/specs/2026-03-26-airavata-thrift-server-extraction-design.md b/docs/superpowers/specs/2026-03-26-airavata-thrift-server-extraction-design.md
deleted file mode 100644
index c792b0596e..0000000000
--- a/docs/superpowers/specs/2026-03-26-airavata-thrift-server-extraction-design.md
+++ /dev/null
@@ -1,190 +0,0 @@
-# Airavata Thrift Server Extraction Design
-
-**Date:** 2026-03-26
-**Status:** Draft
-
-## Goal
-
-Extract all thrift server concerns from `airavata-api` into a new `airavata-thrift-server` Maven module. Introduce protobuf DTOs as the canonical data types in the service layer, making `airavata-api` completely thrift-free. MapStruct mappers in `airavata-thrift-server` bridge proto and thrift types at the handler boundary.
-
-## Repository Layout (Post-Extraction)
-
-```
-airavata/
-├── airavata-thrift-server/ # NEW — all thrift concerns
-│ ├── pom.xml
-│ └── src/main/
-│ ├── java/
-│ │ └── org/apache/airavata/
-│ │ ├── server/ # AiravataServer.java (TMultiplexedProcessor bootstrap)
-│ │ ├── handler/ # All 9 thrift handlers
-│ │ └── mapper/ # MapStruct mappers (proto <-> thrift)
-│ └── thrift/ # Moved from thrift-interface-descriptions/
-│ ├── airavata-apis/
-│ ├── base-api/
-│ ├── data-models/
-│ ├── service-cpis/
-│ └── stubs_java.thrift (etc.)
-│
-├── airavata-api/ # SLIMMED — services + background processes
-│ ├── pom.xml
-│ └── src/main/
-│ ├── java/
-│ │ └── org/apache/airavata/
-│ │ ├── service/ # Business logic services
-│ │ ├── repository/ # JPA data access
-│ │ └── background/ # Helix, monitors, event managers, etc.
-│ └── proto/ # NEW — .proto files mirroring thrift IDL
-│ └── org/apache/airavata/
-│ ├── model/
-│ ├── api/
-│ ├── registry/
-│ ├── credential/
-│ ├── sharing/
-│ └── ...
-│
-├── modules/ # Unchanged
-└── pom.xml # Root — adds airavata-thrift-server module
-```
-
-## Dependency Graph
-
-```
-airavata-thrift-server
-├── depends on: airavata-api (service layer + proto generated classes)
-├── depends on: libthrift (Apache Thrift runtime)
-├── owns: thrift IDL compilation -> generated thrift Java classes
-├── owns: MapStruct mappers (proto <-> thrift)
-└── owns: TMultiplexedProcessor, TThreadPoolServer bootstrap
-
-airavata-api
-├── depends on: protobuf-java (for generated proto classes)
-├── owns: service layer (o.a.a.service.*)
-├── owns: repository / data access layer
-├── owns: background services (Helix, monitors, event managers)
-├── owns: proto definitions + protoc generation
-└── NO thrift dependency
-```
-
-## Thrift Services Moved (All 9)
-
-| Service Name | Handler Class |
-|---------------------|------------------------------------|
-| Airavata | AiravataServerHandler |
-| RegistryService | RegistryServerHandler |
-| SharingRegistry | SharingRegistryServerHandler |
-| CredentialStore | CredentialStoreServerHandler |
-| UserProfile | UserProfileServiceHandler |
-| TenantProfile | TenantProfileServiceHandler |
-| IamAdminServices | IamAdminServicesHandler |
-| GroupManager | GroupManagerServiceHandler |
-| Orchestrator | OrchestratorServerHandler |
-
-## What Stays in `airavata-api`
-
-### Services (refactored to proto types)
-All 14 business logic services: ExperimentService, ApplicationCatalogService, CredentialService, GatewayService, GatewayResourceProfileService, GroupResourceProfileService, NotificationService, ParserService, ProjectService, ResourceService, UserResourceProfileService, DataProductService, ResourceSharingService, SSHAccountService.
-
-### Data Access
-JPA entities, repositories, Hibernate config, database initialization (ExpCatalogDB, AppCatalogDB, ReplicaCatalogDB, WorkflowCatalogDB, CredentialStoreDB, UserProfileCatalogDB).
-
-### Background Services (retains its own main entry point)
-- DB Event Manager
-- Monitoring Server (Prometheus on port 9097)
-- Cluster Status Monitor
-- Data Interpreter
-- Process Rescheduler
-- Helix Controller/Participant
-- Workflow Managers (Pre/Post/Parser)
-- Job Monitors (Email + Real-time)
-
-### Removed from `airavata-api`
-- `AiravataServer.java`
-- All 9 thrift handler classes
-- Thrift IDL files
-- `libthrift` dependency
-- Thrift code generation Maven plugin config
-
-## Proto File Strategy
-
-Proto files mirror thrift IDL 1:1 — same fields, same nesting, same enums. Mechanical translation, not a redesign.
-
-### Conventions
-- Field numbers match thrift field IDs where possible
-- Proto uses `snake_case` per protobuf convention; MapStruct handles naming differences
-- No proto service definitions — only message types (no gRPC yet)
-- Package structure mirrors thrift: `org.apache.airavata.model.*`, `org.apache.airavata.api.*`, etc.
-- Generated via protoc Maven plugin in `airavata-api`
-
-### Example
-
-Thrift:
-```thrift
-struct ExperimentModel {
- 1: string experimentId,
- 2: string projectId,
- 3: string gatewayId,
- 4: ExperimentType experimentType,
- 5: string userName,
- 6: string experimentName,
- 7: i64 creationTime
-}
-```
-
-Proto:
-```protobuf
-message ExperimentModel {
- string experiment_id = 1;
- string project_id = 2;
- string gateway_id = 3;
- ExperimentType experiment_type = 4;
- string user_name = 5;
- string experiment_name = 6;
- int64 creation_time = 7;
-}
-```
-
-## Handler Conversion Pattern
-
-```
-Thrift Client
- -> TMultiplexedProcessor (airavata-thrift-server)
- -> ThriftHandler.method(ThriftRequest)
- -> MapStruct: ThriftRequest -> ProtoDTO
- -> Service.method(ProtoDTO) (airavata-api)
- -> returns ProtoResult
- -> MapStruct: ProtoResult -> ThriftResponse
- -> returns ThriftResponse
-```
-
-### Example — createExperiment
-
-```java
-// In airavata-thrift-server: AiravataServerHandler
-public String createExperiment(AuthzToken authzToken, String gatewayId, ExperimentModel experiment) {
- var protoExperiment = ExperimentMapper.INSTANCE.toProto(experiment);
- var protoAuthz = AuthzTokenMapper.INSTANCE.toProto(authzToken);
- var result = experimentService.createExperiment(protoAuthz, gatewayId, protoExperiment);
- return result;
-}
-```
-
-### MapStruct Mapper
-
-```java
-@Mapper
-public interface ExperimentMapper {
- ExperimentMapper INSTANCE = Mappers.getMapper(ExperimentMapper.class);
- ExperimentProto toProto(ExperimentModel thriftModel);
- ExperimentModel toThrift(ExperimentProto proto);
-}
-```
-
-## Build Order
-
-1. `airavata-api` builds first — compiles proto files, produces service classes + proto generated code
-2. `airavata-thrift-server` builds second — compiles thrift IDL, compiles handlers + mappers against airavata-api
-
-## Development
-
-Work is done in a git worktree off the main `airavata` repo for isolation. Thrift IDL content is unchanged (no SDK breakage). Thrift spec changes are a separate future effort.
diff --git a/integration-tests/src/test/java/org/apache/airavata/integration/BackgroundServiceHealthTest.java b/integration-tests/src/test/java/org/apache/airavata/integration/BackgroundServiceHealthTest.java
index 14d0aff42d..677f53e8eb 100644
--- a/integration-tests/src/test/java/org/apache/airavata/integration/BackgroundServiceHealthTest.java
+++ b/integration-tests/src/test/java/org/apache/airavata/integration/BackgroundServiceHealthTest.java
@@ -73,7 +73,9 @@ class BackgroundServiceHealthTest {
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
assertEquals(200, response.statusCode(),
"Could not reach /health/services — got HTTP " + response.statusCode());
- cachedRoot = objectMapper.readTree(response.body());
+ JsonNode body = objectMapper.readTree(response.body());
+ cachedRoot = body.get("services");
+ assertNotNull(cachedRoot, "Expected 'services' key in /health/services response");
}
static Stream<String> expectedServices() {
diff --git a/integration-tests/src/test/java/org/apache/airavata/integration/ServiceHealthEndpointTest.java b/integration-tests/src/test/java/org/apache/airavata/integration/ServiceHealthEndpointTest.java
index 219ff00d35..b9b12048e9 100644
--- a/integration-tests/src/test/java/org/apache/airavata/integration/ServiceHealthEndpointTest.java
+++ b/integration-tests/src/test/java/org/apache/airavata/integration/ServiceHealthEndpointTest.java
@@ -82,7 +82,9 @@ class ServiceHealthEndpointTest {
JsonNode root = objectMapper.readTree(response.body());
assertNotNull(root, "Response body could not be parsed as JSON");
assertTrue(root.isObject(), "Expected JSON object at root, got: " + root.getNodeType());
- assertFalse(root.isEmpty(), "Expected at least one service entry in the response");
+ JsonNode services = root.get("services");
+ assertNotNull(services, "Expected 'services' key in response, got: " + root);
+ assertFalse(services.isEmpty(), "Expected at least one service entry in the response");
}
@Test
@@ -91,7 +93,9 @@ class ServiceHealthEndpointTest {
assertEquals(200, response.statusCode());
JsonNode root = objectMapper.readTree(response.body());
- Iterator<Map.Entry<String, JsonNode>> fields = root.fields();
+ JsonNode services = root.get("services");
+ assertNotNull(services, "Expected 'services' key in response");
+ Iterator<Map.Entry<String, JsonNode>> fields = services.fields();
while (fields.hasNext()) {
Map.Entry<String, JsonNode> entry = fields.next();
String serviceName = entry.getKey();