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

yasith pushed a commit to branch feat/grpc-armeria-migration
in repository https://gitbox.apache.org/repos/asf/airavata.git

commit 63c808d30c3277947e98fbad30e33f90836f45a3
Author: yasithdev <[email protected]>
AuthorDate: Wed Apr 1 13:24:43 2026 -0400

    feat: extract compute-service as independent Maven module
    
    Move compute service layer (service/) into a new compute-service module,
    following the same pattern as storage-service and credential-service.
    Model, repository, mapper, task, and util packages remain in airavata-api
    as shared domain types.
    
    ResourceService now implements the ComputeResourceProvider SPI with
    @Override on all contract methods plus new delegate methods for
    getGatewayResourceProfile and getGroupComputeResourcePreference.
    
    ExperimentService decoupled from concrete GroupResourceProfileService
    via a GroupResourceProfileListProvider functional interface, wired at
    the server level in ServiceWiringConfig.
---
 airavata-api/agent-service/pom.xml                 |   5 +
 airavata-api/compute-service/pom.xml               | 140 +++++++++++++++++++++
 .../compute/service/ApplicationCatalogService.java |   0
 .../service/GatewayResourceProfileService.java     |   0
 .../service/GroupResourceProfileService.java       |   0
 .../airavata/compute/service/ParserService.java    |   0
 .../airavata/compute/service/ResourceService.java  |  34 ++++-
 .../service/UserResourceProfileService.java        |   0
 .../service/ApplicationCatalogServiceTest.java     |   0
 .../service/GatewayResourceProfileServiceTest.java |   0
 .../service/GroupResourceProfileServiceTest.java   |   0
 .../compute/service/ParserServiceTest.java         |   0
 .../compute/service/ResourceServiceTest.java       |   0
 .../service/UserResourceProfileServiceTest.java    |   0
 .../execution/service/ExperimentService.java       |  22 +++-
 airavata-server/pom.xml                            |   5 +
 .../server/config/ServiceWiringConfig.java         |  39 ++++++
 pom.xml                                            |   1 +
 18 files changed, 239 insertions(+), 7 deletions(-)

diff --git a/airavata-api/agent-service/pom.xml 
b/airavata-api/agent-service/pom.xml
index 98cbcb4bbb..6915dadc7f 100644
--- a/airavata-api/agent-service/pom.xml
+++ b/airavata-api/agent-service/pom.xml
@@ -119,6 +119,11 @@ under the License.
         </exclusion>
       </exclusions>
     </dependency>
+    <dependency>
+      <groupId>org.apache.airavata</groupId>
+      <artifactId>compute-service</artifactId>
+      <version>${project.version}</version>
+    </dependency>
     <dependency>
       <groupId>org.apache.airavata</groupId>
       <artifactId>airavata-api</artifactId>
diff --git a/airavata-api/compute-service/pom.xml 
b/airavata-api/compute-service/pom.xml
new file mode 100644
index 0000000000..84b7b3df7f
--- /dev/null
+++ b/airavata-api/compute-service/pom.xml
@@ -0,0 +1,140 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<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>compute-service</artifactId>
+    <name>Compute Service</name>
+    <description>Compute resource management service 
implementation</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.airavata</groupId>
+            <artifactId>airavata-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.airavata</groupId>
+            <artifactId>credential-service</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <!-- Spring (optional in airavata-api, needed here for 
@Component/@Service) -->
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-autoconfigure</artifactId>
+            <optional>true</optional>
+        </dependency>
+
+        <!-- MapStruct (needed for ComputeMapper) -->
+        <dependency>
+            <groupId>org.mapstruct</groupId>
+            <artifactId>mapstruct</artifactId>
+        </dependency>
+
+        <!-- Test dependencies -->
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <version>5.23.0</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-junit-jupiter</artifactId>
+            <version>5.23.0</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.testcontainers</groupId>
+            <artifactId>testcontainers</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.testcontainers</groupId>
+            <artifactId>mariadb</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.testcontainers</groupId>
+            <artifactId>junit-jupiter</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.platform</groupId>
+            <artifactId>junit-platform-launcher</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <!-- MapStruct annotation processor -->
+            <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>
+
+            <!-- Run Tests -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <inherited>true</inherited>
+                <configuration>
+                    <environmentVariables>
+                        
<TESTCONTAINERS_RYUK_DISABLED>true</TESTCONTAINERS_RYUK_DISABLED>
+                    </environmentVariables>
+                </configuration>
+            </plugin>
+        </plugins>
+
+        
<testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
+        
<testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
+    </build>
+
+</project>
diff --git 
a/airavata-api/src/main/java/org/apache/airavata/compute/service/ApplicationCatalogService.java
 
