This is an automated email from the ASF dual-hosted git repository.

yasith pushed a commit to branch feat/thrift-server-extraction
in repository https://gitbox.apache.org/repos/asf/airavata.git

commit af40880f3c4de6a68e2e30a7b9455988dc0a22c5
Author: yasithdev <[email protected]>
AuthorDate: Thu Mar 26 13:51:35 2026 -0500

    docs: add airavata-thrift-server extraction implementation plan
---
 ...2026-03-26-airavata-thrift-server-extraction.md | 1090 ++++++++++++++++++++
 1 file changed, 1090 insertions(+)

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
new file mode 100644
index 0000000000..837d304414
--- /dev/null
+++ b/docs/superpowers/plans/2026-03-26-airavata-thrift-server-extraction.md
@@ -0,0 +1,1090 @@
+# 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.)


Reply via email to