b/airavata-api/compute-service/src/main/java/org/apache/airavata/compute/service/ApplicationCatalogService.java
similarity index 100%
rename from 
airavata-api/src/main/java/org/apache/airavata/compute/service/ApplicationCatalogService.java
rename to 
airavata-api/compute-service/src/main/java/org/apache/airavata/compute/service/ApplicationCatalogService.java
diff --git 
a/airavata-api/src/main/java/org/apache/airavata/compute/service/GatewayResourceProfileService.java
 
b/airavata-api/compute-service/src/main/java/org/apache/airavata/compute/service/GatewayResourceProfileService.java
similarity index 100%
rename from 
airavata-api/src/main/java/org/apache/airavata/compute/service/GatewayResourceProfileService.java
rename to 
airavata-api/compute-service/src/main/java/org/apache/airavata/compute/service/GatewayResourceProfileService.java
diff --git 
a/airavata-api/src/main/java/org/apache/airavata/compute/service/GroupResourceProfileService.java
 
b/airavata-api/compute-service/src/main/java/org/apache/airavata/compute/service/GroupResourceProfileService.java
similarity index 100%
rename from 
airavata-api/src/main/java/org/apache/airavata/compute/service/GroupResourceProfileService.java
rename to 
airavata-api/compute-service/src/main/java/org/apache/airavata/compute/service/GroupResourceProfileService.java
diff --git 
a/airavata-api/src/main/java/org/apache/airavata/compute/service/ParserService.java
 
b/airavata-api/compute-service/src/main/java/org/apache/airavata/compute/service/ParserService.java
similarity index 100%
rename from 
airavata-api/src/main/java/org/apache/airavata/compute/service/ParserService.java
rename to 
airavata-api/compute-service/src/main/java/org/apache/airavata/compute/service/ParserService.java
diff --git 
a/airavata-api/src/main/java/org/apache/airavata/compute/service/ResourceService.java
 
b/airavata-api/compute-service/src/main/java/org/apache/airavata/compute/service/ResourceService.java
similarity index 96%
rename from 
airavata-api/src/main/java/org/apache/airavata/compute/service/ResourceService.java
rename to 
airavata-api/compute-service/src/main/java/org/apache/airavata/compute/service/ResourceService.java
index 4f777a34df..da5856183b 100644
--- 
a/airavata-api/src/main/java/org/apache/airavata/compute/service/ResourceService.java
+++ 
b/airavata-api/compute-service/src/main/java/org/apache/airavata/compute/service/ResourceService.java
@@ -22,6 +22,7 @@ package org.apache.airavata.compute.service;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
+import org.apache.airavata.compute.spi.ComputeResourceProvider;
 import org.apache.airavata.compute.util.AgentAdaptor;
 import org.apache.airavata.compute.util.AgentException;
 import org.apache.airavata.execution.handler.RegistryServerHandler;
@@ -50,7 +51,7 @@ import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
 
 @Service
-public class ResourceService {
+public class ResourceService implements ComputeResourceProvider {
 
     private static final Logger logger = 
LoggerFactory.getLogger(ResourceService.class);
 
@@ -76,6 +77,7 @@ public class ResourceService {
         }
     }
 
+    @Override
     public ComputeResourceDescription getComputeResource(String 
computeResourceId) throws ServiceException {
         try {
             return registryHandler.getComputeResource(computeResourceId);
@@ -84,6 +86,7 @@ public class ResourceService {
         }
     }
 
+    @Override
     public Map<String, String> getAllComputeResourceNames() throws 
ServiceException {
         try {
             return registryHandler.getAllComputeResourceNames();
@@ -177,6 +180,7 @@ public class ResourceService {
         }
     }
 
+    @Override
     public LOCALSubmission getLocalJobSubmission(String jobSubmissionId) 
throws ServiceException {
         try {
             return registryHandler.getLocalJobSubmission(jobSubmissionId);
@@ -203,6 +207,7 @@ public class ResourceService {
         }
     }
 
+    @Override
     public SSHJobSubmission getSSHJobSubmission(String jobSubmissionId) throws 
ServiceException {
         try {
             return registryHandler.getSSHJobSubmission(jobSubmissionId);
@@ -221,6 +226,7 @@ public class ResourceService {
         }
     }
 
+    @Override
     public CloudJobSubmission getCloudJobSubmission(String jobSubmissionId) 
throws ServiceException {
         try {
             return registryHandler.getCloudJobSubmission(jobSubmissionId);
@@ -240,6 +246,7 @@ public class ResourceService {
         }
     }
 
+    @Override
     public UnicoreJobSubmission getUnicoreJobSubmission(String 
jobSubmissionId) throws ServiceException {
         try {
             return registryHandler.getUnicoreJobSubmission(jobSubmissionId);
@@ -428,6 +435,7 @@ public class ResourceService {
         }
     }
 
+    @Override
     public ResourceJobManager getResourceJobManager(String 
resourceJobManagerId) throws ServiceException {
         try {
             return registryHandler.getResourceJobManager(resourceJobManagerId);
@@ -456,6 +464,30 @@ public class ResourceService {
         }
     }
 
+    // 
-------------------------------------------------------------------------
+    // ComputeResourceProvider SPI delegates
+    // 
-------------------------------------------------------------------------
+
+    @Override
+    public GatewayResourceProfile getGatewayResourceProfile(String gatewayId) 
throws ServiceException {
+        try {
+            return registryHandler.getGatewayResourceProfile(gatewayId);
+        } catch (Exception e) {
+            throw new ServiceException("Error while retrieving gateway 
resource profile: " + e.getMessage(), e);
+        }
+    }
+
+    @Override
+    public GroupComputeResourcePreference getGroupComputeResourcePreference(
+            String computeResourceId, String groupResourceProfileId) throws 
ServiceException {
+        try {
+            return 
registryHandler.getGroupComputeResourcePreference(computeResourceId, 
groupResourceProfileId);
+        } catch (Exception e) {
+            throw new ServiceException(
+                    "Error while retrieving group compute resource preference: 
" + e.getMessage(), e);
+        }
+    }
+
     // 
-------------------------------------------------------------------------
     // Storage Info
     // 
-------------------------------------------------------------------------
diff --git 
a/airavata-api/src/main/java/org/apache/airavata/compute/service/UserResourceProfileService.java
 
b/airavata-api/compute-service/src/main/java/org/apache/airavata/compute/service/UserResourceProfileService.java
similarity index 100%
rename from 
airavata-api/src/main/java/org/apache/airavata/compute/service/UserResourceProfileService.java
rename to 
airavata-api/compute-service/src/main/java/org/apache/airavata/compute/service/UserResourceProfileService.java
diff --git 
a/airavata-api/src/test/java/org/apache/airavata/compute/service/ApplicationCatalogServiceTest.java
 
b/airavata-api/compute-service/src/test/java/org/apache/airavata/compute/service/ApplicationCatalogServiceTest.java
similarity index 100%
rename from 
airavata-api/src/test/java/org/apache/airavata/compute/service/ApplicationCatalogServiceTest.java
rename to 
airavata-api/compute-service/src/test/java/org/apache/airavata/compute/service/ApplicationCatalogServiceTest.java
diff --git 
a/airavata-api/src/test/java/org/apache/airavata/compute/service/GatewayResourceProfileServiceTest.java
 
b/airavata-api/compute-service/src/test/java/org/apache/airavata/compute/service/GatewayResourceProfileServiceTest.java
similarity index 100%
rename from 
airavata-api/src/test/java/org/apache/airavata/compute/service/GatewayResourceProfileServiceTest.java
rename to 
airavata-api/compute-service/src/test/java/org/apache/airavata/compute/service/GatewayResourceProfileServiceTest.java
diff --git 
a/airavata-api/src/test/java/org/apache/airavata/compute/service/GroupResourceProfileServiceTest.java
 
b/airavata-api/compute-service/src/test/java/org/apache/airavata/compute/service/GroupResourceProfileServiceTest.java
similarity index 100%
rename from 
airavata-api/src/test/java/org/apache/airavata/compute/service/GroupResourceProfileServiceTest.java
rename to 
airavata-api/compute-service/src/test/java/org/apache/airavata/compute/service/GroupResourceProfileServiceTest.java
diff --git 
a/airavata-api/src/test/java/org/apache/airavata/compute/service/ParserServiceTest.java
 
b/airavata-api/compute-service/src/test/java/org/apache/airavata/compute/service/ParserServiceTest.java
similarity index 100%
rename from 
airavata-api/src/test/java/org/apache/airavata/compute/service/ParserServiceTest.java
rename to 
airavata-api/compute-service/src/test/java/org/apache/airavata/compute/service/ParserServiceTest.java
diff --git 
a/airavata-api/src/test/java/org/apache/airavata/compute/service/ResourceServiceTest.java
 
b/airavata-api/compute-service/src/test/java/org/apache/airavata/compute/service/ResourceServiceTest.java
similarity index 100%
rename from 
airavata-api/src/test/java/org/apache/airavata/compute/service/ResourceServiceTest.java
rename to 
airavata-api/compute-service/src/test/java/org/apache/airavata/compute/service/ResourceServiceTest.java
diff --git 
a/airavata-api/src/test/java/org/apache/airavata/compute/service/UserResourceProfileServiceTest.java
 
b/airavata-api/compute-service/src/test/java/org/apache/airavata/compute/service/UserResourceProfileServiceTest.java
similarity index 100%
rename from 
airavata-api/src/test/java/org/apache/airavata/compute/service/UserResourceProfileServiceTest.java
rename to 
airavata-api/compute-service/src/test/java/org/apache/airavata/compute/service/UserResourceProfileServiceTest.java
diff --git 
a/airavata-api/src/main/java/org/apache/airavata/execution/service/ExperimentService.java
 
b/airavata-api/src/main/java/org/apache/airavata/execution/service/ExperimentService.java
index 0d2ca88f37..8df022bd13 100644
--- 
a/airavata-api/src/main/java/org/apache/airavata/execution/service/ExperimentService.java
+++ 
b/airavata-api/src/main/java/org/apache/airavata/execution/service/ExperimentService.java
@@ -27,7 +27,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.stream.Collectors;
-import org.apache.airavata.compute.service.GroupResourceProfileService;
 import org.apache.airavata.execution.handler.RegistryServerHandler;
 import org.apache.airavata.messaging.service.EventPublisher;
 import org.apache.airavata.model.application.io.proto.OutputDataObjectType;
@@ -65,7 +64,18 @@ public class ExperimentService {
     private final RegistryServerHandler registryHandler;
     private final SharingRegistryServerHandler sharingHandler;
     private final EventPublisher eventPublisher;
-    private GroupResourceProfileService groupResourceProfileService;
+    private GroupResourceProfileListProvider groupResourceProfileListProvider;
+
+    /**
+     * Functional interface for providing accessible group resource profiles.
+     * This decouples ExperimentService from the concrete 
GroupResourceProfileService
+     * in the compute-service module.
+     */
+    @FunctionalInterface
+    public interface GroupResourceProfileListProvider {
+        
List<org.apache.airavata.model.appcatalog.groupresourceprofile.proto.GroupResourceProfile>
+                getGroupResourceList(RequestContext ctx, String gatewayId) 
throws ServiceException;
+    }
 
     public ExperimentService(
             RegistryServerHandler registryHandler,
@@ -76,8 +86,8 @@ public class ExperimentService {
         this.eventPublisher = eventPublisher;
     }
 
-    public void setGroupResourceProfileService(GroupResourceProfileService 
groupResourceProfileService) {
-        this.groupResourceProfileService = groupResourceProfileService;
+    public void 
setGroupResourceProfileListProvider(GroupResourceProfileListProvider 
groupResourceProfileListProvider) {
+        this.groupResourceProfileListProvider = 
groupResourceProfileListProvider;
     }
 
     public String createExperiment(RequestContext ctx, ExperimentModel 
experiment) throws ServiceException {
@@ -612,8 +622,8 @@ public class ExperimentService {
             // For backwards compatibility, if there is no 
groupResourceProfileId, pick one
             if 
(experiment.getUserConfigurationData().getGroupResourceProfileId().isEmpty()) {
                 
List<org.apache.airavata.model.appcatalog.groupresourceprofile.proto.GroupResourceProfile>
-                        accessibleGroupResourceProfiles = 
groupResourceProfileService != null
-                                ? 
groupResourceProfileService.getGroupResourceList(ctx, gatewayId)
+                        accessibleGroupResourceProfiles = 
groupResourceProfileListProvider != null
+                                ? 
groupResourceProfileListProvider.getGroupResourceList(ctx, gatewayId)
                                 : List.of();
                 if (!accessibleGroupResourceProfiles.isEmpty()) {
                     final String groupResourceProfileId =
diff --git a/airavata-server/pom.xml b/airavata-server/pom.xml
index e9d46425f7..52b8f740eb 100644
--- a/airavata-server/pom.xml
+++ b/airavata-server/pom.xml
@@ -73,6 +73,11 @@ under the License.
             <artifactId>storage-service</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.airavata</groupId>
+            <artifactId>compute-service</artifactId>
+            <version>${project.version}</version>
+        </dependency>
 
         <!-- Armeria gRPC -->
         <dependency>
diff --git 
a/airavata-server/src/main/java/org/apache/airavata/server/config/ServiceWiringConfig.java
 
b/airavata-server/src/main/java/org/apache/airavata/server/config/ServiceWiringConfig.java
new file mode 100644
index 0000000000..c4a0b842da
--- /dev/null
+++ 
b/airavata-server/src/main/java/org/apache/airavata/server/config/ServiceWiringConfig.java
@@ -0,0 +1,39 @@
+/**
+*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+package org.apache.airavata.server.config;
+
+import org.apache.airavata.compute.service.GroupResourceProfileService;
+import org.apache.airavata.execution.service.ExperimentService;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Wires cross-module dependencies that cannot be expressed as direct Maven
+ * dependencies without creating cycles (e.g. execution -> compute-service).
+ */
+@Configuration(proxyBeanMethods = false)
+public class ServiceWiringConfig {
+
+    public ServiceWiringConfig(
+            ExperimentService experimentService,
+            GroupResourceProfileService groupResourceProfileService) {
+        experimentService.setGroupResourceProfileListProvider(
+                groupResourceProfileService::getGroupResourceList);
+    }
+}
diff --git a/pom.xml b/pom.xml
index 8ac070879b..b96460ede3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -73,6 +73,7 @@ under the License.
         <module>airavata-api/research-service</module>
         <module>airavata-api/credential-service</module>
         <module>airavata-api/storage-service</module>
+        <module>airavata-api/compute-service</module>
         <module>airavata-server</module>
     </modules>
 

Reply via email to