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/28 04:00:34 UTC
(airavata) branch master updated: refactor: unified transport servers — Spring module reorganization (#600)
This is an automated email from the ASF dual-hosted git repository.
yasith pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/airavata.git
The following commit(s) were added to refs/heads/master by this push:
new fdffece4ff refactor: unified transport servers — Spring module reorganization (#600)
fdffece4ff is described below
commit fdffece4ff7c95c7b79becb7f3ef66756fcf448f
Author: Yasith Jayawardana <ya...@gatech.edu>
AuthorDate: Fri Mar 27 23:00:28 2026 -0500
refactor: unified transport servers — Spring module reorganization (#600)
* feat: add @ConditionalOnServer, AiravataServerProperties, unified UserContext
* refactor: migrate airavata-api from OpenJPA to Hibernate
Replace OpenJPA dependency, bytecode enhancement plugin, and
@ForeignKey annotations with Hibernate equivalents (@OnDelete).
Delete persistence.xml — no longer needed with Hibernate runtime
proxies. EntityManagerFactory usage in JPAUtils noted but left for
the Spring Boot wrapping task.
* refactor: convert research-service from standalone Boot app to plain library
* refactor: convert agent-service from standalone Boot app to plain library
- Remove spring-boot-maven-plugin, maven-assembly-plugin, and actuator dependency
- Add AgentServiceConfig for component scanning, entity scanning, JPA repos
- Add AgentProperties (@ConfigurationProperties) replacing @Value annotations
- Replace local UserContext with unified org.apache.airavata.common.security.UserContext
- Delete AgentServiceApplication, AuthzTokenFilter, application.yml, assembly descriptor
* refactor: convert file-server to plain library, normalize paths to /api/v1/files/*
* feat: create airavata-rest-server, absorb restproxy, centralize auth + OpenAPI
* feat: create airavata-grpc-server with centralized gRPC auth interceptor
* refactor: wrap airavata-thrift-server in Spring Boot with SmartLifecycle
Replace the custom main() bootstrap in AiravataServer.java with
Spring-managed components:
- AiravataThriftServerConfig: @ConditionalOnServer("thrift") entry point
- ThriftProcessorConfig: builds TMultiplexedProcessor as a @Bean
- ThriftServerLifecycle: SmartLifecycle that manages TThreadPoolServer
- BackgroundServicesConfig: @PostConstruct DB initialization
All handlers annotated with @Component. OrchestratorServerHandler
created via @Bean factory with graceful fallback on init failure.
Background services (Helix, monitoring, etc.) deferred to future task.
* feat: create unified airavata-server launcher with distribution assembly
* refactor: update Tiltfile for unified server startup
Replace 5 separate service definitions (airavata-server, research-service,
agent-service, file-server, rest-proxy) with a single unified airavata-server
entry. Update build deps to track new server modules.
* chore: remove stale assembly descriptors from airavata-api
The unified airavata-server module now produces the distribution tarball,
so the assembly plugin and descriptor files in airavata-api are no longer needed.
---
Tiltfile | 86 +----
airavata-api/pom.xml | 68 +---
.../src/main/assembly/api-server-bin-assembly.xml | 116 ------
.../src/main/assembly/api-server-src-assembly.xml | 81 -----
.../common/config/AiravataServerProperties.java | 16 +
.../common/config/ConditionalOnServer.java | 12 +
.../airavata/common/config/OnServerCondition.java | 19 +
.../airavata/common/security/UserContext.java | 41 +++
.../compute/model/AppEnvironmentEntity.java | 6 +-
.../compute/model/ApplicationInputEntity.java | 6 +-
.../compute/model/ApplicationOutputEntity.java | 6 +-
.../model/BatchQueueResourcePolicyEntity.java | 6 +-
.../compute/model/ComputeResourcePolicyEntity.java | 6 +-
.../model/ComputeResourceReservationEntity.java | 6 +-
.../model/GroupComputeResourcePrefEntity.java | 6 +-
.../model/GroupSSHAccountProvisionerConfig.java | 6 +-
.../compute/model/LibraryApendPathEntity.java | 6 +-
.../compute/model/LibraryPrependPathEntity.java | 6 +-
.../compute/model/ModuleLoadCmdEntity.java | 6 +-
.../compute/model/PostjobCommandEntity.java | 6 +-
.../compute/model/PrejobCommandEntity.java | 6 +-
.../handler/CredentialStoreServerHandler.java | 2 +
.../execution/handler/RegistryServerHandler.java | 2 +
.../handler/SharingRegistryServerHandler.java | 2 +
.../src/main/resources/META-INF/persistence.xml | 203 -----------
.../file-server => airavata-grpc-server}/pom.xml | 101 +++---
.../grpc/server/AiravataGrpcServerConfig.java | 27 +-
.../grpc/server/config/GrpcAuthInterceptor.java | 104 ++++++
.../file-server => airavata-rest-server}/pom.xml | 120 ++++---
.../rest/server/AiravataRestServerConfig.java | 22 +-
.../rest/server}/config/OpenApiConfig.java | 82 ++---
.../rest/server/config/SecurityConfig.java | 132 +++++++
.../airavata/rest/server}/config/WebMvcConfig.java | 19 +-
.../server/controller/KafkaProxyController.java | 35 +-
{modules/restproxy => airavata-server}/pom.xml | 78 ++---
.../src/main/assembly/server-bin-assembly.xml | 61 ++++
airavata-server/src/main/bin/airavata.sh | 8 +
.../apache/airavata/server/AiravataServerMain.java | 41 +++
.../src/main/resources/application-grpc.yml | 4 +
.../src/main/resources/application-rest.yml | 14 +
.../src/main/resources/application-thrift.yml | 4 +
airavata-server/src/main/resources/application.yml | 67 ++++
airavata-thrift-server/pom.xml | 10 +
.../apache/airavata/api/server/AiravataServer.java | 389 ---------------------
.../api/server/handler/AiravataServerHandler.java | 5 +
.../handlers/GroupManagerServiceHandler.java | 2 +
.../profile/handlers/IamAdminServicesHandler.java | 2 +
.../handlers/TenantProfileServiceHandler.java | 2 +
.../handlers/UserProfileServiceHandler.java | 2 +
.../thrift/server/AiravataThriftServerConfig.java | 28 +-
.../server/config/BackgroundServicesConfig.java | 69 ++++
.../server/config/ThriftProcessorConfig.java | 121 +++++++
.../server/config/ThriftServerLifecycle.java | 106 ++++++
modules/agent-framework/agent-service/pom.xml | 29 --
.../main/assembly/agent-service-bin-assembly.xml | 76 ----
.../agent/connection/service/UserContext.java | 53 ---
.../connection/service/config/AgentProperties.java | 35 ++
.../service/config/AgentServiceConfig.java | 13 +
.../service/config/AuthzTokenFilter.java | 64 ----
.../service/controllers/PlanController.java | 6 +-
.../service/handlers/AgentConnectionHandler.java | 26 +-
.../service/handlers/AgentManagementHandler.java | 21 +-
.../service/services/AiravataFileService.java | 2 +-
.../service/services/AiravataService.java | 10 +-
.../src/main/resources/application.yml | 64 ----
modules/file-server/pom.xml | 33 --
.../main/assembly/file-service-bin-assembly.xml | 75 ----
.../file/server/FileServerApplication.java | 35 --
.../file/server/FileServerConfiguration.java | 4 +-
.../file/server/config/FileServerConfig.java | 9 +
.../file/server/controller/FileController.java | 8 +-
.../src/main/resources/application.properties | 10 -
.../research-framework/research-service/pom.xml | 33 --
.../assembly/research-service-bin-assembly.xml | 76 ----
.../airavata/research/service/AiravataService.java | 2 +-
.../research/service/config/AuthzTokenFilter.java | 122 -------
.../service/config/DevDataInitializer.java | 11 +-
.../service/config/ResearchProperties.java | 28 ++
.../service/config/ResearchServiceConfig.java | 15 +
.../service/controller/SessionController.java | 2 +-
.../research/service/handlers/ProjectHandler.java | 2 +-
.../service/handlers/ResearchHubHandler.java | 34 +-
.../research/service/handlers/ResourceHandler.java | 2 +-
.../research/service/handlers/SessionHandler.java | 2 +-
.../research/service/model/UserContext.java | 62 ----
.../src/main/resources/application.yml | 76 ----
.../src/main/assembly/restproxy-bin-assembly.xml | 75 ----
.../airavata/restproxy/RestProxyApplication.java | 32 --
.../src/main/resources/application.properties | 4 -
.../main/resources/distribution/bin/restproxy.sh | 26 --
.../src/main/resources/distribution/bin/setenv.sh | 146 --------
.../src/main/resources/distribution/conf/.gitkeep | 0
modules/restproxy/src/main/resources/log4j2.xml | 39 ---
pom.xml | 14 +-
94 files changed, 1358 insertions(+), 2399 deletions(-)
diff --git a/Tiltfile b/Tiltfile
index 7632a6a326..ad9700a596 100644
--- a/Tiltfile
+++ b/Tiltfile
@@ -13,91 +13,31 @@ local_resource(
'airavata-api/pom.xml',
'airavata-thrift-server/src',
'airavata-thrift-server/pom.xml',
- 'modules/file-server/src',
- 'modules/file-server/pom.xml',
- 'modules/agent-framework/agent-service/src',
- 'modules/agent-framework/agent-service/pom.xml',
- 'modules/research-framework/research-service/src',
- 'modules/research-framework/research-service/pom.xml',
- 'modules/restproxy/src',
- 'modules/restproxy/pom.xml',
+ 'airavata-rest-server/src',
+ 'airavata-rest-server/pom.xml',
+ 'airavata-grpc-server/src',
+ 'airavata-grpc-server/pom.xml',
+ 'airavata-server/src',
+ 'airavata-server/pom.xml',
],
labels=['build'],
)
-# --- Airavata Thrift Server (port 8930 thrift, 9097 monitoring) ---
+# --- Airavata Server (unified: Thrift + REST + gRPC) ---
local_resource(
'airavata-server',
- serve_cmd=' '.join([
- 'java',
- '-cp', 'airavata-thrift-server/target/classes:airavata-api/target/classes:airavata-api/target/dependency/*',
- '-Dlog4j.configurationFile=airavata-api/src/main/resources/log4j2.xml',
- '-Dairavata.config.dir=airavata-api/src/main/resources',
- 'org.apache.airavata.api.server.AiravataServer',
- ]),
- readiness_probe=probe(
- http_get=http_get_action(port=9097, path='/health/services'),
- period_secs=5,
- timeout_secs=5,
- initial_delay_secs=15,
- ),
- resource_deps=['build', 'db', 'rabbitmq', 'zookeeper', 'kafka', 'keycloak'],
- labels=['airavata'],
-)
-
-# --- Research Service (port 18889 HTTP, 19908 gRPC) ---
-local_resource(
- 'research-service',
- serve_cmd='mvn spring-boot:run -pl modules/research-framework/research-service -q',
+ serve_cmd='java -jar airavata-server/target/airavata-server-0.21-SNAPSHOT.jar',
readiness_probe=probe(
http_get=http_get_action(port=18889, path='/actuator/health'),
- period_secs=5,
- timeout_secs=5,
- initial_delay_secs=20,
- ),
- resource_deps=['build', 'airavata-server', 'db', 'keycloak'],
- labels=['airavata'],
-)
-
-# --- Agent Service (port 18880 HTTP, 19900 gRPC) ---
-local_resource(
- 'agent-service',
- serve_cmd='mvn spring-boot:run -pl modules/agent-framework/agent-service -q',
- readiness_probe=probe(
- http_get=http_get_action(port=18880, path='/actuator/health'),
- period_secs=5,
- timeout_secs=5,
initial_delay_secs=20,
- ),
- resource_deps=['build', 'airavata-server', 'db'],
- labels=['airavata'],
-)
-
-# --- File Server (port 8050) ---
-local_resource(
- 'file-server',
- serve_cmd='mvn spring-boot:run -pl modules/file-server -q',
- readiness_probe=probe(
- http_get=http_get_action(port=8050, path='/actuator/health'),
- period_secs=5,
- timeout_secs=5,
- initial_delay_secs=15,
- ),
- resource_deps=['build', 'airavata-server'],
- labels=['airavata'],
-)
-
-# --- REST Proxy (port 8082) ---
-local_resource(
- 'rest-proxy',
- serve_cmd='mvn spring-boot:run -pl modules/restproxy -q',
- readiness_probe=probe(
- http_get=http_get_action(port=8082, path='/actuator/health'),
period_secs=5,
timeout_secs=5,
- initial_delay_secs=15,
),
- resource_deps=['build', 'airavata-server', 'kafka'],
+ resource_deps=['build', 'db', 'rabbitmq', 'zookeeper', 'kafka', 'keycloak'],
+ links=[
+ link('http://localhost:18889/swagger-ui.html', 'Swagger UI'),
+ link('http://localhost:18889/actuator/health', 'Health'),
+ ],
labels=['airavata'],
)
diff --git a/airavata-api/pom.xml b/airavata-api/pom.xml
index 402d15879e..177e1462e4 100644
--- a/airavata-api/pom.xml
+++ b/airavata-api/pom.xml
@@ -111,8 +111,8 @@ under the License.
</exclusions>
</dependency>
<dependency>
- <groupId>org.apache.openjpa</groupId>
- <artifactId>openjpa</artifactId>
+ <groupId>org.hibernate.orm</groupId>
+ <artifactId>hibernate-core</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
@@ -331,6 +331,18 @@ under the License.
<artifactId>commons-lang3</artifactId>
</dependency>
+ <!-- Spring (optional, for @ConditionalOnServer and config properties) -->
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-autoconfigure</artifactId>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ <optional>true</optional>
+ </dependency>
+
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>ec2</artifactId>
@@ -487,35 +499,6 @@ under the License.
</configuration>
</plugin>
- <!-- Enhance OpenJPA Entities -->
- <plugin>
- <groupId>org.apache.openjpa</groupId>
- <artifactId>openjpa-maven-plugin</artifactId>
- <configuration>
- <includes>**/entities/**/*.class,**/compute/model/*.class,**/storage/model/*.class,**/execution/model/*.class,**/execution/model/workflow/*.class,**/sharing/model/*.class,**/credential/model/*.class</includes>
- <excludes>**/entities/**/XML*.class,**/entities/**/*PK.class,**/*PK.class</excludes>
- <addDefaultConstructor>true</addDefaultConstructor>
- <enforcePropertyRestrictions>true</enforcePropertyRestrictions>
- <persistenceXmlFile>${project.basedir}/src/main/resources/META-INF/persistence.xml</persistenceXmlFile>
- </configuration>
- <executions>
- <execution>
- <id>enhancer</id>
- <phase>process-classes</phase>
- <goals>
- <goal>enhance</goal>
- </goals>
- </execution>
- </executions>
- <dependencies>
- <dependency>
- <groupId>org.apache.openjpa</groupId>
- <artifactId>openjpa</artifactId>
- <version>4.1.1</version>
- </dependency>
- </dependencies>
- </plugin>
-
<!-- Run Tests -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -543,29 +526,6 @@ under the License.
</configuration>
</plugin>
- <!-- Package distribution (tarball) -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-assembly-plugin</artifactId>
- <executions>
- <execution>
- <id>api-server-distribution-package</id>
- <phase>package</phase>
- <goals>
- <goal>single</goal>
- </goals>
- <configuration>
- <tarLongFileMode>posix</tarLongFileMode>
- <finalName>${api.server.dist.name}</finalName>
- <descriptors>
- <descriptor>src/main/assembly/api-server-bin-assembly.xml</descriptor>
- </descriptors>
- <attach>false</attach>
- </configuration>
- </execution>
- </executions>
- </plugin>
-
<!-- Copy runtime dependencies for classpath mode (Tiltfile) -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
diff --git a/airavata-api/src/main/assembly/api-server-bin-assembly.xml b/airavata-api/src/main/assembly/api-server-bin-assembly.xml
deleted file mode 100644
index a4ba2f2ae6..0000000000
--- a/airavata-api/src/main/assembly/api-server-bin-assembly.xml
+++ /dev/null
@@ -1,116 +0,0 @@
-<!--
-
-
- 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.
-
--->
-<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.2.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.2.0 http://maven.apache.org/xsd/assembly-2.2.0.xsd">
- <id>bin</id>
- <includeBaseDirectory>true</includeBaseDirectory>
- <formats>
- <format>tar.gz</format>
- </formats>
-
- <fileSets>
-
- <!-- ********************** copy metadata files ********************** -->
- <fileSet>
- <directory>..</directory>
- <outputDirectory>.</outputDirectory>
- <includes>
- <include>INSTALL</include>
- <include>LICENSE</include>
- <include>NOTICE</include>
- <include>RELEASE_NOTES</include>
- <include>README.md</include>
- <include>logo.txt</include>
- </includes>
- </fileSet>
-
- <!-- ********************** copy keystore files ********************** -->
- <fileSet>
- <directory>../keystores</directory>
- <outputDirectory>conf/keystores</outputDirectory>
- <includes>
- <include>*.jks</include>
- </includes>
- </fileSet>
-
- <!-- ********************** copy config files ********************** -->
- <fileSet>
- <directory>src/main/resources</directory>
- <outputDirectory>conf</outputDirectory>
- <includes>
- <include>META-INF/persistence.xml</include>
- <include>templates/*.template</include>
- <include>*.properties</include>
- <include>*.xml</include>
- </includes>
- </fileSet>
-
- <!-- ********************** copy database scripts ********************** -->
- <fileSet>
- <directory>src/main/resources/database_scripts</directory>
- <outputDirectory>database_scripts</outputDirectory>
- <includes>
- <include>*.sql</include>
- </includes>
- </fileSet>
-
- <!-- ********************** copy bin files ********************** -->
- <fileSet>
- <directory>src/main/resources/distribution/bin</directory>
- <outputDirectory>bin</outputDirectory>
- <fileMode>777</fileMode>
- <includes>
- <include>*.sh</include>
- <include>*.bat</include>
- </includes>
- </fileSet>
-
- <!-- ********************** copy config files ********************** -->
- <fileSet>
- <directory>src/main/resources/distribution/conf</directory>
- <outputDirectory>conf</outputDirectory>
- <includes>
- <include>*</include>
- </includes>
- </fileSet>
-
- <!-- ********************** copy logs ********************** -->
- <fileSet>
- <directory>./</directory>
- <outputDirectory>logs</outputDirectory>
- <excludes>
- <exclude>*/**</exclude>
- </excludes>
- </fileSet>
-
- </fileSets>
-
- <dependencySets>
- <dependencySet>
- <useProjectArtifact>true</useProjectArtifact>
- <outputDirectory>lib</outputDirectory>
- <useTransitiveDependencies>true</useTransitiveDependencies>
- </dependencySet>
- </dependencySets>
-
-</assembly>
\ No newline at end of file
diff --git a/airavata-api/src/main/assembly/api-server-src-assembly.xml b/airavata-api/src/main/assembly/api-server-src-assembly.xml
deleted file mode 100644
index b33ff157ec..0000000000
--- a/airavata-api/src/main/assembly/api-server-src-assembly.xml
+++ /dev/null
@@ -1,81 +0,0 @@
-<!--
-
-
- 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.
-
--->
-<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.2.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.2.0 http://maven.apache.org/xsd/assembly-2.2.0.xsd">
- <id>src</id>
- <includeBaseDirectory>true</includeBaseDirectory>
- <baseDirectory>${api.server.dist.name}</baseDirectory>
- <formats>
- <format>tar.gz</format>
- </formats>
-
- <fileSets>
-
- <!-- ********************** copy metadata files ********************** -->
- <fileSet>
- <directory>../..</directory>
- <outputDirectory>.</outputDirectory>
- <includes>
- <include>INSTALL</include>
- <include>LICENSE</include>
- <include>NOTICE</include>
- <include>RELEASE_NOTES</include>
- <include>README.md</include>
- </includes>
- </fileSet>
-
- <!-- ********************** copy source code ********************** -->
- <fileSet>
- <directory>../..</directory>
- <outputDirectory></outputDirectory>
- <useDefaultExcludes>true</useDefaultExcludes>
- <includes>
- <include>pom.xml</include>
- <include>airavata-api/**</include>
- <include>modules/**</include>
- <include>examples/**</include>
- </includes>
- <excludes>
- <!-- Exclusions from org.apache.resources:apache-source-release-assembly-descriptor.
- Note that they assume that all sources are located under an "src" directory. This
- is not the case for Axis2, which doesn't use the standard Maven 2 conventions.
- Thus we may still encounter some issues here. -->
- <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/).*${project.build.directory}.*]</exclude>
- <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?maven-eclipse\.xml]</exclude>
- <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.project]</exclude>
- <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.classpath]</exclude>
- <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?[^/]*\.iws]</exclude>
- <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?[^/]*\.ipr]</exclude>
- <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?[^/]*\.iml]</exclude>
- <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.settings(/.*)?]</exclude>
- <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.externalToolBuilders(/.*)?]</exclude>
- <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.deployables(/.*)?]</exclude>
- <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.wtpmodules(/.*)?]</exclude>
- <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?cobertura\.ser]</exclude>
- <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?pom\.xml\.releaseBackup]</exclude>
- <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?release\.properties]</exclude>
- </excludes>
- </fileSet>
-
- </fileSets>
-</assembly>
\ No newline at end of file
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/config/AiravataServerProperties.java b/airavata-api/src/main/java/org/apache/airavata/common/config/AiravataServerProperties.java
new file mode 100644
index 0000000000..46ae58aa49
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/config/AiravataServerProperties.java
@@ -0,0 +1,16 @@
+package org.apache.airavata.common.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import java.util.List;
+
+/**
+ * Binds the {@code airavata.servers} list property.
+ * Consumers must register via {@code @EnableConfigurationProperties(AiravataServerProperties.class)}.
+ */
+@ConfigurationProperties(prefix = "airavata")
+public class AiravataServerProperties {
+ private List<String> servers = List.of("thrift", "rest", "grpc");
+
+ public List<String> getServers() { return servers; }
+ public void setServers(List<String> servers) { this.servers = servers; }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/config/ConditionalOnServer.java b/airavata-api/src/main/java/org/apache/airavata/common/config/ConditionalOnServer.java
new file mode 100644
index 0000000000..015d919e40
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/config/ConditionalOnServer.java
@@ -0,0 +1,12 @@
+package org.apache.airavata.common.config;
+
+import org.springframework.context.annotation.Conditional;
+import java.lang.annotation.*;
+
+@Target({ElementType.TYPE, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Conditional(OnServerCondition.class)
+public @interface ConditionalOnServer {
+ String value();
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/config/OnServerCondition.java b/airavata-api/src/main/java/org/apache/airavata/common/config/OnServerCondition.java
new file mode 100644
index 0000000000..6356b9dc53
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/config/OnServerCondition.java
@@ -0,0 +1,19 @@
+package org.apache.airavata.common.config;
+
+import org.springframework.context.annotation.Condition;
+import org.springframework.context.annotation.ConditionContext;
+import org.springframework.core.type.AnnotatedTypeMetadata;
+import java.util.Arrays;
+import java.util.Map;
+
+public class OnServerCondition implements Condition {
+ @Override
+ public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
+ Map<String, Object> attrs = metadata.getAnnotationAttributes(ConditionalOnServer.class.getName());
+ if (attrs == null) return false;
+ String requiredServer = (String) attrs.get("value");
+ String[] servers = context.getEnvironment().getProperty("airavata.servers", String[].class);
+ if (servers == null) return true; // Default: all enabled
+ return Arrays.asList(servers).contains(requiredServer);
+ }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/common/security/UserContext.java b/airavata-api/src/main/java/org/apache/airavata/common/security/UserContext.java
new file mode 100644
index 0000000000..d67ed248dd
--- /dev/null
+++ b/airavata-api/src/main/java/org/apache/airavata/common/security/UserContext.java
@@ -0,0 +1,41 @@
+package org.apache.airavata.common.security;
+
+import org.apache.airavata.common.config.Constants;
+import org.apache.airavata.model.security.AuthzToken;
+import org.apache.airavata.security.profile.commons.user.entities.UserProfileEntity;
+
+import java.util.Map;
+
+public class UserContext {
+
+ private static final ThreadLocal<AuthzToken> AUTHZ_TOKEN = new ThreadLocal<>();
+ private static final ThreadLocal<UserProfileEntity> CURRENT_USER = new ThreadLocal<>();
+
+ private UserContext() {}
+
+ public static AuthzToken authzToken() { return AUTHZ_TOKEN.get(); }
+ public static void setAuthzToken(AuthzToken token) { AUTHZ_TOKEN.set(token); }
+ public static UserProfileEntity user() { return CURRENT_USER.get(); }
+ public static void setUser(UserProfileEntity user) { CURRENT_USER.set(user); }
+
+ public static String userId() {
+ var token = authzToken();
+ if (token == null) return null;
+ Map<String, String> claims = token.getClaimsMap();
+ return claims != null ? claims.get(Constants.USER_NAME) : null;
+ }
+
+ public static String gatewayId() {
+ var token = authzToken();
+ if (token == null) return null;
+ Map<String, String> claims = token.getClaimsMap();
+ return claims != null ? claims.get(Constants.GATEWAY_ID) : null;
+ }
+
+ public static boolean isAuthenticated() { return authzToken() != null; }
+
+ public static void clear() {
+ AUTHZ_TOKEN.remove();
+ CURRENT_USER.remove();
+ }
+}
diff --git a/airavata-api/src/main/java/org/apache/airavata/compute/model/AppEnvironmentEntity.java b/airavata-api/src/main/java/org/apache/airavata/compute/model/AppEnvironmentEntity.java
index c1b35a7eef..6f8ac4177e 100644
--- a/airavata-api/src/main/java/org/apache/airavata/compute/model/AppEnvironmentEntity.java
+++ b/airavata-api/src/main/java/org/apache/airavata/compute/model/AppEnvironmentEntity.java
@@ -21,8 +21,8 @@ package org.apache.airavata.compute.model;
import jakarta.persistence.*;
import java.io.Serializable;
-import org.apache.openjpa.persistence.jdbc.ForeignKey;
-import org.apache.openjpa.persistence.jdbc.ForeignKeyAction;
+import org.hibernate.annotations.OnDelete;
+import org.hibernate.annotations.OnDeleteAction;
/**
* The persistent class for the app_environment database table.
@@ -49,7 +49,7 @@ public class AppEnvironmentEntity implements Serializable {
@ManyToOne(targetEntity = ApplicationDeploymentEntity.class)
@JoinColumn(name = "DEPLOYMENT_ID", nullable = false, updatable = false)
- @ForeignKey(deleteAction = ForeignKeyAction.CASCADE)
+ @OnDelete(action = OnDeleteAction.CASCADE)
private ApplicationDeploymentEntity applicationDeployment;
public AppEnvironmentEntity() {}
diff --git a/airavata-api/src/main/java/org/apache/airavata/compute/model/ApplicationInputEntity.java b/airavata-api/src/main/java/org/apache/airavata/compute/model/ApplicationInputEntity.java
index fc2c0705f1..9d8092a4c1 100644
--- a/airavata-api/src/main/java/org/apache/airavata/compute/model/ApplicationInputEntity.java
+++ b/airavata-api/src/main/java/org/apache/airavata/compute/model/ApplicationInputEntity.java
@@ -22,8 +22,8 @@ package org.apache.airavata.compute.model;
import jakarta.persistence.*;
import java.io.Serializable;
import org.apache.airavata.model.application.io.DataType;
-import org.apache.openjpa.persistence.jdbc.ForeignKey;
-import org.apache.openjpa.persistence.jdbc.ForeignKeyAction;
+import org.hibernate.annotations.OnDelete;
+import org.hibernate.annotations.OnDeleteAction;
/**
* The persistent class for the application_input database table.
@@ -83,7 +83,7 @@ public class ApplicationInputEntity implements Serializable {
@ManyToOne(targetEntity = ApplicationInterfaceEntity.class)
@JoinColumn(name = "INTERFACE_ID", nullable = false, updatable = false)
- @ForeignKey(deleteAction = ForeignKeyAction.CASCADE)
+ @OnDelete(action = OnDeleteAction.CASCADE)
private ApplicationInterfaceEntity applicationInterface;
public ApplicationInputEntity() {}
diff --git a/airavata-api/src/main/java/org/apache/airavata/compute/model/ApplicationOutputEntity.java b/airavata-api/src/main/java/org/apache/airavata/compute/model/ApplicationOutputEntity.java
index a405698780..b50ef9e7ae 100644
--- a/airavata-api/src/main/java/org/apache/airavata/compute/model/ApplicationOutputEntity.java
+++ b/airavata-api/src/main/java/org/apache/airavata/compute/model/ApplicationOutputEntity.java
@@ -22,8 +22,8 @@ package org.apache.airavata.compute.model;
import jakarta.persistence.*;
import java.io.Serializable;
import org.apache.airavata.model.application.io.DataType;
-import org.apache.openjpa.persistence.jdbc.ForeignKey;
-import org.apache.openjpa.persistence.jdbc.ForeignKeyAction;
+import org.hibernate.annotations.OnDelete;
+import org.hibernate.annotations.OnDeleteAction;
/**
* The persistent class for the application_output database table.
@@ -75,7 +75,7 @@ public class ApplicationOutputEntity implements Serializable {
@ManyToOne(targetEntity = ApplicationInterfaceEntity.class)
@JoinColumn(name = "INTERFACE_ID", nullable = false, updatable = false)
- @ForeignKey(deleteAction = ForeignKeyAction.CASCADE)
+ @OnDelete(action = OnDeleteAction.CASCADE)
private ApplicationInterfaceEntity applicationInterface;
public ApplicationOutputEntity() {}
diff --git a/airavata-api/src/main/java/org/apache/airavata/compute/model/BatchQueueResourcePolicyEntity.java b/airavata-api/src/main/java/org/apache/airavata/compute/model/BatchQueueResourcePolicyEntity.java
index 1a86d60591..64df10b84c 100644
--- a/airavata-api/src/main/java/org/apache/airavata/compute/model/BatchQueueResourcePolicyEntity.java
+++ b/airavata-api/src/main/java/org/apache/airavata/compute/model/BatchQueueResourcePolicyEntity.java
@@ -26,8 +26,8 @@ import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import java.io.Serializable;
-import org.apache.openjpa.persistence.jdbc.ForeignKey;
-import org.apache.openjpa.persistence.jdbc.ForeignKeyAction;
+import org.hibernate.annotations.OnDelete;
+import org.hibernate.annotations.OnDeleteAction;
/**
* The persistent class for the batch_queue_resource_policy database table.
@@ -62,7 +62,7 @@ public class BatchQueueResourcePolicyEntity implements Serializable {
@ManyToOne(targetEntity = GroupResourceProfileEntity.class)
@JoinColumn(name = "GROUP_RESOURCE_PROFILE_ID", nullable = false, updatable = false)
- @ForeignKey(deleteAction = ForeignKeyAction.CASCADE)
+ @OnDelete(action = OnDeleteAction.CASCADE)
private GroupResourceProfileEntity groupResourceProfile;
public BatchQueueResourcePolicyEntity() {}
diff --git a/airavata-api/src/main/java/org/apache/airavata/compute/model/ComputeResourcePolicyEntity.java b/airavata-api/src/main/java/org/apache/airavata/compute/model/ComputeResourcePolicyEntity.java
index 5a9eb51f6e..c43e400734 100644
--- a/airavata-api/src/main/java/org/apache/airavata/compute/model/ComputeResourcePolicyEntity.java
+++ b/airavata-api/src/main/java/org/apache/airavata/compute/model/ComputeResourcePolicyEntity.java
@@ -30,8 +30,8 @@ import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import java.io.Serializable;
import java.util.List;
-import org.apache.openjpa.persistence.jdbc.ForeignKey;
-import org.apache.openjpa.persistence.jdbc.ForeignKeyAction;
+import org.hibernate.annotations.OnDelete;
+import org.hibernate.annotations.OnDeleteAction;
/**
* The persistent class for the compute_resource_policy database table.
@@ -62,7 +62,7 @@ public class ComputeResourcePolicyEntity implements Serializable {
@ManyToOne(targetEntity = GroupResourceProfileEntity.class)
@JoinColumn(name = "GROUP_RESOURCE_PROFILE_ID", nullable = false, updatable = false)
- @ForeignKey(deleteAction = ForeignKeyAction.CASCADE)
+ @OnDelete(action = OnDeleteAction.CASCADE)
private GroupResourceProfileEntity groupResourceProfile;
public ComputeResourcePolicyEntity() {}
diff --git a/airavata-api/src/main/java/org/apache/airavata/compute/model/ComputeResourceReservationEntity.java b/airavata-api/src/main/java/org/apache/airavata/compute/model/ComputeResourceReservationEntity.java
index 2903981a1f..865f383f44 100644
--- a/airavata-api/src/main/java/org/apache/airavata/compute/model/ComputeResourceReservationEntity.java
+++ b/airavata-api/src/main/java/org/apache/airavata/compute/model/ComputeResourceReservationEntity.java
@@ -32,8 +32,8 @@ import jakarta.persistence.Table;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.List;
-import org.apache.openjpa.persistence.jdbc.ForeignKey;
-import org.apache.openjpa.persistence.jdbc.ForeignKeyAction;
+import org.hibernate.annotations.OnDelete;
+import org.hibernate.annotations.OnDeleteAction;
/**
* The persistent class for the COMPUTE_RESOURCE_RESERVATION database table.
@@ -73,7 +73,7 @@ public class ComputeResourceReservationEntity implements Serializable {
nullable = false,
updatable = false)
})
- @ForeignKey(deleteAction = ForeignKeyAction.CASCADE)
+ @OnDelete(action = OnDeleteAction.CASCADE)
private GroupComputeResourcePrefEntity groupComputeResourcePref;
public ComputeResourceReservationEntity() {}
diff --git a/airavata-api/src/main/java/org/apache/airavata/compute/model/GroupComputeResourcePrefEntity.java b/airavata-api/src/main/java/org/apache/airavata/compute/model/GroupComputeResourcePrefEntity.java
index 8deec605b6..76277cbf8d 100644
--- a/airavata-api/src/main/java/org/apache/airavata/compute/model/GroupComputeResourcePrefEntity.java
+++ b/airavata-api/src/main/java/org/apache/airavata/compute/model/GroupComputeResourcePrefEntity.java
@@ -36,8 +36,8 @@ import jakarta.persistence.Table;
import java.io.Serializable;
import org.apache.airavata.model.appcatalog.computeresource.JobSubmissionProtocol;
import org.apache.airavata.model.data.movement.DataMovementProtocol;
-import org.apache.openjpa.persistence.jdbc.ForeignKey;
-import org.apache.openjpa.persistence.jdbc.ForeignKeyAction;
+import org.hibernate.annotations.OnDelete;
+import org.hibernate.annotations.OnDeleteAction;
/**
* The persistent class for the group_compute_resource_preference database table.
@@ -81,7 +81,7 @@ public abstract class GroupComputeResourcePrefEntity implements Serializable {
@ManyToOne(targetEntity = GroupResourceProfileEntity.class, cascade = CascadeType.PERSIST)
@JoinColumn(name = "GROUP_RESOURCE_PROFILE_ID", nullable = false, updatable = false)
- @ForeignKey(deleteAction = ForeignKeyAction.CASCADE)
+ @OnDelete(action = OnDeleteAction.CASCADE)
private GroupResourceProfileEntity groupResourceProfile;
public GroupComputeResourcePrefEntity() {}
diff --git a/airavata-api/src/main/java/org/apache/airavata/compute/model/GroupSSHAccountProvisionerConfig.java b/airavata-api/src/main/java/org/apache/airavata/compute/model/GroupSSHAccountProvisionerConfig.java
index 4def294703..0678f3f9b0 100644
--- a/airavata-api/src/main/java/org/apache/airavata/compute/model/GroupSSHAccountProvisionerConfig.java
+++ b/airavata-api/src/main/java/org/apache/airavata/compute/model/GroupSSHAccountProvisionerConfig.java
@@ -28,8 +28,8 @@ import jakarta.persistence.JoinColumns;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import java.io.Serializable;
-import org.apache.openjpa.persistence.jdbc.ForeignKey;
-import org.apache.openjpa.persistence.jdbc.ForeignKeyAction;
+import org.hibernate.annotations.OnDelete;
+import org.hibernate.annotations.OnDeleteAction;
/**
* The persistent class for the grp_ssh_acc_prov_config database table.
@@ -64,7 +64,7 @@ public class GroupSSHAccountProvisionerConfig implements Serializable {
referencedColumnName = "GROUP_RESOURCE_PROFILE_ID",
nullable = false)
})
- @ForeignKey(deleteAction = ForeignKeyAction.CASCADE)
+ @OnDelete(action = OnDeleteAction.CASCADE)
private GroupComputeResourcePrefEntity groupComputeResourcePref;
public GroupSSHAccountProvisionerConfig() {}
diff --git a/airavata-api/src/main/java/org/apache/airavata/compute/model/LibraryApendPathEntity.java b/airavata-api/src/main/java/org/apache/airavata/compute/model/LibraryApendPathEntity.java
index 66520f6be1..02c787ec25 100644
--- a/airavata-api/src/main/java/org/apache/airavata/compute/model/LibraryApendPathEntity.java
+++ b/airavata-api/src/main/java/org/apache/airavata/compute/model/LibraryApendPathEntity.java
@@ -21,8 +21,8 @@ package org.apache.airavata.compute.model;
import jakarta.persistence.*;
import java.io.Serializable;
-import org.apache.openjpa.persistence.jdbc.ForeignKey;
-import org.apache.openjpa.persistence.jdbc.ForeignKeyAction;
+import org.hibernate.annotations.OnDelete;
+import org.hibernate.annotations.OnDeleteAction;
/**
* The persistent class for the library_apend_path database table.
@@ -46,7 +46,7 @@ public class LibraryApendPathEntity implements Serializable {
@ManyToOne(targetEntity = ApplicationDeploymentEntity.class, cascade = CascadeType.MERGE)
@JoinColumn(name = "DEPLOYMENT_ID")
- @ForeignKey(deleteAction = ForeignKeyAction.CASCADE)
+ @OnDelete(action = OnDeleteAction.CASCADE)
private ApplicationDeploymentEntity applicationDeployment;
public LibraryApendPathEntity() {}
diff --git a/airavata-api/src/main/java/org/apache/airavata/compute/model/LibraryPrependPathEntity.java b/airavata-api/src/main/java/org/apache/airavata/compute/model/LibraryPrependPathEntity.java
index a1e261151b..986d411a6e 100644
--- a/airavata-api/src/main/java/org/apache/airavata/compute/model/LibraryPrependPathEntity.java
+++ b/airavata-api/src/main/java/org/apache/airavata/compute/model/LibraryPrependPathEntity.java
@@ -21,8 +21,8 @@ package org.apache.airavata.compute.model;
import jakarta.persistence.*;
import java.io.Serializable;
-import org.apache.openjpa.persistence.jdbc.ForeignKey;
-import org.apache.openjpa.persistence.jdbc.ForeignKeyAction;
+import org.hibernate.annotations.OnDelete;
+import org.hibernate.annotations.OnDeleteAction;
/**
* The persistent class for the library_apend_path database table.
@@ -47,7 +47,7 @@ public class LibraryPrependPathEntity implements Serializable {
@ManyToOne(targetEntity = ApplicationDeploymentEntity.class, cascade = CascadeType.MERGE)
@JoinColumn(name = "DEPLOYMENT_ID")
- @ForeignKey(deleteAction = ForeignKeyAction.CASCADE)
+ @OnDelete(action = OnDeleteAction.CASCADE)
private ApplicationDeploymentEntity applicationDeployment;
public LibraryPrependPathEntity() {}
diff --git a/airavata-api/src/main/java/org/apache/airavata/compute/model/ModuleLoadCmdEntity.java b/airavata-api/src/main/java/org/apache/airavata/compute/model/ModuleLoadCmdEntity.java
index a8d549f179..79cfd0ed6a 100644
--- a/airavata-api/src/main/java/org/apache/airavata/compute/model/ModuleLoadCmdEntity.java
+++ b/airavata-api/src/main/java/org/apache/airavata/compute/model/ModuleLoadCmdEntity.java
@@ -21,8 +21,8 @@ package org.apache.airavata.compute.model;
import jakarta.persistence.*;
import java.io.Serializable;
-import org.apache.openjpa.persistence.jdbc.ForeignKey;
-import org.apache.openjpa.persistence.jdbc.ForeignKeyAction;
+import org.hibernate.annotations.OnDelete;
+import org.hibernate.annotations.OnDeleteAction;
/**
* The persistent class for the module_load_cmd database table.
@@ -46,7 +46,7 @@ public class ModuleLoadCmdEntity implements Serializable {
@ManyToOne(targetEntity = ApplicationDeploymentEntity.class, cascade = CascadeType.MERGE)
@JoinColumn(name = "APP_DEPLOYMENT_ID")
- @ForeignKey(deleteAction = ForeignKeyAction.CASCADE)
+ @OnDelete(action = OnDeleteAction.CASCADE)
private ApplicationDeploymentEntity applicationDeployment;
public ModuleLoadCmdEntity() {}
diff --git a/airavata-api/src/main/java/org/apache/airavata/compute/model/PostjobCommandEntity.java b/airavata-api/src/main/java/org/apache/airavata/compute/model/PostjobCommandEntity.java
index bbc934f423..3c59bf2469 100644
--- a/airavata-api/src/main/java/org/apache/airavata/compute/model/PostjobCommandEntity.java
+++ b/airavata-api/src/main/java/org/apache/airavata/compute/model/PostjobCommandEntity.java
@@ -21,8 +21,8 @@ package org.apache.airavata.compute.model;
import jakarta.persistence.*;
import java.io.Serializable;
-import org.apache.openjpa.persistence.jdbc.ForeignKey;
-import org.apache.openjpa.persistence.jdbc.ForeignKeyAction;
+import org.hibernate.annotations.OnDelete;
+import org.hibernate.annotations.OnDeleteAction;
/**
* The persistent class for the postjob_command database table.
@@ -46,7 +46,7 @@ public class PostjobCommandEntity implements Serializable {
@ManyToOne(targetEntity = ApplicationDeploymentEntity.class, cascade = CascadeType.MERGE)
@JoinColumn(name = "APPDEPLOYMENT_ID")
- @ForeignKey(deleteAction = ForeignKeyAction.CASCADE)
+ @OnDelete(action = OnDeleteAction.CASCADE)
private ApplicationDeploymentEntity applicationDeployment;
public PostjobCommandEntity() {}
diff --git a/airavata-api/src/main/java/org/apache/airavata/compute/model/PrejobCommandEntity.java b/airavata-api/src/main/java/org/apache/airavata/compute/model/PrejobCommandEntity.java
index fd6cfea735..3cd8a7c7e1 100644
--- a/airavata-api/src/main/java/org/apache/airavata/compute/model/PrejobCommandEntity.java
+++ b/airavata-api/src/main/java/org/apache/airavata/compute/model/PrejobCommandEntity.java
@@ -21,8 +21,8 @@ package org.apache.airavata.compute.model;
import jakarta.persistence.*;
import java.io.Serializable;
-import org.apache.openjpa.persistence.jdbc.ForeignKey;
-import org.apache.openjpa.persistence.jdbc.ForeignKeyAction;
+import org.hibernate.annotations.OnDelete;
+import org.hibernate.annotations.OnDeleteAction;
/**
* The persistent class for the prejob_command database table.
@@ -46,7 +46,7 @@ public class PrejobCommandEntity implements Serializable {
@ManyToOne(targetEntity = ApplicationDeploymentEntity.class, cascade = CascadeType.MERGE)
@JoinColumn(name = "APPDEPLOYMENT_ID")
- @ForeignKey(deleteAction = ForeignKeyAction.CASCADE)
+ @OnDelete(action = OnDeleteAction.CASCADE)
private ApplicationDeploymentEntity applicationDeployment;
public PrejobCommandEntity() {}
diff --git a/airavata-api/src/main/java/org/apache/airavata/credential/handler/CredentialStoreServerHandler.java b/airavata-api/src/main/java/org/apache/airavata/credential/handler/CredentialStoreServerHandler.java
index f08ded5db4..dbbd1b6211 100644
--- a/airavata-api/src/main/java/org/apache/airavata/credential/handler/CredentialStoreServerHandler.java
+++ b/airavata-api/src/main/java/org/apache/airavata/credential/handler/CredentialStoreServerHandler.java
@@ -47,8 +47,10 @@ import org.apache.commons.codec.binary.Base64;
import org.apache.thrift.TException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
// import sun.security.provider.X509Factory;
+@Component
public class CredentialStoreServerHandler implements CredentialStoreService.Iface {
protected static Logger log = LoggerFactory.getLogger(CredentialStoreServerHandler.class);
private DBUtil dbUtil;
diff --git a/airavata-api/src/main/java/org/apache/airavata/execution/handler/RegistryServerHandler.java b/airavata-api/src/main/java/org/apache/airavata/execution/handler/RegistryServerHandler.java
index bb6b7cb831..3a54bbadfb 100644
--- a/airavata-api/src/main/java/org/apache/airavata/execution/handler/RegistryServerHandler.java
+++ b/airavata-api/src/main/java/org/apache/airavata/execution/handler/RegistryServerHandler.java
@@ -78,7 +78,9 @@ import org.apache.airavata.storage.repository.StorageResourceRepository;
import org.apache.thrift.TException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+@Component
public class RegistryServerHandler implements RegistryService.Iface {
private static final Logger logger = LoggerFactory.getLogger(RegistryServerHandler.class);
diff --git a/airavata-api/src/main/java/org/apache/airavata/sharing/handler/SharingRegistryServerHandler.java b/airavata-api/src/main/java/org/apache/airavata/sharing/handler/SharingRegistryServerHandler.java
index 16afd1f3af..ec765ad396 100644
--- a/airavata-api/src/main/java/org/apache/airavata/sharing/handler/SharingRegistryServerHandler.java
+++ b/airavata-api/src/main/java/org/apache/airavata/sharing/handler/SharingRegistryServerHandler.java
@@ -35,7 +35,9 @@ import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.thrift.TException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+@Component
public class SharingRegistryServerHandler implements SharingRegistryService.Iface {
private static final Logger logger = LoggerFactory.getLogger(SharingRegistryServerHandler.class);
diff --git a/airavata-api/src/main/resources/META-INF/persistence.xml b/airavata-api/src/main/resources/META-INF/persistence.xml
deleted file mode 100644
index 5714ac677c..0000000000
--- a/airavata-api/src/main/resources/META-INF/persistence.xml
+++ /dev/null
@@ -1,203 +0,0 @@
-<?xml version="1.0"?>
-<!--*
- *
- * 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.
- *
-* -->
-<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
- <persistence-unit name="profile_service">
- <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
- <class>org.apache.airavata.security.profile.commons.user.entities.UserProfileEntity</class>
- <class>org.apache.airavata.security.profile.commons.user.entities.NSFDemographicsEntity</class>
- <class>org.apache.airavata.security.profile.commons.user.entities.CustomizedDashboardEntity</class>
- <class>org.apache.airavata.security.profile.commons.tenant.entities.GatewayEntity</class>
- <exclude-unlisted-classes>true</exclude-unlisted-classes>
- <properties>
- <property name="openjpa.jdbc.MappingDefaults"
- value="ForeignKeyDeleteAction=cascade, JoinForeignKeyDeleteAction=cascade" />
- <property name="openjpa.jdbc.DBDictionary" value="mysql" />
- </properties>
- </persistence-unit>
- <persistence-unit name="appcatalog_data_new">
- <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
- <class>org.apache.airavata.storage.model.GridftpDataMovementEntity</class>
- <class>org.apache.airavata.compute.model.ResourceJobManagerEntity</class>
- <class>org.apache.airavata.compute.model.ComputeResourceEntity</class>
- <class>org.apache.airavata.compute.model.ApplicationModuleEntity</class>
- <class>org.apache.airavata.compute.model.ApplicationDeploymentEntity</class>
- <class>org.apache.airavata.compute.model.ApplicationInterfaceEntity</class>
- <class>org.apache.airavata.compute.model.GatewayGroupsEntity</class>
- <class>org.apache.airavata.compute.model.GatewayProfileEntity</class>
- <class>org.apache.airavata.storage.model.StorageResourceEntity</class>
- <class>org.apache.airavata.storage.model.ScpDataMovementEntity</class>
- <class>org.apache.airavata.compute.model.SshJobSubmissionEntity</class>
- <class>org.apache.airavata.compute.model.GlobusSubmissionEntity</class>
- <class>org.apache.airavata.compute.model.GsisshSubmissionEntity</class>
- <class>org.apache.airavata.storage.model.GridftpEndpointEntity</class>
- <class>org.apache.airavata.compute.model.ComputeResourcePreferenceEntity</class>
- <class>org.apache.airavata.compute.model.JobSubmissionInterfaceEntity</class>
- <class>org.apache.airavata.storage.model.DataMovementInterfaceEntity</class>
- <class>org.apache.airavata.storage.model.StorageInterfaceEntity</class>
- <class>org.apache.airavata.compute.model.LocalSubmissionEntity</class>
- <class>org.apache.airavata.compute.model.GlobusGkEndpointEntity</class>
- <class>org.apache.airavata.storage.model.UnicoreDatamovementEntity</class>
- <class>org.apache.airavata.compute.model.UnicoreSubmissionEntity</class>
- <class>org.apache.airavata.compute.model.GsisshPostjobcommandEntity</class>
- <class>org.apache.airavata.compute.model.GsisshPrejobcommandEntity</class>
- <class>org.apache.airavata.compute.model.GsisshExportEntity</class>
- <class>org.apache.airavata.compute.model.LibraryApendPathEntity</class>
- <class>org.apache.airavata.compute.model.LibraryPrependPathEntity</class>
- <class>org.apache.airavata.compute.model.AppEnvironmentEntity</class>
- <class>org.apache.airavata.compute.model.PrejobCommandEntity</class>
- <class>org.apache.airavata.compute.model.PostjobCommandEntity</class>
- <class>org.apache.airavata.compute.model.AppModuleMappingEntity</class>
- <class>org.apache.airavata.compute.model.ApplicationInputEntity</class>
- <class>org.apache.airavata.compute.model.ApplicationOutputEntity</class>
- <class>org.apache.airavata.compute.model.BatchQueueEntity</class>
- <class>org.apache.airavata.compute.model.ComputeResourceFileSystemEntity</class>
- <class>org.apache.airavata.compute.model.CloudJobSubmissionEntity</class>
- <class>org.apache.airavata.compute.model.JobManagerCommandEntity</class>
- <class>org.apache.airavata.compute.model.ParallelismCommandEntity</class>
- <class>org.apache.airavata.storage.model.LocalDataMovementEntity</class>
- <class>org.apache.airavata.storage.model.StoragePreferenceEntity</class>
- <class>org.apache.airavata.compute.model.SSHAccountProvisionerConfiguration</class>
- <class>org.apache.airavata.compute.model.BatchQueueResourcePolicyEntity</class>
- <class>org.apache.airavata.compute.model.ComputeResourcePolicyEntity</class>
- <class>org.apache.airavata.compute.model.GroupComputeResourcePrefEntity</class>
- <class>org.apache.airavata.compute.model.AWSGroupComputeResourcePrefEntity</class>
- <class>org.apache.airavata.compute.model.SlurmGroupComputeResourcePrefEntity</class>
- <class>org.apache.airavata.compute.model.GroupSSHAccountProvisionerConfig</class>
- <class>org.apache.airavata.compute.model.GroupResourceProfileEntity</class>
- <class>org.apache.airavata.compute.model.ModuleLoadCmdEntity</class>
- <class>org.apache.airavata.compute.model.UserResourceProfileEntity</class>
- <class>org.apache.airavata.compute.model.UserComputeResourcePreferenceEntity</class>
- <class>org.apache.airavata.storage.model.UserStoragePreferenceEntity</class>
- <class>org.apache.airavata.compute.model.ParserEntity</class>
- <class>org.apache.airavata.compute.model.ParserInputEntity</class>
- <class>org.apache.airavata.compute.model.ParserOutputEntity</class>
- <class>org.apache.airavata.compute.model.ParsingTemplateEntity</class>
- <class>org.apache.airavata.compute.model.ParsingTemplateInputEntity</class>
- <class>org.apache.airavata.compute.model.ParserConnectorInputEntity</class>
- <class>org.apache.airavata.compute.model.ParserConnectorEntity</class>
- <class>org.apache.airavata.compute.model.ComputeResourceReservationEntity</class>
- <exclude-unlisted-classes>true</exclude-unlisted-classes>
- <properties>
- <property name="openjpa.jdbc.MappingDefaults"
- value="ForeignKeyDeleteAction=cascade, JoinForeignKeyDeleteAction=cascade" />
- <property name="openjpa.jdbc.DBDictionary" value="mysql" />
- </properties>
- </persistence-unit>
- <persistence-unit name="replicacatalog_data_new">
- <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
- <class>org.apache.airavata.storage.model.ConfigurationEntity</class>
- <class>org.apache.airavata.storage.model.DataProductEntity</class>
- <class>org.apache.airavata.storage.model.DataProductMetadataEntity</class>
- <class>org.apache.airavata.storage.model.DataReplicaLocationEntity</class>
- <class>org.apache.airavata.storage.model.DataReplicaMetadataEntity</class>
- <exclude-unlisted-classes>true</exclude-unlisted-classes>
- <properties>
- <property name="openjpa.jdbc.MappingDefaults"
- value="ForeignKeyDeleteAction=cascade, JoinForeignKeyDeleteAction=cascade" />
- <property name="openjpa.jdbc.DBDictionary" value="mysql" />
- </properties>
- </persistence-unit>
- <persistence-unit name="workflowcatalog_data_new">
- <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
- <class>org.apache.airavata.execution.model.workflow.AiravataWorkflowEntity</class>
- <class>
- org.apache.airavata.execution.model.workflow.AiravataWorkflowErrorEntity</class>
- <class>
- org.apache.airavata.execution.model.workflow.AiravataWorkflowStatusEntity</class>
- <class>org.apache.airavata.execution.model.workflow.ApplicationErrorEntity</class>
- <class>
- org.apache.airavata.execution.model.workflow.ApplicationStatusEntity</class>
- <class>org.apache.airavata.execution.model.workflow.HandlerErrorEntity</class>
- <class>org.apache.airavata.execution.model.workflow.HandlerInputEntity</class>
- <class>org.apache.airavata.execution.model.workflow.HandlerOutputEntity</class>
- <class>org.apache.airavata.execution.model.workflow.HandlerStatusEntity</class>
- <class>
- org.apache.airavata.execution.model.workflow.WorkflowApplicationEntity</class>
- <class>
- org.apache.airavata.execution.model.workflow.WorkflowConnectionEntity</class>
- <class>
- org.apache.airavata.execution.model.workflow.WorkflowDataBlockEntity</class>
- <class>org.apache.airavata.execution.model.workflow.WorkflowHandlerEntity</class>
- <exclude-unlisted-classes>true</exclude-unlisted-classes>
- <properties>
- <property name="openjpa.jdbc.MappingDefaults"
- value="ForeignKeyDeleteAction=cascade, JoinForeignKeyDeleteAction=cascade" />
- <property name="openjpa.jdbc.DBDictionary" value="mysql" />
- </properties>
- </persistence-unit>
- <persistence-unit name="experiment_data_new">
- <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
- <class>org.apache.airavata.execution.model.ExperimentEntity</class>
- <class>org.apache.airavata.execution.model.ExperimentErrorEntity</class>
- <class>org.apache.airavata.execution.model.ExperimentInputEntity</class>
- <class>org.apache.airavata.execution.model.ExperimentOutputEntity</class>
- <class>org.apache.airavata.execution.model.ExperimentStatusEntity</class>
- <class>org.apache.airavata.execution.model.ExperimentSummaryEntity</class>
- <class>org.apache.airavata.execution.model.GatewayEntity</class>
- <class>org.apache.airavata.execution.model.GatewayWorkerEntity</class>
- <class>org.apache.airavata.execution.model.GatewayUsageReportingCommandEntity</class>
- <class>org.apache.airavata.execution.model.JobEntity</class>
- <class>org.apache.airavata.execution.model.JobStatusEntity</class>
- <class>org.apache.airavata.execution.model.NotificationEntity</class>
- <class>org.apache.airavata.execution.model.ProcessEntity</class>
- <class>org.apache.airavata.execution.model.ProcessErrorEntity</class>
- <class>org.apache.airavata.execution.model.ProcessInputEntity</class>
- <class>org.apache.airavata.execution.model.ProcessOutputEntity</class>
- <class>org.apache.airavata.execution.model.ProcessResourceScheduleEntity</class>
- <class>org.apache.airavata.execution.model.ProcessStatusEntity</class>
- <class>org.apache.airavata.execution.model.ProcessWorkflowEntity</class>
- <class>org.apache.airavata.execution.model.ProjectEntity</class>
- <class>org.apache.airavata.execution.model.ProjectUserEntity</class>
- <class>org.apache.airavata.execution.model.QueueStatusEntity</class>
- <class>org.apache.airavata.execution.model.TaskEntity</class>
- <class>org.apache.airavata.execution.model.TaskErrorEntity</class>
- <class>org.apache.airavata.execution.model.TaskStatusEntity</class>
- <class>org.apache.airavata.execution.model.UserConfigurationDataEntity</class>
- <class>
- org.apache.airavata.execution.model.ComputationalResourceSchedulingEntity</class>
- <class>org.apache.airavata.execution.model.UserEntity</class>
- <exclude-unlisted-classes>true</exclude-unlisted-classes>
- <properties>
- <property name="openjpa.jdbc.MappingDefaults"
- value="ForeignKeyDeleteAction=cascade, JoinForeignKeyDeleteAction=cascade" />
- <property name="openjpa.jdbc.DBDictionary" value="mysql" />
- </properties>
- </persistence-unit>
- <persistence-unit name="airavata-sharing-registry">
- <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
- <class>org.apache.airavata.sharing.model.DomainEntity</class>
- <class>org.apache.airavata.sharing.model.EntityEntity</class>
- <class>org.apache.airavata.sharing.model.EntityTypeEntity</class>
- <class>org.apache.airavata.sharing.model.GroupMembershipEntity</class>
- <class>org.apache.airavata.sharing.model.PermissionTypeEntity</class>
- <class>org.apache.airavata.sharing.model.SharingEntity</class>
- <class>org.apache.airavata.sharing.model.UserEntity</class>
- <class>org.apache.airavata.sharing.model.GroupAdminEntity</class>
- <class>org.apache.airavata.sharing.model.UserGroupEntity</class>
- <exclude-unlisted-classes>true</exclude-unlisted-classes>
- <properties>
- <property name="openjpa.jdbc.MappingDefaults"
- value="ForeignKeyDeleteAction=cascade, JoinForeignKeyDeleteAction=cascade" />
- <property name="openjpa.jdbc.DBDictionary" value="mysql" />
- </properties>
- </persistence-unit>
-</persistence>
\ No newline at end of file
diff --git a/modules/file-server/pom.xml b/airavata-grpc-server/pom.xml
similarity index 55%
copy from modules/file-server/pom.xml
copy to airavata-grpc-server/pom.xml
index 0276417a25..6852ae093d 100644
--- a/modules/file-server/pom.xml
+++ b/airavata-grpc-server/pom.xml
@@ -16,33 +16,57 @@ 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">
+<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/xsd/maven-4.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>
+ <relativePath>../pom.xml</relativePath>
</parent>
- <artifactId>file-server</artifactId>
- <name>Airavata File Server</name>
+
+ <artifactId>airavata-grpc-server</artifactId>
+ <name>Airavata gRPC Server</name>
<dependencies>
+ <!-- Project modules -->
<dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-api</artifactId>
+ <version>${project.version}</version>
<exclusions>
<exclusion>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-logging</artifactId>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-core</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.airavata</groupId>
- <artifactId>airavata-api</artifactId>
+ <artifactId>agent-service</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>research-service</artifactId>
<version>${project.version}</version>
+ </dependency>
+
+ <!-- gRPC -->
+ <dependency>
+ <groupId>net.devh</groupId>
+ <artifactId>grpc-server-spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>ch.qos.logback</groupId>
@@ -54,52 +78,45 @@ under the License.
</exclusion>
</exclusions>
</dependency>
+
+ <!-- Spring Boot -->
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-data-jpa</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <!-- Database -->
+ <dependency>
+ <groupId>org.mariadb.jdbc</groupId>
+ <artifactId>mariadb-java-client</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
- <compilerArgs>
- <arg>-parameters</arg>
- </compilerArgs>
+ <release>17</release>
</configuration>
</plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-assembly-plugin</artifactId>
- <executions>
- <execution>
- <id>file-service-distribution-package</id>
- <phase>package</phase>
- <goals>
- <goal>single</goal>
- </goals>
- <configuration>
- <tarLongFileMode>posix</tarLongFileMode>
- <finalName>${file.service.dist.name}</finalName>
- <descriptors>
- <descriptor>src/main/assembly/file-service-bin-assembly.xml</descriptor>
- </descriptors>
- <attach>false</attach>
- </configuration>
- </execution>
- </executions>
- </plugin>
</plugins>
</build>
-
- <properties>
- <file.service.dist.name>apache-airavata-file-server-${project.version}</file.service.dist.name>
- </properties>
</project>
diff --git a/modules/restproxy/src/main/java/org/apache/airavata/restproxy/RestProxyConfiguration.java b/airavata-grpc-server/src/main/java/org/apache/airavata/grpc/server/AiravataGrpcServerConfig.java
similarity index 59%
rename from modules/restproxy/src/main/java/org/apache/airavata/restproxy/RestProxyConfiguration.java
rename to airavata-grpc-server/src/main/java/org/apache/airavata/grpc/server/AiravataGrpcServerConfig.java
index 65dbf83aa0..6bdc8c2fae 100644
--- a/modules/restproxy/src/main/java/org/apache/airavata/restproxy/RestProxyConfiguration.java
+++ b/airavata-grpc-server/src/main/java/org/apache/airavata/grpc/server/AiravataGrpcServerConfig.java
@@ -17,20 +17,19 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.airavata.restproxy;
+package org.apache.airavata.grpc.server;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.stereotype.Component;
+import org.apache.airavata.agent.connection.service.config.AgentServiceConfig;
+import org.apache.airavata.common.config.ConditionalOnServer;
+import org.apache.airavata.research.service.config.ResearchServiceConfig;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
-@Component
-@ConfigurationProperties
-public class RestProxyConfiguration {
-
- @Value("${restproxy.broker.url:airavata.host:9092}")
- private String brokerUrl;
-
- public String getBrokerUrl() {
- return brokerUrl;
- }
+@Configuration
+@ConditionalOnServer("grpc")
+@Import({
+ AgentServiceConfig.class,
+ ResearchServiceConfig.class
+})
+public class AiravataGrpcServerConfig {
}
diff --git a/airavata-grpc-server/src/main/java/org/apache/airavata/grpc/server/config/GrpcAuthInterceptor.java b/airavata-grpc-server/src/main/java/org/apache/airavata/grpc/server/config/GrpcAuthInterceptor.java
new file mode 100644
index 0000000000..142a3e78d0
--- /dev/null
+++ b/airavata-grpc-server/src/main/java/org/apache/airavata/grpc/server/config/GrpcAuthInterceptor.java
@@ -0,0 +1,104 @@
+/**
+*
+* 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.grpc.server.config;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.grpc.ForwardingServerCallListener;
+import io.grpc.Metadata;
+import io.grpc.ServerCall;
+import io.grpc.ServerCallHandler;
+import io.grpc.ServerInterceptor;
+import io.grpc.Status;
+import net.devh.boot.grpc.server.interceptor.GrpcGlobalServerInterceptor;
+import org.apache.airavata.common.security.UserContext;
+import org.apache.airavata.model.security.AuthzToken;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@GrpcGlobalServerInterceptor
+public class GrpcAuthInterceptor implements ServerInterceptor {
+
+ private static final Logger log = LoggerFactory.getLogger(GrpcAuthInterceptor.class);
+ private static final ObjectMapper objectMapper = new ObjectMapper();
+
+ private static final Metadata.Key<String> AUTHORIZATION_KEY =
+ Metadata.Key.of("authorization", Metadata.ASCII_STRING_MARSHALLER);
+ private static final Metadata.Key<String> X_CLAIMS_KEY =
+ Metadata.Key.of("x-claims", Metadata.ASCII_STRING_MARSHALLER);
+
+ @Override
+ public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
+ ServerCall<ReqT, RespT> call,
+ Metadata headers,
+ ServerCallHandler<ReqT, RespT> next) {
+
+ String authHeader = headers.get(AUTHORIZATION_KEY);
+ String accessToken = null;
+ if (authHeader != null && authHeader.startsWith("Bearer ")) {
+ accessToken = authHeader.substring(7);
+ }
+
+ if (accessToken == null) {
+ call.close(Status.UNAUTHENTICATED.withDescription("Missing authorization metadata"), new Metadata());
+ return new ServerCall.Listener<>() {};
+ }
+
+ AuthzToken authzToken = new AuthzToken(accessToken);
+
+ Map<String, String> claimsMap = new HashMap<>();
+ String claimsHeader = headers.get(X_CLAIMS_KEY);
+ if (claimsHeader != null && !claimsHeader.isBlank()) {
+ try {
+ claimsMap = objectMapper.readValue(claimsHeader, new TypeReference<Map<String, String>>() {});
+ } catch (Exception e) {
+ log.warn("Failed to parse x-claims metadata: {}", e.getMessage());
+ }
+ }
+
+ authzToken.setClaimsMap(claimsMap);
+ UserContext.setAuthzToken(authzToken);
+
+ ServerCall.Listener<ReqT> delegate = next.startCall(call, headers);
+
+ return new ForwardingServerCallListener.SimpleForwardingServerCallListener<>(delegate) {
+ @Override
+ public void onComplete() {
+ try {
+ super.onComplete();
+ } finally {
+ UserContext.clear();
+ }
+ }
+
+ @Override
+ public void onCancel() {
+ try {
+ super.onCancel();
+ } finally {
+ UserContext.clear();
+ }
+ }
+ };
+ }
+}
diff --git a/modules/file-server/pom.xml b/airavata-rest-server/pom.xml
similarity index 51%
copy from modules/file-server/pom.xml
copy to airavata-rest-server/pom.xml
index 0276417a25..433a23fc2c 100644
--- a/modules/file-server/pom.xml
+++ b/airavata-rest-server/pom.xml
@@ -16,90 +16,118 @@ 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">
+<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/xsd/maven-4.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>
+ <relativePath>../pom.xml</relativePath>
</parent>
- <artifactId>file-server</artifactId>
- <name>Airavata File Server</name>
+
+ <artifactId>airavata-rest-server</artifactId>
+ <name>Airavata REST Server</name>
<dependencies>
+ <!-- Project modules -->
<dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-api</artifactId>
+ <version>${project.version}</version>
<exclusions>
<exclusion>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-logging</artifactId>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-core</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.airavata</groupId>
- <artifactId>airavata-api</artifactId>
+ <artifactId>research-service</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>agent-service</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>file-server</artifactId>
<version>${project.version}</version>
+ </dependency>
+
+ <!-- Spring Boot -->
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-data-jpa</artifactId>
+ <exclusions>
<exclusion>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-core</artifactId>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <!-- OpenAPI -->
+ <dependency>
+ <groupId>org.springdoc</groupId>
+ <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
+ </dependency>
+
+ <!-- Kafka -->
+ <dependency>
+ <groupId>org.apache.kafka</groupId>
+ <artifactId>kafka-clients</artifactId>
+ </dependency>
+
+ <!-- Database -->
+ <dependency>
+ <groupId>org.mariadb.jdbc</groupId>
+ <artifactId>mariadb-java-client</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
- <compilerArgs>
- <arg>-parameters</arg>
- </compilerArgs>
+ <release>17</release>
</configuration>
</plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-assembly-plugin</artifactId>
- <executions>
- <execution>
- <id>file-service-distribution-package</id>
- <phase>package</phase>
- <goals>
- <goal>single</goal>
- </goals>
- <configuration>
- <tarLongFileMode>posix</tarLongFileMode>
- <finalName>${file.service.dist.name}</finalName>
- <descriptors>
- <descriptor>src/main/assembly/file-service-bin-assembly.xml</descriptor>
- </descriptors>
- <attach>false</attach>
- </configuration>
- </execution>
- </executions>
- </plugin>
</plugins>
</build>
-
- <properties>
- <file.service.dist.name>apache-airavata-file-server-${project.version}</file.service.dist.name>
- </properties>
</project>
diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/AgentServiceApplication.java b/airavata-rest-server/src/main/java/org/apache/airavata/rest/server/AiravataRestServerConfig.java
similarity index 56%
rename from modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/AgentServiceApplication.java
rename to airavata-rest-server/src/main/java/org/apache/airavata/rest/server/AiravataRestServerConfig.java
index 301fb03aad..eec0f97ca8 100644
--- a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/AgentServiceApplication.java
+++ b/airavata-rest-server/src/main/java/org/apache/airavata/rest/server/AiravataRestServerConfig.java
@@ -17,16 +17,16 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.airavata.agent.connection.service;
+package org.apache.airavata.rest.server;
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.apache.airavata.agent.connection.service.config.AgentServiceConfig;
+import org.apache.airavata.common.config.ConditionalOnServer;
+import org.apache.airavata.file.server.config.FileServerConfig;
+import org.apache.airavata.research.service.config.ResearchServiceConfig;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
-@SpringBootApplication
-@EnableJpaRepositories()
-public class AgentServiceApplication {
- public static void main(String[] args) {
- SpringApplication.run(AgentServiceApplication.class, args);
- }
-}
+@Configuration
+@ConditionalOnServer("rest")
+@Import({ResearchServiceConfig.class, AgentServiceConfig.class, FileServerConfig.class})
+public class AiravataRestServerConfig {}
diff --git a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/config/OpenApiConfig.java b/airavata-rest-server/src/main/java/org/apache/airavata/rest/server/config/OpenApiConfig.java
similarity index 52%
rename from modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/config/OpenApiConfig.java
rename to airavata-rest-server/src/main/java/org/apache/airavata/rest/server/config/OpenApiConfig.java
index db49d784c5..207bf18c1f 100644
--- a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/config/OpenApiConfig.java
+++ b/airavata-rest-server/src/main/java/org/apache/airavata/rest/server/config/OpenApiConfig.java
@@ -17,18 +17,15 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.airavata.research.service.config;
+package org.apache.airavata.rest.server.config;
+import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
-import io.swagger.v3.oas.models.media.StringSchema;
-import io.swagger.v3.oas.models.parameters.Parameter;
import io.swagger.v3.oas.models.security.OAuthFlow;
import io.swagger.v3.oas.models.security.OAuthFlows;
-import io.swagger.v3.oas.models.security.Scopes;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
-import org.springdoc.core.customizers.OpenApiCustomizer;
import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
@@ -37,54 +34,57 @@ import org.springframework.context.annotation.Configuration;
@Configuration
public class OpenApiConfig {
- @Value("${airavata.openid.url}")
- private String openIdConfigURL;
+ @Value("${airavata.security.openid-url:}")
+ private String openIdUrl;
@Bean
- public GroupedOpenApi publicApi() {
- return GroupedOpenApi.builder()
- .group("public")
- .pathsToMatch("/api/**")
- .addOpenApiCustomizer(globalHeaderCustomizer())
- .build();
- }
-
- @Bean
- public OpenAPI researchServiceOpenAPI() {
+ public OpenAPI airavataOpenApi() {
return new OpenAPI()
- .info(new Info().title("Research Service API").version("1.0.0"))
- .addSecurityItem(new SecurityRequirement().addList("oauth2-pkce"))
- .components(new io.swagger.v3.oas.models.Components()
+ .info(new Info()
+ .title("Airavata REST API")
+ .version("0.21-SNAPSHOT")
+ .description("Unified Airavata REST API"))
+ .components(new Components()
.addSecuritySchemes(
"oauth2-pkce",
new SecurityScheme()
.type(SecurityScheme.Type.OAUTH2)
.flows(new OAuthFlows()
.authorizationCode(new OAuthFlow()
- .authorizationUrl(
- openIdConfigURL + "/protocol/openid-connect/auth")
- .tokenUrl(openIdConfigURL + "/protocol/openid-connect/token")
- .scopes(new Scopes()
- .addString("openid", "openid")
- .addString("email", "email"))))));
+ .authorizationUrl(openIdUrl + "/protocol/openid-connect/auth")
+ .tokenUrl(openIdUrl + "/protocol/openid-connect/token")))))
+ .addSecurityItem(new SecurityRequirement().addList("oauth2-pkce"));
}
@Bean
- public OpenApiCustomizer globalHeaderCustomizer() {
- System.out.println("Applying global header customizer...");
- return openApi -> {
- Parameter claimsHeader = new Parameter()
- .in("header")
- .schema(new StringSchema())
- .name("X-Claims")
- .description("{userName: ..., gatewayID: ...}")
- .required(false);
+ public GroupedOpenApi researchGroup() {
+ return GroupedOpenApi.builder()
+ .group("research")
+ .pathsToMatch("/api/v1/rf/**")
+ .build();
+ }
- openApi.getPaths().values().forEach(pathItem -> {
- pathItem.readOperations().forEach(operation -> {
- operation.addParametersItem(claimsHeader);
- });
- });
- };
+ @Bean
+ public GroupedOpenApi agentGroup() {
+ return GroupedOpenApi.builder()
+ .group("agent")
+ .pathsToMatch("/api/v1/agent/**", "/api/v1/plan/**", "/api/v1/exp/**")
+ .build();
+ }
+
+ @Bean
+ public GroupedOpenApi filesGroup() {
+ return GroupedOpenApi.builder()
+ .group("files")
+ .pathsToMatch("/api/v1/files/**")
+ .build();
+ }
+
+ @Bean
+ public GroupedOpenApi kafkaGroup() {
+ return GroupedOpenApi.builder()
+ .group("kafka")
+ .pathsToMatch("/api/v1/kafka/**")
+ .build();
}
}
diff --git a/airavata-rest-server/src/main/java/org/apache/airavata/rest/server/config/SecurityConfig.java b/airavata-rest-server/src/main/java/org/apache/airavata/rest/server/config/SecurityConfig.java
new file mode 100644
index 0000000000..8caed09b3a
--- /dev/null
+++ b/airavata-rest-server/src/main/java/org/apache/airavata/rest/server/config/SecurityConfig.java
@@ -0,0 +1,132 @@
+/**
+*
+* 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.rest.server.config;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import jakarta.servlet.Filter;
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.ServletRequest;
+import jakarta.servlet.ServletResponse;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import org.apache.airavata.common.config.Constants;
+import org.apache.airavata.common.security.UserContext;
+import org.apache.airavata.model.security.AuthzToken;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class SecurityConfig {
+
+ private static final Logger log = LoggerFactory.getLogger(SecurityConfig.class);
+ private static final ObjectMapper objectMapper = new ObjectMapper();
+
+ private static final Set<String> SKIP_PREFIXES = Set.of("/swagger-ui", "/v3/api-docs", "/actuator");
+
+ @Bean
+ public FilterRegistrationBean<Filter> authFilter() {
+ FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>();
+ registration.setFilter(new AuthTokenFilter());
+ registration.addUrlPatterns("/api/*");
+ registration.setOrder(1);
+ return registration;
+ }
+
+ private static class AuthTokenFilter implements Filter {
+
+ @Override
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+ throws IOException, ServletException {
+ HttpServletRequest httpReq = (HttpServletRequest) request;
+ HttpServletResponse httpResp = (HttpServletResponse) response;
+
+ // Skip OPTIONS (CORS preflight)
+ if ("OPTIONS".equalsIgnoreCase(httpReq.getMethod())) {
+ chain.doFilter(request, response);
+ return;
+ }
+
+ // Skip swagger / api-docs / actuator
+ String path = httpReq.getRequestURI();
+ for (String prefix : SKIP_PREFIXES) {
+ if (path.startsWith(prefix)) {
+ chain.doFilter(request, response);
+ return;
+ }
+ }
+
+ try {
+ String authHeader = httpReq.getHeader("Authorization");
+ String accessToken = null;
+ if (authHeader != null && authHeader.startsWith("Bearer ")) {
+ accessToken = authHeader.substring(7);
+ }
+
+ if (accessToken == null) {
+ httpResp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Missing Authorization header");
+ return;
+ }
+
+ AuthzToken authzToken = new AuthzToken(accessToken);
+
+ // Parse X-Claims header if present (JSON map of claim key-values)
+ String claimsHeader = httpReq.getHeader("X-Claims");
+ Map<String, String> claimsMap = new HashMap<>();
+ if (claimsHeader != null && !claimsHeader.isBlank()) {
+ try {
+ claimsMap = objectMapper.readValue(claimsHeader, new TypeReference<Map<String, String>>() {});
+ } catch (Exception e) {
+ log.warn("Failed to parse X-Claims header: {}", e.getMessage());
+ }
+ }
+
+ // Also accept individual headers as fallback
+ if (!claimsMap.containsKey(Constants.USER_NAME)) {
+ String userName = httpReq.getHeader("X-User-Name");
+ if (userName != null) {
+ claimsMap.put(Constants.USER_NAME, userName);
+ }
+ }
+ if (!claimsMap.containsKey(Constants.GATEWAY_ID)) {
+ String gatewayId = httpReq.getHeader("X-Gateway-Id");
+ if (gatewayId != null) {
+ claimsMap.put(Constants.GATEWAY_ID, gatewayId);
+ }
+ }
+
+ authzToken.setClaimsMap(claimsMap);
+ UserContext.setAuthzToken(authzToken);
+
+ chain.doFilter(request, response);
+ } finally {
+ UserContext.clear();
+ }
+ }
+ }
+}
diff --git a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/config/WebMvcConfig.java b/airavata-rest-server/src/main/java/org/apache/airavata/rest/server/config/WebMvcConfig.java
similarity index 73%
rename from modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/config/WebMvcConfig.java
rename to airavata-rest-server/src/main/java/org/apache/airavata/rest/server/config/WebMvcConfig.java
index 06b393c56a..f6bc160386 100644
--- a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/config/WebMvcConfig.java
+++ b/airavata-rest-server/src/main/java/org/apache/airavata/rest/server/config/WebMvcConfig.java
@@ -17,7 +17,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.airavata.research.service.config;
+package org.apache.airavata.rest.server.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
@@ -27,17 +27,16 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
- @Value("${airavata.research-portal.url}")
- private String deployedOrigin;
-
- @Value("${airavata.research-portal.dev-url}")
- private String devOrigin;
+ @Value("${airavata.cors.allowed-origins:*}")
+ private String allowedOrigins;
@Override
public void addCorsMappings(CorsRegistry registry) {
- registry.addMapping("/**")
- .allowedOrigins(deployedOrigin, devOrigin)
- .allowedMethods("GET", "POST", "OPTIONS", "PATCH", "DELETE", "PUT")
- .allowedHeaders("*");
+ registry.addMapping("/api/**")
+ .allowedOrigins(allowedOrigins.split(","))
+ .allowedMethods("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS")
+ .allowedHeaders("*")
+ .allowCredentials(true)
+ .maxAge(3600);
}
}
diff --git a/modules/restproxy/src/main/java/org/apache/airavata/restproxy/controller/ProxyController.java b/airavata-rest-server/src/main/java/org/apache/airavata/rest/server/controller/KafkaProxyController.java
similarity index 76%
rename from modules/restproxy/src/main/java/org/apache/airavata/restproxy/controller/ProxyController.java
rename to airavata-rest-server/src/main/java/org/apache/airavata/rest/server/controller/KafkaProxyController.java
index a7c7d8fa65..bf117c7d66 100644
--- a/modules/restproxy/src/main/java/org/apache/airavata/restproxy/controller/ProxyController.java
+++ b/airavata-rest-server/src/main/java/org/apache/airavata/rest/server/controller/KafkaProxyController.java
@@ -17,44 +17,52 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.airavata.restproxy.controller;
+package org.apache.airavata.rest.server.controller;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.PostConstruct;
+import jakarta.annotation.PreDestroy;
import java.util.Properties;
-import org.apache.airavata.restproxy.RestProxyConfiguration;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.common.serialization.StringSerializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
-public class ProxyController {
- private static final Logger log = LoggerFactory.getLogger(ProxyController.class);
+@RequestMapping("/api/v1/kafka")
+public class KafkaProxyController {
+
+ private static final Logger log = LoggerFactory.getLogger(KafkaProxyController.class);
private KafkaProducer<String, String> producer;
private final ObjectMapper objectMapper = new ObjectMapper();
- private final RestProxyConfiguration restProxyConfiguration;
- public ProxyController(RestProxyConfiguration restProxyConfiguration) {
- this.restProxyConfiguration = restProxyConfiguration;
- }
+ @Value("${airavata.kafka.broker-url:localhost:9092}")
+ private String brokerUrl;
@PostConstruct
public void init() {
Properties props = new Properties();
- props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, restProxyConfiguration.getBrokerUrl());
- props.put(ProducerConfig.CLIENT_ID_CONFIG, "RestProxyProducer");
+ props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, brokerUrl);
+ props.put(ProducerConfig.CLIENT_ID_CONFIG, "AiravataKafkaProxy");
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
producer = new KafkaProducer<>(props);
}
+ @PreDestroy
+ public void destroy() {
+ if (producer != null) {
+ producer.close();
+ }
+ }
+
@PostMapping(value = "/topics/{topic}", consumes = "application/vnd.kafka.json.v2+json")
public ResponseEntity<?> postToKafka(@PathVariable("topic") String topic, @RequestBody String body) {
try {
@@ -64,16 +72,19 @@ public class ProxyController {
}
for (JsonNode record : root.get("records")) {
JsonNode valueNode = record.get("value");
- if (valueNode == null) continue;
+ if (valueNode == null) {
+ continue;
+ }
String valueStr = objectMapper.writeValueAsString(valueNode);
log.info("Received message for topic {}: {}", topic, valueStr);
var kafkaRecord = new ProducerRecord<String, String>(topic, valueStr);
producer.send(kafkaRecord).get();
- log.info("RestProxyProducer posted to topic {}: {}", topic, valueStr);
+ log.info("Posted to topic {}: {}", topic, valueStr);
producer.flush();
}
return ResponseEntity.ok().build();
} catch (Exception e) {
+ log.error("Failed to post to Kafka topic {}", topic, e);
return ResponseEntity.internalServerError().body(e.getMessage());
}
}
diff --git a/modules/restproxy/pom.xml b/airavata-server/pom.xml
similarity index 58%
rename from modules/restproxy/pom.xml
rename to airavata-server/pom.xml
index 7a955a62de..3c3c88ada8 100644
--- a/modules/restproxy/pom.xml
+++ b/airavata-server/pom.xml
@@ -16,22 +16,44 @@ 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">
+<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/xsd/maven-4.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>
+ <relativePath>../pom.xml</relativePath>
</parent>
- <artifactId>restproxy</artifactId>
- <name>Airavata REST Proxy</name>
+
+ <artifactId>airavata-server</artifactId>
+ <name>Airavata Server</name>
+ <description>Unified launcher for all Airavata server modules</description>
<dependencies>
+ <!-- Server modules -->
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-rest-server</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-grpc-server</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-thrift-server</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <!-- Spring Boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
+ <artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
@@ -39,21 +61,9 @@ under the License.
</exclusion>
</exclusions>
</dependency>
- <dependency>
- <groupId>org.apache.kafka</groupId>
- <artifactId>kafka-clients</artifactId>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-databind</artifactId>
- </dependency>
- <dependency>
- <groupId>jakarta.annotation</groupId>
- <artifactId>jakarta.annotation-api</artifactId>
- </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-actuator</artifactId>
+ <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
</dependencies>
@@ -65,38 +75,24 @@ under the License.
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
+ <artifactId>maven-assembly-plugin</artifactId>
<configuration>
- <compilerArgs>
- <arg>-parameters</arg>
- </compilerArgs>
+ <descriptors>
+ <descriptor>src/main/assembly/server-bin-assembly.xml</descriptor>
+ </descriptors>
+ <finalName>airavata-server-${project.version}</finalName>
+ <appendAssemblyId>false</appendAssemblyId>
</configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
- <id>file-service-distribution-package</id>
+ <id>create-distribution</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
- <configuration>
- <tarLongFileMode>posix</tarLongFileMode>
- <finalName>${restproxy.dist.name}</finalName>
- <descriptors>
- <descriptor>src/main/assembly/restproxy-bin-assembly.xml</descriptor>
- </descriptors>
- <attach>false</attach>
- </configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
-
- <properties>
- <restproxy.dist.name>apache-airavata-restproxy-${project.version}</restproxy.dist.name>
- </properties>
-</project>
\ No newline at end of file
+</project>
diff --git a/airavata-server/src/main/assembly/server-bin-assembly.xml b/airavata-server/src/main/assembly/server-bin-assembly.xml
new file mode 100644
index 0000000000..d976d54a89
--- /dev/null
+++ b/airavata-server/src/main/assembly/server-bin-assembly.xml
@@ -0,0 +1,61 @@
+<!--
+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.
+-->
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3
+ http://maven.apache.org/xsd/assembly-1.1.3.xsd">
+ <id>bin</id>
+ <formats>
+ <format>tar.gz</format>
+ </formats>
+ <includeBaseDirectory>true</includeBaseDirectory>
+
+ <fileSets>
+ <!-- launcher script -->
+ <fileSet>
+ <directory>src/main/bin</directory>
+ <outputDirectory>bin</outputDirectory>
+ <fileMode>0755</fileMode>
+ </fileSet>
+ <!-- configuration files -->
+ <fileSet>
+ <directory>src/main/resources</directory>
+ <outputDirectory>conf</outputDirectory>
+ <includes>
+ <include>application*.yml</include>
+ </includes>
+ </fileSet>
+ <!-- empty logs directory -->
+ <fileSet>
+ <directory>.</directory>
+ <outputDirectory>logs</outputDirectory>
+ <excludes>
+ <exclude>**/*</exclude>
+ </excludes>
+ </fileSet>
+ </fileSets>
+
+ <!-- executable jar -->
+ <files>
+ <file>
+ <source>target/${project.artifactId}-${project.version}.jar</source>
+ <outputDirectory>lib</outputDirectory>
+ </file>
+ </files>
+</assembly>
diff --git a/airavata-server/src/main/bin/airavata.sh b/airavata-server/src/main/bin/airavata.sh
new file mode 100755
index 0000000000..4a12fa1e18
--- /dev/null
+++ b/airavata-server/src/main/bin/airavata.sh
@@ -0,0 +1,8 @@
+#!/usr/bin/env bash
+set -euo pipefail
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
+BASE_DIR="$(dirname "$SCRIPT_DIR")"
+CONF_DIR="$BASE_DIR/conf"
+LIB_DIR="$BASE_DIR/lib"
+JAVA_OPTS="${JAVA_OPTS:--Xms512m -Xmx2g}"
+exec java $JAVA_OPTS -jar "$LIB_DIR"/airavata-server-*.jar --spring.config.location="$CONF_DIR/" "$@"
diff --git a/airavata-server/src/main/java/org/apache/airavata/server/AiravataServerMain.java b/airavata-server/src/main/java/org/apache/airavata/server/AiravataServerMain.java
new file mode 100644
index 0000000000..620730e29f
--- /dev/null
+++ b/airavata-server/src/main/java/org/apache/airavata/server/AiravataServerMain.java
@@ -0,0 +1,41 @@
+/*
+ * 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;
+
+import org.apache.airavata.common.config.AiravataServerProperties;
+import org.apache.airavata.grpc.server.AiravataGrpcServerConfig;
+import org.apache.airavata.rest.server.AiravataRestServerConfig;
+import org.apache.airavata.thrift.server.AiravataThriftServerConfig;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Import;
+
+@SpringBootApplication
+@EnableConfigurationProperties(AiravataServerProperties.class)
+@Import({
+ AiravataRestServerConfig.class,
+ AiravataGrpcServerConfig.class,
+ AiravataThriftServerConfig.class
+})
+public class AiravataServerMain {
+ public static void main(String[] args) {
+ SpringApplication.run(AiravataServerMain.class, args);
+ }
+}
diff --git a/airavata-server/src/main/resources/application-grpc.yml b/airavata-server/src/main/resources/application-grpc.yml
new file mode 100644
index 0000000000..3fb6e2171b
--- /dev/null
+++ b/airavata-server/src/main/resources/application-grpc.yml
@@ -0,0 +1,4 @@
+grpc:
+ server:
+ port: 19900
+ max-inbound-message-size: 20971520
diff --git a/airavata-server/src/main/resources/application-rest.yml b/airavata-server/src/main/resources/application-rest.yml
new file mode 100644
index 0000000000..8ece0266ff
--- /dev/null
+++ b/airavata-server/src/main/resources/application-rest.yml
@@ -0,0 +1,14 @@
+server:
+ port: 18889
+
+springdoc:
+ api-docs:
+ enabled: true
+ swagger-ui:
+ path: /swagger-ui.html
+ operationsSorter: alpha
+ tagsSorter: alpha
+ doc-expansion: none
+ oauth:
+ use-pkce-with-authorization-code-grant: true
+ client-id: data-catalog-portal
diff --git a/airavata-server/src/main/resources/application-thrift.yml b/airavata-server/src/main/resources/application-thrift.yml
new file mode 100644
index 0000000000..da6bd56712
--- /dev/null
+++ b/airavata-server/src/main/resources/application-thrift.yml
@@ -0,0 +1,4 @@
+airavata:
+ thrift:
+ port: 8930
+ min-threads: 50
diff --git a/airavata-server/src/main/resources/application.yml b/airavata-server/src/main/resources/application.yml
new file mode 100644
index 0000000000..e6e3ca7c98
--- /dev/null
+++ b/airavata-server/src/main/resources/application.yml
@@ -0,0 +1,67 @@
+airavata:
+ servers:
+ - thrift
+ - rest
+ - grpc
+
+spring:
+ datasource:
+ url: jdbc:mariadb://localhost:13306/airavata
+ username: airavata
+ password: ${AIRAVATA_DB_PASSWORD:123456}
+ driver-class-name: org.mariadb.jdbc.Driver
+ hikari:
+ pool-name: AiravataPool
+ leak-detection-threshold: 20000
+ jpa:
+ hibernate:
+ ddl-auto: update
+ open-in-view: false
+ servlet:
+ multipart:
+ max-file-size: 200MB
+ max-request-size: 200MB
+
+management:
+ endpoints:
+ web:
+ exposure:
+ include: health,info
+
+airavata.security:
+ openid-url: http://localhost:18080/realms/default
+
+airavata.cors:
+ allowed-origins: http://localhost:5173
+
+airavata.kafka:
+ broker-url: localhost:9092
+
+airavata.thrift:
+ host: localhost
+ port: 8930
+ min-threads: 50
+
+airavata.agent:
+ storage-resource-id: localhost_77116e91-f042-4d3a-ab9c-3e7b4ebcd5bd
+ storage-path: /tmp
+ cluster:
+ application-interface-id: AiravataAgent_f4313e4d-20c2-4bf6-bff1-8aa0f0b0c1d6
+ tunnel:
+ server-host: localhost
+ server-port: 17000
+ server-token: airavata
+ server-api-url: http://localhost:8000
+
+airavata.research:
+ hub-url: http://localhost:20000
+ portal-url: http://localhost:5173
+ dev-url: http://localhost:5173
+ dev-user: "airavata@apache.org"
+ admin-api-key: "JUPYTER_ADMIN_API_KEY"
+ limit: 10
+
+airavata.user-profile:
+ server:
+ url: localhost
+ port: 8930
diff --git a/airavata-thrift-server/pom.xml b/airavata-thrift-server/pom.xml
index 294e6ed356..f04088d66e 100644
--- a/airavata-thrift-server/pom.xml
+++ b/airavata-thrift-server/pom.xml
@@ -51,6 +51,16 @@ under the License.
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
</dependencies>
<build>
diff --git a/airavata-thrift-server/src/main/java/org/apache/airavata/api/server/AiravataServer.java b/airavata-thrift-server/src/main/java/org/apache/airavata/api/server/AiravataServer.java
deleted file mode 100644
index 9961c67aae..0000000000
--- a/airavata-thrift-server/src/main/java/org/apache/airavata/api/server/AiravataServer.java
+++ /dev/null
@@ -1,389 +0,0 @@
-/**
-*
-* 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.api.server;
-
-import java.net.InetSocketAddress;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.function.Supplier;
-import org.apache.airavata.api.Airavata;
-import org.apache.airavata.api.server.handler.AiravataServerHandler;
-import org.apache.airavata.api.server.util.Constants;
-import org.apache.airavata.common.config.ServerSettings;
-import org.apache.airavata.common.db.DBInitConfig;
-import org.apache.airavata.common.db.DBInitializer;
-import org.apache.airavata.common.exception.ApplicationSettingsException;
-import org.apache.airavata.common.server.IServer;
-import org.apache.airavata.common.server.MonitoringServer;
-import org.apache.airavata.common.server.ServiceRegistry;
-import org.apache.airavata.credential.handler.CredentialStoreServerHandler;
-import org.apache.airavata.credential.repository.util.CredentialStoreDBInitConfig;
-import org.apache.airavata.credential.store.cpi.CredentialStoreService;
-import org.apache.airavata.execution.handler.RegistryServerHandler;
-import org.apache.airavata.execution.monitor.ComputationalResourceMonitoringService;
-import org.apache.airavata.execution.monitor.EmailBasedMonitor;
-import org.apache.airavata.execution.monitor.RealtimeMonitor;
-import org.apache.airavata.execution.orchestrator.AbstractTask;
-import org.apache.airavata.execution.orchestrator.GlobalParticipant;
-import org.apache.airavata.execution.orchestrator.HelixController;
-import org.apache.airavata.execution.orchestrator.ParserWorkflowManager;
-import org.apache.airavata.execution.orchestrator.PostWorkflowManager;
-import org.apache.airavata.execution.orchestrator.PreWorkflowManager;
-import org.apache.airavata.execution.scheduler.DataInterpreterService;
-import org.apache.airavata.execution.scheduler.ProcessReschedulingService;
-import org.apache.airavata.execution.util.AppCatalogDBInitConfig;
-import org.apache.airavata.execution.util.ExpCatalogDBInitConfig;
-import org.apache.airavata.execution.util.ReplicaCatalogDBInitConfig;
-import org.apache.airavata.execution.util.WorkflowCatalogDBInitConfig;
-import org.apache.airavata.messaging.handler.DBEventManagerRunner;
-import org.apache.airavata.model.error.AiravataErrorType;
-import org.apache.airavata.model.error.AiravataSystemException;
-import org.apache.airavata.orchestrator.cpi.OrchestratorService;
-import org.apache.airavata.orchestrator.server.OrchestratorServerHandler;
-import org.apache.airavata.registry.api.RegistryService;
-import org.apache.airavata.security.profile.user.core.utils.UserProfileCatalogDBInitConfig;
-import org.apache.airavata.service.profile.groupmanager.cpi.GroupManagerService;
-import org.apache.airavata.service.profile.groupmanager.cpi.group_manager_cpiConstants;
-import org.apache.airavata.service.profile.handlers.GroupManagerServiceHandler;
-import org.apache.airavata.service.profile.handlers.IamAdminServicesHandler;
-import org.apache.airavata.service.profile.handlers.TenantProfileServiceHandler;
-import org.apache.airavata.service.profile.handlers.UserProfileServiceHandler;
-import org.apache.airavata.service.profile.iam.admin.services.cpi.IamAdminServices;
-import org.apache.airavata.service.profile.iam.admin.services.cpi.iam_admin_services_cpiConstants;
-import org.apache.airavata.service.profile.tenant.cpi.TenantProfileService;
-import org.apache.airavata.service.profile.tenant.cpi.profile_tenant_cpiConstants;
-import org.apache.airavata.service.profile.user.cpi.UserProfileService;
-import org.apache.airavata.service.profile.user.cpi.profile_user_cpiConstants;
-import org.apache.airavata.sharing.handler.SharingRegistryServerHandler;
-import org.apache.airavata.sharing.registry.service.cpi.SharingRegistryService;
-import org.apache.airavata.sharing.util.SharingRegistryDBInitConfig;
-import org.apache.thrift.TMultiplexedProcessor;
-import org.apache.thrift.server.TServer;
-import org.apache.thrift.server.TThreadPoolServer;
-import org.apache.thrift.transport.TServerSocket;
-import org.apache.thrift.transport.TServerTransport;
-import org.apache.thrift.transport.TTransportException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Consolidated Thrift server that hosts all Airavata services on a single multiplexed port.
- *
- * <p>Services registered on the TMultiplexedProcessor:
- * <ul>
- * <li>"Airavata" → AiravataServerHandler (main API)</li>
- * <li>"RegistryService" → RegistryServerHandler</li>
- * <li>"SharingRegistry" → SharingRegistryServerHandler</li>
- * <li>"CredentialStore" → CredentialStoreServerHandler</li>
- * <li>Profile services (UserProfile, TenantProfile, IamAdminServices, GroupManager)</li>
- * </ul>
- *
- * <p>All services share the same port (default 8930, from {@code apiserver.port}).
- */
-public class AiravataServer {
-
- private static final Logger logger = LoggerFactory.getLogger(AiravataServer.class);
-
- private TServer server;
- private final ServiceRegistry serviceRegistry = new ServiceRegistry();
-
- private final List<DBInitConfig> dbInitConfigs = Arrays.asList(
- new ExpCatalogDBInitConfig(),
- new AppCatalogDBInitConfig(),
- new ReplicaCatalogDBInitConfig(),
- new WorkflowCatalogDBInitConfig(),
- new CredentialStoreDBInitConfig(),
- new UserProfileCatalogDBInitConfig());
-
- public void start() throws Exception {
- logger.info("Initializing databases...");
- for (DBInitConfig dbInitConfig : dbInitConfigs) {
- DBInitializer.initializeDB(dbInitConfig);
- }
- logger.info("Databases initialized successfully");
-
- try {
- final String serverHost = ServerSettings.getSetting(Constants.API_SERVER_HOST, null);
- final int serverPort = Integer.parseInt(ServerSettings.getSetting(Constants.API_SERVER_PORT, "8930"));
-
- // --- Instantiate handlers ---
- CredentialStoreServerHandler credentialStoreServerHandler = new CredentialStoreServerHandler();
- RegistryServerHandler registryServerHandler = new RegistryServerHandler();
- SharingRegistryServerHandler sharingRegistryServerHandler =
- new SharingRegistryServerHandler(new SharingRegistryDBInitConfig());
-
- // AiravataServerHandler constructor accepting in-process handler refs is added in Task 3.
- // Until then this file will not compile.
- AiravataServerHandler airavataServerHandler = new AiravataServerHandler(
- registryServerHandler, sharingRegistryServerHandler, credentialStoreServerHandler);
- airavataServerHandler.initialize();
-
- // --- Build processors ---
- TMultiplexedProcessor multiplexedProcessor = new TMultiplexedProcessor();
-
- multiplexedProcessor.registerProcessor("Airavata", new Airavata.Processor<>(airavataServerHandler));
-
- multiplexedProcessor.registerProcessor(
- "RegistryService", new RegistryService.Processor<>(registryServerHandler));
-
- multiplexedProcessor.registerProcessor(
- "SharingRegistry", new SharingRegistryService.Processor<>(sharingRegistryServerHandler));
-
- multiplexedProcessor.registerProcessor(
- "CredentialStore", new CredentialStoreService.Processor<>(credentialStoreServerHandler));
-
- // Profile services
- multiplexedProcessor.registerProcessor(
- profile_user_cpiConstants.USER_PROFILE_CPI_NAME,
- new UserProfileService.Processor<>(new UserProfileServiceHandler()));
-
- multiplexedProcessor.registerProcessor(
- profile_tenant_cpiConstants.TENANT_PROFILE_CPI_NAME,
- new TenantProfileService.Processor<>(new TenantProfileServiceHandler()));
-
- multiplexedProcessor.registerProcessor(
- iam_admin_services_cpiConstants.IAM_ADMIN_SERVICES_CPI_NAME,
- new IamAdminServices.Processor<>(new IamAdminServicesHandler()));
-
- multiplexedProcessor.registerProcessor(
- group_manager_cpiConstants.GROUP_MANAGER_CPI_NAME,
- new GroupManagerService.Processor<>(new GroupManagerServiceHandler()));
-
- // Orchestrator service
- try {
- OrchestratorServerHandler orchestratorHandler = new OrchestratorServerHandler();
- multiplexedProcessor.registerProcessor(
- "Orchestrator", new OrchestratorService.Processor<>(orchestratorHandler));
- logger.info("Orchestrator service registered");
- } catch (Exception e) {
- logger.warn(
- "Orchestrator service failed to initialize (ZooKeeper/Helix may not be available): {}",
- e.getMessage());
- }
-
- // --- Transport and server ---
- TServerTransport serverTransport;
- if (serverHost == null) {
- serverTransport = new TServerSocket(serverPort);
- } else {
- serverTransport = new TServerSocket(new InetSocketAddress(serverHost, serverPort));
- }
-
- TThreadPoolServer.Args options = new TThreadPoolServer.Args(serverTransport);
- options.minWorkerThreads =
- Integer.parseInt(ServerSettings.getSetting(Constants.API_SERVER_MIN_THREADS, "50"));
- server = new TThreadPoolServer(options.processor(multiplexedProcessor));
-
- Thread serveThread = new Thread(
- () -> {
- server.serve();
- logger.info("Airavata Server stopped.");
- },
- "airavata-thrift-server");
- serveThread.setDaemon(true);
- serveThread.start();
-
- new Thread(() -> {
- while (!server.isServing()) {
- try {
- Thread.sleep(500);
- } catch (InterruptedException e) {
- break;
- }
- }
- if (server.isServing()) {
- logger.info("Airavata Server started on port {}", serverPort);
- logger.info("Registered services: Airavata, RegistryService, SharingRegistry, "
- + "CredentialStore, UserProfile, TenantProfile, IamAdminServices, GroupManager");
- startBackgroundServices();
- }
- })
- .start();
-
- } catch (TTransportException | ApplicationSettingsException e) {
- logger.error("Failed to start Airavata Server", e);
- throw new AiravataSystemException(AiravataErrorType.INTERNAL_ERROR);
- }
- }
-
- /**
- * Starts background services after the Thrift server is ready.
- * Each service has an independent lifecycle — failures are non-fatal
- * and do not affect other services.
- */
- private void startBackgroundServices() {
- logger.info("Starting background services...");
-
- // DB Event Manager — processes async DB events
- registerAndStart(new DBEventManagerRunner(), "db_event_manager");
-
- // Monitoring Server — Prometheus metrics endpoint
- try {
- if (ServerSettings.getBooleanSetting("api.server.monitoring.enabled")) {
- String monHost = ServerSettings.getSetting("api.server.monitoring.host", "localhost");
- int monPort = Integer.parseInt(ServerSettings.getSetting("api.server.monitoring.port", "9097"));
- MonitoringServer monitoringServer = new MonitoringServer(monHost, monPort);
- monitoringServer.setServiceRegistry(serviceRegistry);
- registerAndStart(monitoringServer, "monitoring_server");
- }
- } catch (Exception e) {
- logger.warn(" monitoring_server: config error — {}", e.getMessage());
- serviceRegistry.recordError("monitoring_server", e.getMessage());
- }
-
- // Cluster status monitoring — polls compute resource queue status
- try {
- if (ServerSettings.enableClusterStatusMonitoring()) {
- registerAndStart(new ComputationalResourceMonitoringService(), "cluster_status_monitor");
- }
- } catch (Exception e) {
- logger.warn(" cluster_status_monitor: config error — {}", e.getMessage());
- serviceRegistry.recordError("cluster_status_monitor", e.getMessage());
- }
-
- // Data interpreter — metadata analysis for submitted jobs
- try {
- if (ServerSettings.enableDataAnalyzerJobScanning()) {
- registerAndStart(new DataInterpreterService(), "data_interpreter");
- }
- } catch (Exception e) {
- logger.warn(" data_interpreter: config error — {}", e.getMessage());
- serviceRegistry.recordError("data_interpreter", e.getMessage());
- }
-
- // Process rescheduler — retries/reschedules failed processes
- try {
- if (ServerSettings.enableMetaschedulerJobScanning()) {
- registerAndStart(new ProcessReschedulingService(), "process_rescheduler");
- }
- } catch (Exception e) {
- logger.warn(" process_rescheduler: config error — {}", e.getMessage());
- serviceRegistry.recordError("process_rescheduler", e.getMessage());
- }
-
- // Execution engine services — controller must initialize the cluster
- // in ZooKeeper before participants and workflow managers can join
- try {
- registerAndStart(new HelixController(), "helix_controller");
- waitForHelixCluster();
- } catch (Exception e) {
- logger.warn(" helix_controller: config error — {}", e.getMessage());
- serviceRegistry.recordError("helix_controller", e.getMessage());
- }
- try {
- ArrayList<Class<? extends AbstractTask>> taskClasses = new ArrayList<>();
- for (String taskName : GlobalParticipant.TASK_CLASS_NAMES) {
- taskClasses.add(Class.forName(taskName).asSubclass(AbstractTask.class));
- }
- registerAndStart(new GlobalParticipant(taskClasses, null), "helix_participant");
- } catch (Exception e) {
- logger.warn(" helix_participant: config error — {}", e.getMessage());
- serviceRegistry.recordError("helix_participant", e.getMessage());
- }
- try {
- registerAndStart(new PreWorkflowManager(), "pre_workflow_manager");
- } catch (Exception e) {
- logger.warn(" pre_workflow_manager: config error — {}", e.getMessage());
- serviceRegistry.recordError("pre_workflow_manager", e.getMessage());
- }
- try {
- registerAndStart(new PostWorkflowManager(), "post_workflow_manager");
- } catch (Exception e) {
- logger.warn(" post_workflow_manager: config error — {}", e.getMessage());
- serviceRegistry.recordError("post_workflow_manager", e.getMessage());
- }
- try {
- registerAndStart(new ParserWorkflowManager(), "parser_workflow_manager");
- } catch (Exception e) {
- logger.warn(" parser_workflow_manager: config error — {}", e.getMessage());
- serviceRegistry.recordError("parser_workflow_manager", e.getMessage());
- }
-
- // Job monitors
- try {
- if (Boolean.parseBoolean(ServerSettings.getSetting("email.based.monitoring.enabled", "false"))) {
- registerAndStart(new EmailBasedMonitor(), "email_monitor");
- }
- } catch (Exception e) {
- logger.warn(" email_monitor: config error — {}", e.getMessage());
- serviceRegistry.recordError("email_monitor", e.getMessage());
- }
- try {
- registerAndStart(new RealtimeMonitor(), "realtime_monitor");
- } catch (Exception e) {
- logger.warn(" realtime_monitor: config error — {}", e.getMessage());
- serviceRegistry.recordError("realtime_monitor", e.getMessage());
- }
-
- logger.info("Background services initialization complete");
- }
-
- private void waitForHelixCluster() {
- String clusterName = ServerSettings.getSetting("helix.cluster.name", "AiravataCluster");
- String zkUrl = ServerSettings.getSetting("zookeeper.server.connection", "localhost:2181");
- logger.info(" Waiting for Helix cluster '{}' in ZooKeeper at {}...", clusterName, zkUrl);
- for (int i = 0; i < 30; i++) {
- try {
- org.apache.helix.manager.zk.ZKHelixAdmin admin = new org.apache.helix.manager.zk.ZKHelixAdmin(zkUrl);
- List<String> clusters = admin.getClusters();
- admin.close();
- if (clusters.contains(clusterName)) {
- logger.info(" Helix cluster '{}' is ready", clusterName);
- return;
- }
- } catch (Exception ignored) {
- }
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- return;
- }
- }
- logger.warn(" Helix cluster '{}' not found after 30s — proceeding anyway", clusterName);
- }
-
- private void registerAndStart(IServer service, String label) {
- registerAndStart(service, label, null);
- }
-
- private void registerAndStart(IServer service, String label, Supplier<IServer> factory) {
- Thread t = new Thread(service, "airavata-" + label);
- t.setDaemon(true);
- t.start();
- serviceRegistry.register(label, service, t, factory);
- logger.info(" {}: started", label);
- }
-
- public void stop() throws Exception {
- if (server != null && server.isServing()) {
- server.stop();
- }
- serviceRegistry.stopAll();
- }
-
- public static void main(String[] args) {
- try {
- new AiravataServer().start();
- } catch (Exception e) {
- logger.error("Error starting Airavata Server", e);
- }
- }
-}
diff --git a/airavata-thrift-server/src/main/java/org/apache/airavata/api/server/handler/AiravataServerHandler.java b/airavata-thrift-server/src/main/java/org/apache/airavata/api/server/handler/AiravataServerHandler.java
index aab5021151..7489a40328 100644
--- a/airavata-thrift-server/src/main/java/org/apache/airavata/api/server/handler/AiravataServerHandler.java
+++ b/airavata-thrift-server/src/main/java/org/apache/airavata/api/server/handler/AiravataServerHandler.java
@@ -93,7 +93,11 @@ import org.apache.airavata.storage.service.DataProductService;
import org.apache.thrift.TException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+import jakarta.annotation.PostConstruct;
+
+@Component
public class AiravataServerHandler implements Airavata.Iface {
private static final Logger logger = LoggerFactory.getLogger(AiravataServerHandler.class);
private Publisher statusPublisher;
@@ -155,6 +159,7 @@ public class AiravataServerHandler implements Airavata.Iface {
this(new RegistryServerHandler(), new SharingRegistryServerHandler(), new CredentialStoreServerHandler());
}
+ @PostConstruct
public void initialize() {
try {
initSharingRegistry();
diff --git a/airavata-thrift-server/src/main/java/org/apache/airavata/service/profile/handlers/GroupManagerServiceHandler.java b/airavata-thrift-server/src/main/java/org/apache/airavata/service/profile/handlers/GroupManagerServiceHandler.java
index 7c505b19bf..c516376476 100644
--- a/airavata-thrift-server/src/main/java/org/apache/airavata/service/profile/handlers/GroupManagerServiceHandler.java
+++ b/airavata-thrift-server/src/main/java/org/apache/airavata/service/profile/handlers/GroupManagerServiceHandler.java
@@ -45,7 +45,9 @@ import org.apache.airavata.sharing.util.SharingRegistryServiceClientFactory;
import org.apache.thrift.TException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+@Component
public class GroupManagerServiceHandler implements GroupManagerService.Iface {
private static final Logger logger = LoggerFactory.getLogger(GroupManagerServiceHandler.class);
diff --git a/airavata-thrift-server/src/main/java/org/apache/airavata/service/profile/handlers/IamAdminServicesHandler.java b/airavata-thrift-server/src/main/java/org/apache/airavata/service/profile/handlers/IamAdminServicesHandler.java
index 39c2e0e1df..bc6b42a735 100644
--- a/airavata-thrift-server/src/main/java/org/apache/airavata/service/profile/handlers/IamAdminServicesHandler.java
+++ b/airavata-thrift-server/src/main/java/org/apache/airavata/service/profile/handlers/IamAdminServicesHandler.java
@@ -50,7 +50,9 @@ import org.apache.airavata.service.profile.iam.admin.services.cpi.iam_admin_serv
import org.apache.thrift.TException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+@Component
public class IamAdminServicesHandler implements IamAdminServices.Iface {
private static final Logger logger = LoggerFactory.getLogger(IamAdminServicesHandler.class);
diff --git a/airavata-thrift-server/src/main/java/org/apache/airavata/service/profile/handlers/TenantProfileServiceHandler.java b/airavata-thrift-server/src/main/java/org/apache/airavata/service/profile/handlers/TenantProfileServiceHandler.java
index a4d9b3a77e..e107bc323b 100644
--- a/airavata-thrift-server/src/main/java/org/apache/airavata/service/profile/handlers/TenantProfileServiceHandler.java
+++ b/airavata-thrift-server/src/main/java/org/apache/airavata/service/profile/handlers/TenantProfileServiceHandler.java
@@ -45,10 +45,12 @@ import org.apache.airavata.service.profile.tenant.cpi.profile_tenant_cpiConstant
import org.apache.thrift.TException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
/**
* Created by goshenoy on 3/6/17.
*/
+@Component
public class TenantProfileServiceHandler implements TenantProfileService.Iface {
private static final Logger logger = LoggerFactory.getLogger(TenantProfileServiceHandler.class);
diff --git a/airavata-thrift-server/src/main/java/org/apache/airavata/service/profile/handlers/UserProfileServiceHandler.java b/airavata-thrift-server/src/main/java/org/apache/airavata/service/profile/handlers/UserProfileServiceHandler.java
index 303d5dd71b..510a438fdd 100644
--- a/airavata-thrift-server/src/main/java/org/apache/airavata/service/profile/handlers/UserProfileServiceHandler.java
+++ b/airavata-thrift-server/src/main/java/org/apache/airavata/service/profile/handlers/UserProfileServiceHandler.java
@@ -47,7 +47,9 @@ import org.apache.airavata.service.profile.user.cpi.profile_user_cpiConstants;
import org.apache.thrift.TException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+@Component
public class UserProfileServiceHandler implements UserProfileService.Iface {
private static final Logger logger = LoggerFactory.getLogger(UserProfileServiceHandler.class);
diff --git a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/ResearchServiceApplication.java b/airavata-thrift-server/src/main/java/org/apache/airavata/thrift/server/AiravataThriftServerConfig.java
similarity index 53%
rename from modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/ResearchServiceApplication.java
rename to airavata-thrift-server/src/main/java/org/apache/airavata/thrift/server/AiravataThriftServerConfig.java
index c24f8e75c6..81af820223 100644
--- a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/ResearchServiceApplication.java
+++ b/airavata-thrift-server/src/main/java/org/apache/airavata/thrift/server/AiravataThriftServerConfig.java
@@ -17,18 +17,22 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.airavata.research.service;
+package org.apache.airavata.thrift.server;
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
-import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.apache.airavata.common.config.ConditionalOnServer;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
-@SpringBootApplication
-@EnableJpaRepositories()
-@EnableJpaAuditing
-public class ResearchServiceApplication {
- public static void main(String[] args) {
- SpringApplication.run(ResearchServiceApplication.class, args);
- }
+@Configuration
+@ConditionalOnServer("thrift")
+@ComponentScan(basePackages = {
+ "org.apache.airavata.api.server.handler",
+ "org.apache.airavata.credential.handler",
+ "org.apache.airavata.execution.handler",
+ "org.apache.airavata.sharing.handler",
+ "org.apache.airavata.service.profile.handlers",
+ "org.apache.airavata.orchestrator.server",
+ "org.apache.airavata.thrift.server.config"
+})
+public class AiravataThriftServerConfig {
}
diff --git a/airavata-thrift-server/src/main/java/org/apache/airavata/thrift/server/config/BackgroundServicesConfig.java b/airavata-thrift-server/src/main/java/org/apache/airavata/thrift/server/config/BackgroundServicesConfig.java
new file mode 100644
index 0000000000..0b24c263a5
--- /dev/null
+++ b/airavata-thrift-server/src/main/java/org/apache/airavata/thrift/server/config/BackgroundServicesConfig.java
@@ -0,0 +1,69 @@
+/**
+*
+* 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.thrift.server.config;
+
+import java.util.Arrays;
+import java.util.List;
+import org.apache.airavata.common.db.DBInitConfig;
+import org.apache.airavata.common.db.DBInitializer;
+import org.apache.airavata.credential.repository.util.CredentialStoreDBInitConfig;
+import org.apache.airavata.execution.util.AppCatalogDBInitConfig;
+import org.apache.airavata.execution.util.ExpCatalogDBInitConfig;
+import org.apache.airavata.execution.util.ReplicaCatalogDBInitConfig;
+import org.apache.airavata.execution.util.WorkflowCatalogDBInitConfig;
+import org.apache.airavata.security.profile.user.core.utils.UserProfileCatalogDBInitConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.annotation.Configuration;
+
+import jakarta.annotation.PostConstruct;
+
+@Configuration
+public class BackgroundServicesConfig {
+
+ private static final Logger logger = LoggerFactory.getLogger(BackgroundServicesConfig.class);
+
+ private final List<DBInitConfig> dbInitConfigs = Arrays.asList(
+ new ExpCatalogDBInitConfig(),
+ new AppCatalogDBInitConfig(),
+ new ReplicaCatalogDBInitConfig(),
+ new WorkflowCatalogDBInitConfig(),
+ new CredentialStoreDBInitConfig(),
+ new UserProfileCatalogDBInitConfig());
+
+ @PostConstruct
+ public void initializeDatabases() {
+ logger.info("Initializing databases...");
+ for (DBInitConfig dbInitConfig : dbInitConfigs) {
+ DBInitializer.initializeDB(dbInitConfig);
+ }
+ logger.info("Databases initialized successfully");
+
+ // TODO: Migrate remaining background services to Spring-managed beans:
+ // - DBEventManagerRunner
+ // - MonitoringServer (Prometheus metrics)
+ // - ComputationalResourceMonitoringService
+ // - DataInterpreterService
+ // - ProcessReschedulingService
+ // - HelixController + GlobalParticipant
+ // - PreWorkflowManager, PostWorkflowManager, ParserWorkflowManager
+ // - EmailBasedMonitor, RealtimeMonitor
+ }
+}
diff --git a/airavata-thrift-server/src/main/java/org/apache/airavata/thrift/server/config/ThriftProcessorConfig.java b/airavata-thrift-server/src/main/java/org/apache/airavata/thrift/server/config/ThriftProcessorConfig.java
new file mode 100644
index 0000000000..7b888b1311
--- /dev/null
+++ b/airavata-thrift-server/src/main/java/org/apache/airavata/thrift/server/config/ThriftProcessorConfig.java
@@ -0,0 +1,121 @@
+/**
+*
+* 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.thrift.server.config;
+
+import org.apache.airavata.api.Airavata;
+import org.apache.airavata.api.server.handler.AiravataServerHandler;
+import org.apache.airavata.credential.handler.CredentialStoreServerHandler;
+import org.apache.airavata.credential.store.cpi.CredentialStoreService;
+import org.apache.airavata.execution.handler.RegistryServerHandler;
+import org.apache.airavata.orchestrator.cpi.OrchestratorService;
+import org.apache.airavata.orchestrator.server.OrchestratorServerHandler;
+import org.apache.airavata.registry.api.RegistryService;
+import org.apache.airavata.service.profile.groupmanager.cpi.GroupManagerService;
+import org.apache.airavata.service.profile.groupmanager.cpi.group_manager_cpiConstants;
+import org.apache.airavata.service.profile.handlers.GroupManagerServiceHandler;
+import org.apache.airavata.service.profile.handlers.IamAdminServicesHandler;
+import org.apache.airavata.service.profile.handlers.TenantProfileServiceHandler;
+import org.apache.airavata.service.profile.handlers.UserProfileServiceHandler;
+import org.apache.airavata.service.profile.iam.admin.services.cpi.IamAdminServices;
+import org.apache.airavata.service.profile.iam.admin.services.cpi.iam_admin_services_cpiConstants;
+import org.apache.airavata.service.profile.tenant.cpi.TenantProfileService;
+import org.apache.airavata.service.profile.tenant.cpi.profile_tenant_cpiConstants;
+import org.apache.airavata.service.profile.user.cpi.UserProfileService;
+import org.apache.airavata.service.profile.user.cpi.profile_user_cpiConstants;
+import org.apache.airavata.sharing.handler.SharingRegistryServerHandler;
+import org.apache.airavata.sharing.registry.service.cpi.SharingRegistryService;
+import org.apache.thrift.TMultiplexedProcessor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class ThriftProcessorConfig {
+
+ private static final Logger logger = LoggerFactory.getLogger(ThriftProcessorConfig.class);
+
+ @Bean
+ public OrchestratorServerHandler orchestratorServerHandler() {
+ try {
+ OrchestratorServerHandler handler = new OrchestratorServerHandler();
+ logger.info("OrchestratorServerHandler initialized successfully");
+ return handler;
+ } catch (Exception e) {
+ logger.warn("Orchestrator service failed to initialize (ZooKeeper/Helix may not be available): {}",
+ e.getMessage());
+ return null;
+ }
+ }
+
+ @Bean
+ public TMultiplexedProcessor thriftMultiplexedProcessor(
+ AiravataServerHandler airavataServerHandler,
+ RegistryServerHandler registryServerHandler,
+ SharingRegistryServerHandler sharingRegistryServerHandler,
+ CredentialStoreServerHandler credentialStoreServerHandler,
+ UserProfileServiceHandler userProfileServiceHandler,
+ TenantProfileServiceHandler tenantProfileServiceHandler,
+ IamAdminServicesHandler iamAdminServicesHandler,
+ GroupManagerServiceHandler groupManagerServiceHandler,
+ @Autowired(required = false) OrchestratorServerHandler orchestratorServerHandler) {
+
+ TMultiplexedProcessor processor = new TMultiplexedProcessor();
+
+ processor.registerProcessor("Airavata",
+ new Airavata.Processor<>(airavataServerHandler));
+
+ processor.registerProcessor("RegistryService",
+ new RegistryService.Processor<>(registryServerHandler));
+
+ processor.registerProcessor("SharingRegistry",
+ new SharingRegistryService.Processor<>(sharingRegistryServerHandler));
+
+ processor.registerProcessor("CredentialStore",
+ new CredentialStoreService.Processor<>(credentialStoreServerHandler));
+
+ processor.registerProcessor(profile_user_cpiConstants.USER_PROFILE_CPI_NAME,
+ new UserProfileService.Processor<>(userProfileServiceHandler));
+
+ processor.registerProcessor(profile_tenant_cpiConstants.TENANT_PROFILE_CPI_NAME,
+ new TenantProfileService.Processor<>(tenantProfileServiceHandler));
+
+ processor.registerProcessor(iam_admin_services_cpiConstants.IAM_ADMIN_SERVICES_CPI_NAME,
+ new IamAdminServices.Processor<>(iamAdminServicesHandler));
+
+ processor.registerProcessor(group_manager_cpiConstants.GROUP_MANAGER_CPI_NAME,
+ new GroupManagerService.Processor<>(groupManagerServiceHandler));
+
+ if (orchestratorServerHandler != null) {
+ processor.registerProcessor("Orchestrator",
+ new OrchestratorService.Processor<>(orchestratorServerHandler));
+ logger.info("Orchestrator service registered on thrift processor");
+ } else {
+ logger.warn("Orchestrator service not available — skipping registration");
+ }
+
+ logger.info("Thrift TMultiplexedProcessor configured with services: "
+ + "Airavata, RegistryService, SharingRegistry, CredentialStore, "
+ + "UserProfile, TenantProfile, IamAdminServices, GroupManager");
+
+ return processor;
+ }
+}
diff --git a/airavata-thrift-server/src/main/java/org/apache/airavata/thrift/server/config/ThriftServerLifecycle.java b/airavata-thrift-server/src/main/java/org/apache/airavata/thrift/server/config/ThriftServerLifecycle.java
new file mode 100644
index 0000000000..9d5b1b429b
--- /dev/null
+++ b/airavata-thrift-server/src/main/java/org/apache/airavata/thrift/server/config/ThriftServerLifecycle.java
@@ -0,0 +1,106 @@
+/**
+*
+* 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.thrift.server.config;
+
+import java.net.InetSocketAddress;
+import org.apache.thrift.TMultiplexedProcessor;
+import org.apache.thrift.server.TServer;
+import org.apache.thrift.server.TThreadPoolServer;
+import org.apache.thrift.transport.TServerSocket;
+import org.apache.thrift.transport.TServerTransport;
+import org.apache.thrift.transport.TTransportException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.SmartLifecycle;
+import org.springframework.stereotype.Component;
+
+@Component
+public class ThriftServerLifecycle implements SmartLifecycle {
+
+ private static final Logger logger = LoggerFactory.getLogger(ThriftServerLifecycle.class);
+
+ private final TMultiplexedProcessor processor;
+
+ @Value("${airavata.thrift.port:8930}")
+ private int port;
+
+ @Value("${airavata.thrift.host:#{null}}")
+ private String host;
+
+ @Value("${airavata.thrift.min-threads:50}")
+ private int minThreads;
+
+ private volatile TServer server;
+ private volatile boolean running;
+
+ public ThriftServerLifecycle(TMultiplexedProcessor processor) {
+ this.processor = processor;
+ }
+
+ @Override
+ public void start() {
+ try {
+ TServerTransport serverTransport;
+ if (host == null || host.isBlank()) {
+ serverTransport = new TServerSocket(port);
+ } else {
+ serverTransport = new TServerSocket(new InetSocketAddress(host, port));
+ }
+
+ TThreadPoolServer.Args options = new TThreadPoolServer.Args(serverTransport);
+ options.minWorkerThreads = minThreads;
+ server = new TThreadPoolServer(options.processor(processor));
+
+ Thread serveThread = new Thread(() -> {
+ logger.info("Airavata Thrift Server starting on port {}", port);
+ server.serve();
+ logger.info("Airavata Thrift Server stopped");
+ }, "airavata-thrift-server");
+ serveThread.setDaemon(true);
+ serveThread.start();
+
+ running = true;
+ logger.info("Airavata Thrift Server lifecycle started (port={})", port);
+ } catch (TTransportException e) {
+ throw new IllegalStateException("Failed to start Thrift server on port " + port, e);
+ }
+ }
+
+ @Override
+ public void stop() {
+ if (server != null && server.isServing()) {
+ server.stop();
+ }
+ running = false;
+ logger.info("Airavata Thrift Server lifecycle stopped");
+ }
+
+ @Override
+ public boolean isRunning() {
+ return running;
+ }
+
+ @Override
+ public int getPhase() {
+ // Start after other beans, stop before them
+ return Integer.MAX_VALUE - 100;
+ }
+}
diff --git a/modules/agent-framework/agent-service/pom.xml b/modules/agent-framework/agent-service/pom.xml
index 53db664256..2075ebf2b5 100644
--- a/modules/agent-framework/agent-service/pom.xml
+++ b/modules/agent-framework/agent-service/pom.xml
@@ -31,10 +31,6 @@ under the License.
<artifactId>agent-service</artifactId>
<name>Airavata Agent Service</name>
- <properties>
- <agent.service.dist.name>apache-airavata-agent-service-${project.version}</agent.service.dist.name>
- </properties>
-
<dependencies>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
@@ -165,35 +161,10 @@ under the License.
</exclusion>
</exclusions>
</dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-actuator</artifactId>
- </dependency>
</dependencies>
<build>
<plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-assembly-plugin</artifactId>
- <executions>
- <execution>
- <id>agent-service-distribution-package</id>
- <phase>package</phase>
- <goals>
- <goal>single</goal>
- </goals>
- <configuration>
- <tarLongFileMode>posix</tarLongFileMode>
- <finalName>${agent.service.dist.name}</finalName>
- <descriptors>
- <descriptor>src/main/assembly/agent-service-bin-assembly.xml</descriptor>
- </descriptors>
- <attach>false</attach>
- </configuration>
- </execution>
- </executions>
- </plugin>
<plugin>
<groupId>io.github.ascopes</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
diff --git a/modules/agent-framework/agent-service/src/main/assembly/agent-service-bin-assembly.xml b/modules/agent-framework/agent-service/src/main/assembly/agent-service-bin-assembly.xml
deleted file mode 100644
index d890127838..0000000000
--- a/modules/agent-framework/agent-service/src/main/assembly/agent-service-bin-assembly.xml
+++ /dev/null
@@ -1,76 +0,0 @@
-
-<!--
-
- 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.
-
--->
-<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.2.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.2.0 http://maven.apache.org/xsd/assembly-2.2.0.xsd">
- <id>bin</id>
- <includeBaseDirectory>true</includeBaseDirectory>
- <baseDirectory>${agent.service.dist.name}</baseDirectory>
- <formats>
- <format>tar.gz</format>
- </formats>
-
- <fileSets>
- <fileSet>
- <directory>src/main/resources/distribution/bin</directory>
- <outputDirectory>bin</outputDirectory>
- <fileMode>777</fileMode>
- <includes>
- <include>*.sh</include>
- </includes>
- </fileSet>
- <fileSet>
- <directory>src/main/resources/distribution/conf</directory>
- <outputDirectory>conf</outputDirectory>
- <includes>
- <include>application.yml</include>
- <include>airavata.p12</include>
- <include>log4j2.xml</include>
- </includes>
- </fileSet>
- <fileSet>
- <directory>./</directory>
- <outputDirectory>logs</outputDirectory>
- <excludes>
- <exclude>*/**</exclude>
- </excludes>
- </fileSet>
- <fileSet>
- <directory>target</directory>
- <outputDirectory>lib</outputDirectory>
- <includes>
- <include>*.jar</include>
- </includes>
- </fileSet>
- </fileSets>
-
- <dependencySets>
- <dependencySet>
- <useProjectArtifact>false</useProjectArtifact>
- <outputDirectory>lib</outputDirectory>
- <includes>
- <include>*</include>
- </includes>
- </dependencySet>
- </dependencySets>
-
-</assembly>
\ No newline at end of file
diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/UserContext.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/UserContext.java
deleted file mode 100644
index 0a43f0c675..0000000000
--- a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/UserContext.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
-*
-* 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.agent.connection.service;
-
-import java.util.Map;
-import org.apache.airavata.model.security.AuthzToken;
-
-public class UserContext {
-
- private static final ThreadLocal<AuthzToken> AUTHZ_TOKEN = new ThreadLocal<>();
-
- public static AuthzToken authzToken() {
- return AUTHZ_TOKEN.get();
- }
-
- public static void setAuthzToken(AuthzToken token) {
- AUTHZ_TOKEN.set(token);
- }
-
- public static String username() {
- return getClaim("userName");
- }
-
- public static String gatewayId() {
- return getClaim("gatewayID");
- }
-
- private static String getClaim(String claimId) {
- return AUTHZ_TOKEN.get().getClaimsMap().entrySet().stream()
- .filter(entry -> entry.getKey().equalsIgnoreCase(claimId))
- .map(Map.Entry::getValue)
- .findFirst()
- .orElseThrow(() ->
- new IllegalArgumentException("Missing '" + claimId + "' claim in the authentication token"));
- }
-}
diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/config/AgentProperties.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/config/AgentProperties.java
new file mode 100644
index 0000000000..9656de4723
--- /dev/null
+++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/config/AgentProperties.java
@@ -0,0 +1,35 @@
+package org.apache.airavata.agent.connection.service.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Component
+@ConfigurationProperties(prefix = "airavata.agent")
+public class AgentProperties {
+ private String storageResourceId;
+ private String storagePath;
+ private Tunnel tunnel = new Tunnel();
+
+ public String getStorageResourceId() { return storageResourceId; }
+ public void setStorageResourceId(String s) { this.storageResourceId = s; }
+ public String getStoragePath() { return storagePath; }
+ public void setStoragePath(String s) { this.storagePath = s; }
+ public Tunnel getTunnel() { return tunnel; }
+ public void setTunnel(Tunnel t) { this.tunnel = t; }
+
+ public static class Tunnel {
+ private String serverHost;
+ private int serverPort;
+ private String serverToken;
+ private String serverApiUrl;
+
+ public String getServerHost() { return serverHost; }
+ public void setServerHost(String s) { this.serverHost = s; }
+ public int getServerPort() { return serverPort; }
+ public void setServerPort(int p) { this.serverPort = p; }
+ public String getServerToken() { return serverToken; }
+ public void setServerToken(String s) { this.serverToken = s; }
+ public String getServerApiUrl() { return serverApiUrl; }
+ public void setServerApiUrl(String s) { this.serverApiUrl = s; }
+ }
+}
diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/config/AgentServiceConfig.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/config/AgentServiceConfig.java
new file mode 100644
index 0000000000..35b82a1136
--- /dev/null
+++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/config/AgentServiceConfig.java
@@ -0,0 +1,13 @@
+package org.apache.airavata.agent.connection.service.config;
+
+import org.springframework.boot.autoconfigure.domain.EntityScan;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+
+@Configuration
+@ComponentScan(basePackages = "org.apache.airavata.agent.connection.service")
+@EntityScan(basePackages = "org.apache.airavata.agent.connection.service")
+@EnableJpaRepositories(basePackages = "org.apache.airavata.agent.connection.service")
+public class AgentServiceConfig {
+}
diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/config/AuthzTokenFilter.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/config/AuthzTokenFilter.java
deleted file mode 100644
index afe1e44b11..0000000000
--- a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/config/AuthzTokenFilter.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
-*
-* 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.agent.connection.service.config;
-
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import jakarta.servlet.FilterChain;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.util.Map;
-import org.apache.airavata.agent.connection.service.UserContext;
-import org.apache.airavata.model.security.AuthzToken;
-import org.springframework.stereotype.Component;
-import org.springframework.web.filter.OncePerRequestFilter;
-
-@Component
-public class AuthzTokenFilter extends OncePerRequestFilter {
-
- @Override
- protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
- throws ServletException, IOException {
-
- String authorizationHeader = request.getHeader("Authorization");
- String xClaimsHeader = request.getHeader("X-Claims");
-
- if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ") && xClaimsHeader != null) {
- try {
- String accessToken = authorizationHeader.substring(7); // Remove "Bearer " prefix
- ObjectMapper objectMapper = new ObjectMapper();
- Map<String, String> claimsMap = objectMapper.readValue(xClaimsHeader, new TypeReference<>() {});
-
- AuthzToken authzToken = new AuthzToken();
- authzToken.setAccessToken(accessToken);
- authzToken.setClaimsMap(claimsMap);
-
- UserContext.setAuthzToken(authzToken);
- } catch (Exception e) {
- response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid authorization data");
- return;
- }
- }
-
- filterChain.doFilter(request, response);
- }
-}
diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/controllers/PlanController.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/controllers/PlanController.java
index e99766db9d..6f70dedc18 100644
--- a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/controllers/PlanController.java
+++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/controllers/PlanController.java
@@ -22,7 +22,7 @@ package org.apache.airavata.agent.connection.service.controllers;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;
-import org.apache.airavata.agent.connection.service.UserContext;
+import org.apache.airavata.common.security.UserContext;
import org.apache.airavata.agent.connection.service.db.entity.Plan;
import org.apache.airavata.agent.connection.service.handlers.PlanHandler;
import org.slf4j.Logger;
@@ -60,7 +60,7 @@ public class PlanController {
Plan plan = new Plan();
plan.setId(planId);
- plan.setUserId(UserContext.username());
+ plan.setUserId(UserContext.userId());
plan.setGatewayId(UserContext.gatewayId());
plan.setData(dataAsString);
@@ -75,7 +75,7 @@ public class PlanController {
@GetMapping("/user")
public ResponseEntity<List<Plan>> getPlansByUserId() {
- List<Plan> plans = planHandler.getAllPlansByUserId(UserContext.username(), UserContext.gatewayId());
+ List<Plan> plans = planHandler.getAllPlansByUserId(UserContext.userId(), UserContext.gatewayId());
return ResponseEntity.ok(plans);
}
diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentConnectionHandler.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentConnectionHandler.java
index 56a8f54fce..e62279a05d 100644
--- a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentConnectionHandler.java
+++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentConnectionHandler.java
@@ -30,15 +30,17 @@ import net.devh.boot.grpc.server.service.GrpcService;
import org.apache.airavata.agent.*;
import org.apache.airavata.agent.AsyncCommand;
import org.apache.airavata.agent.connection.service.models.*;
+import org.apache.airavata.agent.connection.service.config.AgentProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Value;
@GrpcService
public class AgentConnectionHandler extends AgentCommunicationServiceGrpc.AgentCommunicationServiceImplBase {
private static final Logger logger = LoggerFactory.getLogger(AgentConnectionHandler.class);
+ private final AgentProperties agentProperties;
+
// <streamId, StreamObserver>
private final Map<String, StreamObserver<ServerMessage>> ACTIVE_STREAMS = new ConcurrentHashMap<>();
@@ -57,17 +59,9 @@ public class AgentConnectionHandler extends AgentCommunicationServiceGrpc.AgentC
private final Map<String, PythonExecutionResponse> PYTHON_EXECUTION_RESPONSE_CACHE = new ConcurrentHashMap<>();
private final Map<String, TunnelCreationResponse> TUNNEL_CREATION_RESPONSE_CACHE = new ConcurrentHashMap<>();
- @Value("${airavata.tunnel.serverHost}")
- private String tunnelServerHost;
-
- @Value("${airavata.tunnel.serverPort}")
- private int tunnelServerPort;
-
- @Value("${airavata.tunnel.serverApiUrl}")
- private String tunnelServerApiUrl;
-
- @Value("${airavata.tunnel.serverToken}")
- private String tunnelServerToken;
+ public AgentConnectionHandler(AgentProperties agentProperties) {
+ this.agentProperties = agentProperties;
+ }
// response handling
public AgentInfoResponse isAgentUp(String agentId) {
@@ -479,10 +473,10 @@ public class AgentConnectionHandler extends AgentCommunicationServiceGrpc.AgentC
.setExecutionId(executionId)
.setLocalPort(tunnelRequest.getLocalPort())
.setLocalBindHost(tunnelRequest.getLocalBindHost())
- .setTunnelServerHost(tunnelServerHost)
- .setTunnelServerPort(tunnelServerPort)
- .setTunnelServerApiUrl(tunnelServerApiUrl)
- .setTunnelServerToken(tunnelServerToken)
+ .setTunnelServerHost(agentProperties.getTunnel().getServerHost())
+ .setTunnelServerPort(agentProperties.getTunnel().getServerPort())
+ .setTunnelServerApiUrl(agentProperties.getTunnel().getServerApiUrl())
+ .setTunnelServerToken(agentProperties.getTunnel().getServerToken())
.build())
.build());
} catch (Exception e) {
diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentManagementHandler.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentManagementHandler.java
index a976a7db8e..9939d25c30 100644
--- a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentManagementHandler.java
+++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentManagementHandler.java
@@ -23,7 +23,8 @@ import java.nio.file.Paths;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
-import org.apache.airavata.agent.connection.service.UserContext;
+import org.apache.airavata.agent.connection.service.config.AgentProperties;
+import org.apache.airavata.common.security.UserContext;
import org.apache.airavata.agent.connection.service.config.ClusterApplicationConfig;
import org.apache.airavata.agent.connection.service.models.AgentLaunchRequest;
import org.apache.airavata.agent.connection.service.models.AgentLaunchResponse;
@@ -55,19 +56,15 @@ public class AgentManagementHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(AgentManagementHandler.class);
private final AiravataService airavataService;
private final ClusterApplicationConfig clusterApplicationConfig;
-
- @Value("${airavata.storageResourceId}")
- private String storageResourceId;
-
- @Value("${airavata.storagePath}")
- private String storagePath;
+ private final AgentProperties agentProperties;
@Value("${grpc.server.host}")
private String grpcHost;
- public AgentManagementHandler(AiravataService airavataService, ClusterApplicationConfig clusterApplicationConfig) {
+ public AgentManagementHandler(AiravataService airavataService, ClusterApplicationConfig clusterApplicationConfig, AgentProperties agentProperties) {
this.airavataService = airavataService;
this.clusterApplicationConfig = clusterApplicationConfig;
+ this.agentProperties = agentProperties;
}
public AgentTerminateResponse terminateExperiment(String experimentId) {
@@ -216,7 +213,7 @@ public class AgentManagementHandler {
String projectDir = projectName.replace(" ", "_");
String projectId = airavataService.getProjectId(airavataClient, projectName);
AuthzToken authzToken = UserContext.authzToken();
- String userName = UserContext.username();
+ String userName = UserContext.userId();
String gatewayId = UserContext.gatewayId();
String appInterfaceId = clusterApplicationConfig.getApplicationInterfaceId();
ExperimentModel experimentModel = new ExperimentModel();
@@ -247,10 +244,10 @@ public class AgentManagementHandler {
userConfigurationDataModel.setAiravataAutoSchedule(false);
userConfigurationDataModel.setOverrideManualScheduledParams(false);
userConfigurationDataModel.setInputStorageResourceId(
- StringUtils.isNotBlank(req.getInputStorageId()) ? req.getInputStorageId() : storageResourceId);
+ StringUtils.isNotBlank(req.getInputStorageId()) ? req.getInputStorageId() : agentProperties.getStorageResourceId());
userConfigurationDataModel.setOutputStorageResourceId(
- StringUtils.isNotBlank(req.getOutputStorageId()) ? req.getInputStorageId() : storageResourceId);
- String experimentDataDir = Paths.get(storagePath, gatewayId, userName, projectDir, experimentName)
+ StringUtils.isNotBlank(req.getOutputStorageId()) ? req.getInputStorageId() : agentProperties.getStorageResourceId());
+ String experimentDataDir = Paths.get(agentProperties.getStoragePath(), gatewayId, userName, projectDir, experimentName)
.toString();
userConfigurationDataModel.setExperimentDataDir(experimentDataDir);
userConfigurationDataModel.setGroupResourceProfileId(groupCompResourcePref.getGroupResourceProfileId());
diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/services/AiravataFileService.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/services/AiravataFileService.java
index 0e0b61733e..cf990fc8e8 100644
--- a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/services/AiravataFileService.java
+++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/services/AiravataFileService.java
@@ -28,7 +28,7 @@ import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import org.apache.airavata.agent.ServerMessage;
-import org.apache.airavata.agent.connection.service.UserContext;
+import org.apache.airavata.common.security.UserContext;
import org.apache.airavata.agent.connection.service.models.DirectoryInfo;
import org.apache.airavata.agent.connection.service.models.ExperimentStorageResponse;
import org.apache.airavata.agent.connection.service.models.FileInfo;
diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/services/AiravataService.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/services/AiravataService.java
index f00d71a667..5df63cc194 100644
--- a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/services/AiravataService.java
+++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/services/AiravataService.java
@@ -25,7 +25,7 @@ import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
-import org.apache.airavata.agent.connection.service.UserContext;
+import org.apache.airavata.common.security.UserContext;
import org.apache.airavata.api.Airavata;
import org.apache.airavata.common.util.AiravataClientFactory;
import org.apache.airavata.model.appcatalog.groupresourceprofile.GroupComputeResourcePreference;
@@ -69,7 +69,7 @@ public class AiravataService {
while (true) {
List<Project> userProjects = airavataClient.getUserProjects(
- UserContext.authzToken(), UserContext.gatewayId(), UserContext.username(), limit, offset);
+ UserContext.authzToken(), UserContext.gatewayId(), UserContext.userId(), limit, offset);
Optional<Project> defaultProject = userProjects.stream()
.filter(project -> projectName.equals(project.getName()))
.findFirst();
@@ -84,7 +84,7 @@ public class AiravataService {
}
throw new RuntimeException(
- "Could not find project: " + projectName + " for the user: " + UserContext.username());
+ "Could not find project: " + projectName + " for the user: " + UserContext.userId());
}
public GroupComputeResourcePreference extractGroupComputeResourcePreference(
@@ -99,7 +99,7 @@ public class AiravataService {
.filter(preference -> preference.getComputeResourceId().startsWith(remoteCluster)))
.findFirst()
.orElseThrow(() -> new RuntimeException("Could not find a matching Compute Resource Preference in the "
- + groupProfileName + " group resource profile for the user: " + UserContext.username()));
+ + groupProfileName + " group resource profile for the user: " + UserContext.userId()));
}
public List<String> getUserExperimentIDs(Airavata.Client airavataClient) throws TException {
@@ -113,7 +113,7 @@ public class AiravataService {
return airavataClient.searchExperiments(
UserContext.authzToken(),
UserContext.gatewayId(),
- UserContext.username(),
+ UserContext.userId(),
filters,
limit,
offset);
diff --git a/modules/agent-framework/agent-service/src/main/resources/application.yml b/modules/agent-framework/agent-service/src/main/resources/application.yml
deleted file mode 100644
index 45de80b923..0000000000
--- a/modules/agent-framework/agent-service/src/main/resources/application.yml
+++ /dev/null
@@ -1,64 +0,0 @@
-# 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.
-#
-
-grpc:
- server:
- host: localhost
- port: 19900
- max-inbound-message-size: 20971520
-
-server:
- port: 18880
- address: localhost
-
-spring:
- servlet:
- multipart:
- max-file-size: 200MB
- max-request-size: 200MB
- datasource:
- url: "jdbc:mariadb://localhost:13306/airavata"
- username: "airavata"
- password: "123456"
- driver-class-name: org.mariadb.jdbc.Driver
- hikari:
- pool-name: AppCatalogPool
- leak-detection-threshold: 20000
- jpa:
- hibernate:
- ddl-auto: update
- open-in-view: false
-
-airavata:
- server:
- url: localhost
- port: 8930
- secure: false
- storageResourceId: localhost_77116e91-f042-4d3a-ab9c-3e7b4ebcd5bd
- storagePath: /tmp
- cluster:
- applicationInterfaceId: AiravataAgent_f4313e4d-20c2-4bf6-bff1-8aa0f0b0c1d6
- tunnel:
- serverHost: localhost
- serverPort: 17000
- serverToken: airavata
- serverApiUrl: http://localhost:8000
-
-management:
- endpoints:
- web:
- exposure:
- include: health
diff --git a/modules/file-server/pom.xml b/modules/file-server/pom.xml
index 0276417a25..07d8d06268 100644
--- a/modules/file-server/pom.xml
+++ b/modules/file-server/pom.xml
@@ -54,18 +54,10 @@ under the License.
</exclusion>
</exclusions>
</dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-actuator</artifactId>
- </dependency>
</dependencies>
<build>
<plugins>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
@@ -75,31 +67,6 @@ under the License.
</compilerArgs>
</configuration>
</plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-assembly-plugin</artifactId>
- <executions>
- <execution>
- <id>file-service-distribution-package</id>
- <phase>package</phase>
- <goals>
- <goal>single</goal>
- </goals>
- <configuration>
- <tarLongFileMode>posix</tarLongFileMode>
- <finalName>${file.service.dist.name}</finalName>
- <descriptors>
- <descriptor>src/main/assembly/file-service-bin-assembly.xml</descriptor>
- </descriptors>
- <attach>false</attach>
- </configuration>
- </execution>
- </executions>
- </plugin>
</plugins>
</build>
-
- <properties>
- <file.service.dist.name>apache-airavata-file-server-${project.version}</file.service.dist.name>
- </properties>
</project>
diff --git a/modules/file-server/src/main/assembly/file-service-bin-assembly.xml b/modules/file-server/src/main/assembly/file-service-bin-assembly.xml
deleted file mode 100644
index d925f39ab5..0000000000
--- a/modules/file-server/src/main/assembly/file-service-bin-assembly.xml
+++ /dev/null
@@ -1,75 +0,0 @@
-
-<!--
-
- 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.
-
--->
-<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.2.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.2.0 http://maven.apache.org/xsd/assembly-2.2.0.xsd">
- <id>bin</id>
- <includeBaseDirectory>true</includeBaseDirectory>
- <baseDirectory>${file.service.dist.name}</baseDirectory>
- <formats>
- <format>tar.gz</format>
- </formats>
-
- <fileSets>
- <fileSet>
- <directory>src/main/resources/distribution/bin</directory>
- <outputDirectory>bin</outputDirectory>
- <fileMode>777</fileMode>
- <includes>
- <include>*.sh</include>
- </includes>
- </fileSet>
- <fileSet>
- <directory>src/main/resources/distribution/conf</directory>
- <outputDirectory>conf</outputDirectory>
- <includes>
- <include>application.properties</include>
- <include>log4j2.xml</include>
- </includes>
- </fileSet>
- <fileSet>
- <directory>./</directory>
- <outputDirectory>logs</outputDirectory>
- <excludes>
- <exclude>*/**</exclude>
- </excludes>
- </fileSet>
- <fileSet>
- <directory>target</directory>
- <outputDirectory>lib</outputDirectory>
- <includes>
- <include>*.jar</include>
- </includes>
- </fileSet>
- </fileSets>
-
- <dependencySets>
- <dependencySet>
- <useProjectArtifact>false</useProjectArtifact>
- <outputDirectory>lib</outputDirectory>
- <includes>
- <include>*</include>
- </includes>
- </dependencySet>
- </dependencySets>
-
-</assembly>
\ No newline at end of file
diff --git a/modules/file-server/src/main/java/org/apache/airavata/file/server/FileServerApplication.java b/modules/file-server/src/main/java/org/apache/airavata/file/server/FileServerApplication.java
deleted file mode 100644
index 81561ec160..0000000000
--- a/modules/file-server/src/main/java/org/apache/airavata/file/server/FileServerApplication.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
-*
-* 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.file.server;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-
-@SpringBootApplication(
- scanBasePackages = "org.apache.airavata.file.server",
- exclude = {GroovyTemplateAutoConfiguration.class})
-@EnableConfigurationProperties(FileServerConfiguration.class)
-public class FileServerApplication {
- public static void main(String[] args) {
- SpringApplication.run(FileServerApplication.class, args);
- }
-}
diff --git a/modules/file-server/src/main/java/org/apache/airavata/file/server/FileServerConfiguration.java b/modules/file-server/src/main/java/org/apache/airavata/file/server/FileServerConfiguration.java
index f89823bd2e..69db3671b8 100644
--- a/modules/file-server/src/main/java/org/apache/airavata/file/server/FileServerConfiguration.java
+++ b/modules/file-server/src/main/java/org/apache/airavata/file/server/FileServerConfiguration.java
@@ -39,10 +39,10 @@ public class FileServerConfiguration {
return AdaptorSupportImpl.getInstance();
}
- @Value("${airavata.server.host:localhost}")
+ @Value("${airavata.thrift.host:localhost}")
private String airavataServerHost;
- @Value("${airavata.server.port:8930}")
+ @Value("${airavata.thrift.port:8930}")
private int airavataServerPort;
@Bean
diff --git a/modules/file-server/src/main/java/org/apache/airavata/file/server/config/FileServerConfig.java b/modules/file-server/src/main/java/org/apache/airavata/file/server/config/FileServerConfig.java
new file mode 100644
index 0000000000..fd80405546
--- /dev/null
+++ b/modules/file-server/src/main/java/org/apache/airavata/file/server/config/FileServerConfig.java
@@ -0,0 +1,9 @@
+package org.apache.airavata.file.server.config;
+
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ComponentScan(basePackages = "org.apache.airavata.file.server")
+public class FileServerConfig {
+}
diff --git a/modules/file-server/src/main/java/org/apache/airavata/file/server/controller/FileController.java b/modules/file-server/src/main/java/org/apache/airavata/file/server/controller/FileController.java
index c433817021..fd17237392 100644
--- a/modules/file-server/src/main/java/org/apache/airavata/file/server/controller/FileController.java
+++ b/modules/file-server/src/main/java/org/apache/airavata/file/server/controller/FileController.java
@@ -30,11 +30,11 @@ import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
-@Controller
+@RestController
+@RequestMapping("/api/v1/files")
public class FileController {
private static final Logger logger = LoggerFactory.getLogger(FileController.class);
@@ -43,7 +43,6 @@ public class FileController {
private AirvataFileService fileService;
@GetMapping("/list/{live}/{processId}")
- @ResponseBody
public Object listFilesRoot(@PathVariable String live, @PathVariable String processId) throws Exception {
String relPath = "/";
try {
@@ -55,7 +54,6 @@ public class FileController {
}
@GetMapping("/list/{live}/{processId}/{*subPath}")
- @ResponseBody
public Object listFiles(@PathVariable String live, @PathVariable String processId, @PathVariable String subPath)
throws Exception {
String relPath = subPath.startsWith("/") ? subPath : "/" + subPath;
@@ -73,7 +71,6 @@ public class FileController {
}
@GetMapping("/download/{live}/{processId}/{*subPath}")
- @ResponseBody
public ResponseEntity downloadFile(
@PathVariable String live, @PathVariable String processId, @PathVariable String subPath) {
String relPath = subPath.startsWith("/") ? subPath : "/" + subPath;
@@ -92,7 +89,6 @@ public class FileController {
}
@PostMapping("/upload/{live}/{processId}/{*subPath}")
- @ResponseBody
public ResponseEntity uploadFile(
@PathVariable String live,
@PathVariable String processId,
diff --git a/modules/file-server/src/main/resources/application.properties b/modules/file-server/src/main/resources/application.properties
deleted file mode 100644
index 44675bb7ba..0000000000
--- a/modules/file-server/src/main/resources/application.properties
+++ /dev/null
@@ -1,10 +0,0 @@
-spring.servlet.multipart.max-file-size=10MB
-spring.servlet.multipart.max-request-size=10MB
-
-# Unified Airavata server (all services on single port)
-airavata.server.host=localhost
-airavata.server.port=8930
-
-server.port=8050
-
-management.endpoints.web.exposure.include=health
diff --git a/modules/research-framework/research-service/pom.xml b/modules/research-framework/research-service/pom.xml
index 1c799544a1..d6796746f4 100644
--- a/modules/research-framework/research-service/pom.xml
+++ b/modules/research-framework/research-service/pom.xml
@@ -31,10 +31,6 @@ under the License.
<artifactId>research-service</artifactId>
<name>Airavata Research Service</name>
- <properties>
- <research.service.dist.name>apache-airavata-research-service-${project.version}</research.service.dist.name>
- </properties>
-
<dependencies>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
@@ -173,35 +169,10 @@ under the License.
</exclusion>
</exclusions>
</dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-actuator</artifactId>
- </dependency>
</dependencies>
<build>
<plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-assembly-plugin</artifactId>
- <executions>
- <execution>
- <id>research-service-distribution-package</id>
- <phase>package</phase>
- <goals>
- <goal>single</goal>
- </goals>
- <configuration>
- <tarLongFileMode>posix</tarLongFileMode>
- <finalName>${research.service.dist.name}</finalName>
- <descriptors>
- <descriptor>src/main/assembly/research-service-bin-assembly.xml</descriptor>
- </descriptors>
- <attach>false</attach>
- </configuration>
- </execution>
- </executions>
- </plugin>
<plugin>
<groupId>io.github.ascopes</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
@@ -235,10 +206,6 @@ under the License.
<release>17</release>
</configuration>
</plugin>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
diff --git a/modules/research-framework/research-service/src/main/assembly/research-service-bin-assembly.xml b/modules/research-framework/research-service/src/main/assembly/research-service-bin-assembly.xml
deleted file mode 100644
index 46bd0b32ff..0000000000
--- a/modules/research-framework/research-service/src/main/assembly/research-service-bin-assembly.xml
+++ /dev/null
@@ -1,76 +0,0 @@
-
-<!--
-
- 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.
-
--->
-<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.2.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.2.0 http://maven.apache.org/xsd/assembly-2.2.0.xsd">
- <id>bin</id>
- <includeBaseDirectory>true</includeBaseDirectory>
- <baseDirectory>${research.service.dist.name}</baseDirectory>
- <formats>
- <format>tar.gz</format>
- </formats>
-
- <fileSets>
- <fileSet>
- <directory>src/main/resources/distribution/bin</directory>
- <outputDirectory>bin</outputDirectory>
- <fileMode>777</fileMode>
- <includes>
- <include>*.sh</include>
- </includes>
- </fileSet>
- <fileSet>
- <directory>src/main/resources/distribution/conf</directory>
- <outputDirectory>conf</outputDirectory>
- <includes>
- <include>application.yml</include>
- <include>airavata.p12</include>
- <include>log4j2.xml</include>
- </includes>
- </fileSet>
- <fileSet>
- <directory>./</directory>
- <outputDirectory>logs</outputDirectory>
- <excludes>
- <exclude>*/**</exclude>
- </excludes>
- </fileSet>
- <fileSet>
- <directory>target</directory>
- <outputDirectory>lib</outputDirectory>
- <includes>
- <include>*.jar</include>
- </includes>
- </fileSet>
- </fileSets>
-
- <dependencySets>
- <dependencySet>
- <useProjectArtifact>false</useProjectArtifact>
- <outputDirectory>lib</outputDirectory>
- <includes>
- <include>*</include>
- </includes>
- </dependencySet>
- </dependencySets>
-
-</assembly>
\ No newline at end of file
diff --git a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/AiravataService.java b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/AiravataService.java
index 67f8493ac6..2dc09ed6a5 100644
--- a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/AiravataService.java
+++ b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/AiravataService.java
@@ -21,7 +21,7 @@ package org.apache.airavata.research.service;
import org.apache.airavata.model.security.AuthzToken;
import org.apache.airavata.model.user.UserProfile;
-import org.apache.airavata.research.service.model.UserContext;
+import org.apache.airavata.common.security.UserContext;
import org.apache.airavata.security.profile.client.ProfileServiceClientFactory;
import org.apache.airavata.service.profile.user.cpi.UserProfileService;
import org.apache.airavata.service.profile.user.cpi.exception.UserProfileServiceException;
diff --git a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/config/AuthzTokenFilter.java b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/config/AuthzTokenFilter.java
deleted file mode 100644
index fa55625547..0000000000
--- a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/config/AuthzTokenFilter.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/**
-*
-* 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.research.service.config;
-
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import jakarta.servlet.FilterChain;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.util.Map;
-import org.apache.airavata.model.security.AuthzToken;
-import org.apache.airavata.model.user.UserProfile;
-import org.apache.airavata.research.service.AiravataService;
-import org.apache.airavata.research.service.model.UserContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-import org.springframework.web.filter.OncePerRequestFilter;
-
-@Component
-public class AuthzTokenFilter extends OncePerRequestFilter {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(AuthzTokenFilter.class);
- private static final String USERNAME_CLAIM = "userName";
- private static final String GATEWAY_CLAIM = "gatewayID";
-
- private final AiravataService airavataService;
-
- @Value("${airavata.research-hub.url}")
- private String csHubUrl;
-
- public AuthzTokenFilter(AiravataService airavataService) {
- this.airavataService = airavataService;
- }
-
- @Override
- protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
- String path = request.getRequestURI();
-
- if (request.getMethod().equalsIgnoreCase("POST")
- || request.getMethod().equalsIgnoreCase("PUT")
- || request.getMethod().equalsIgnoreCase("PATCH")
- || request.getMethod().equalsIgnoreCase("DELETE")) {
- return false; // mutation requests should be authenticated
- }
-
- return path.startsWith("/swagger")
- || path.startsWith("/v2/api-docs")
- || path.startsWith("/v3/api-docs")
- || path.startsWith("/swagger-ui")
- || path.startsWith("/swagger-resources")
- || path.startsWith("/webjars/");
- }
-
- @Override
- protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
- throws ServletException, IOException {
- try {
- String authorizationHeader = request.getHeader("Authorization");
- String xClaimsHeader = request.getHeader("X-Claims");
-
- if (request.getMethod().equals("OPTIONS")) {
- filterChain.doFilter(request, response);
- return;
- }
-
- if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ") && xClaimsHeader != null) {
- try {
- String accessToken = authorizationHeader.substring(7); // Remove "Bearer " prefix
- ObjectMapper objectMapper = new ObjectMapper();
- Map<String, String> claimsMap = objectMapper.readValue(xClaimsHeader, new TypeReference<>() {});
-
- AuthzToken authzToken = new AuthzToken();
- authzToken.setAccessToken(accessToken);
- authzToken.setClaimsMap(claimsMap);
- UserContext.setAuthzToken(authzToken);
-
- UserProfile userProfile = airavataService.getUserProfile(
- authzToken, getClaim(authzToken, USERNAME_CLAIM), getClaim(authzToken, GATEWAY_CLAIM));
- UserContext.setUser(userProfile);
- } catch (Exception e) {
- LOGGER.error("Invalid authorization data", e);
- response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid authorization data");
- return;
- }
- }
-
- filterChain.doFilter(request, response);
- } finally {
- UserContext.clear();
- }
- }
-
- private static String getClaim(AuthzToken authzToken, String claimId) {
- return authzToken.getClaimsMap().entrySet().stream()
- .filter(entry -> entry.getKey().equalsIgnoreCase(claimId))
- .map(Map.Entry::getValue)
- .findFirst()
- .orElseThrow(() ->
- new IllegalArgumentException("Missing '" + claimId + "' claim in the authentication token"));
- }
-}
diff --git a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/config/DevDataInitializer.java b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/config/DevDataInitializer.java
index ceb321fbbf..8576d0b214 100644
--- a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/config/DevDataInitializer.java
+++ b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/config/DevDataInitializer.java
@@ -30,7 +30,6 @@ import org.apache.airavata.research.service.model.entity.Tag;
import org.apache.airavata.research.service.model.repo.ProjectRepository;
import org.apache.airavata.research.service.model.repo.ResourceRepository;
import org.apache.airavata.research.service.model.repo.TagRepository;
-import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
@@ -42,15 +41,17 @@ public class DevDataInitializer implements CommandLineRunner {
private final ProjectRepository projectRepository;
private final ResourceRepository resourceRepository;
private final TagRepository tagRepository;
-
- @Value("${airavata.research-hub.dev-user}")
- private String devUserEmail;
+ private final ResearchProperties researchProperties;
public DevDataInitializer(
- ProjectRepository projectRepository, ResourceRepository resourceRepository, TagRepository tagRepository) {
+ ProjectRepository projectRepository,
+ ResourceRepository resourceRepository,
+ TagRepository tagRepository,
+ ResearchProperties researchProperties) {
this.projectRepository = projectRepository;
this.resourceRepository = resourceRepository;
this.tagRepository = tagRepository;
+ this.researchProperties = researchProperties;
}
private void createProject(
diff --git a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/config/ResearchProperties.java b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/config/ResearchProperties.java
new file mode 100644
index 0000000000..f289ecabe1
--- /dev/null
+++ b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/config/ResearchProperties.java
@@ -0,0 +1,28 @@
+package org.apache.airavata.research.service.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Component
+@ConfigurationProperties(prefix = "airavata.research")
+public class ResearchProperties {
+ private String hubUrl;
+ private String portalUrl;
+ private String devUrl;
+ private String devUser;
+ private String adminApiKey;
+ private int limit = 10;
+
+ public String getHubUrl() { return hubUrl; }
+ public void setHubUrl(String hubUrl) { this.hubUrl = hubUrl; }
+ public String getPortalUrl() { return portalUrl; }
+ public void setPortalUrl(String portalUrl) { this.portalUrl = portalUrl; }
+ public String getDevUrl() { return devUrl; }
+ public void setDevUrl(String devUrl) { this.devUrl = devUrl; }
+ public String getDevUser() { return devUser; }
+ public void setDevUser(String devUser) { this.devUser = devUser; }
+ public String getAdminApiKey() { return adminApiKey; }
+ public void setAdminApiKey(String adminApiKey) { this.adminApiKey = adminApiKey; }
+ public int getLimit() { return limit; }
+ public void setLimit(int limit) { this.limit = limit; }
+}
diff --git a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/config/ResearchServiceConfig.java b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/config/ResearchServiceConfig.java
new file mode 100644
index 0000000000..2ba233945c
--- /dev/null
+++ b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/config/ResearchServiceConfig.java
@@ -0,0 +1,15 @@
+package org.apache.airavata.research.service.config;
+
+import org.springframework.boot.autoconfigure.domain.EntityScan;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+
+@Configuration
+@ComponentScan(basePackages = "org.apache.airavata.research.service")
+@EntityScan(basePackages = "org.apache.airavata.research.service")
+@EnableJpaRepositories(basePackages = "org.apache.airavata.research.service")
+@EnableJpaAuditing
+public class ResearchServiceConfig {
+}
diff --git a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/controller/SessionController.java b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/controller/SessionController.java
index 521acad8a5..4396f50c2a 100644
--- a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/controller/SessionController.java
+++ b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/controller/SessionController.java
@@ -24,7 +24,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
import org.apache.airavata.research.service.enums.SessionStatusEnum;
import org.apache.airavata.research.service.handlers.SessionHandler;
-import org.apache.airavata.research.service.model.UserContext;
+import org.apache.airavata.common.security.UserContext;
import org.apache.airavata.research.service.model.entity.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/handlers/ProjectHandler.java b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/handlers/ProjectHandler.java
index 9fca965303..0106ebce34 100644
--- a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/handlers/ProjectHandler.java
+++ b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/handlers/ProjectHandler.java
@@ -28,7 +28,7 @@ import java.util.stream.Collectors;
import org.apache.airavata.research.service.dto.CreateProjectRequest;
import org.apache.airavata.research.service.enums.ResourceTypeEnum;
import org.apache.airavata.research.service.enums.StateEnum;
-import org.apache.airavata.research.service.model.UserContext;
+import org.apache.airavata.common.security.UserContext;
import org.apache.airavata.research.service.model.entity.DatasetResource;
import org.apache.airavata.research.service.model.entity.Project;
import org.apache.airavata.research.service.model.entity.RepositoryResource;
diff --git a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/handlers/ResearchHubHandler.java b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/handlers/ResearchHubHandler.java
index 3cecf1c512..c5a583c81c 100644
--- a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/handlers/ResearchHubHandler.java
+++ b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/handlers/ResearchHubHandler.java
@@ -25,14 +25,14 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.apache.airavata.research.service.enums.SessionStatusEnum;
-import org.apache.airavata.research.service.model.UserContext;
+import org.apache.airavata.common.security.UserContext;
import org.apache.airavata.research.service.model.entity.DatasetResource;
import org.apache.airavata.research.service.model.entity.Project;
import org.apache.airavata.research.service.model.entity.Session;
import org.apache.airavata.research.service.model.repo.ProjectRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Value;
+import org.apache.airavata.research.service.config.ResearchProperties;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
@@ -53,29 +53,25 @@ public class ResearchHubHandler {
private final ProjectHandler projectHandler;
private final SessionHandler sessionHandler;
private final ProjectRepository projectRepository;
-
- @Value("${airavata.research-hub.url}")
- private String csHubUrl;
-
- @Value("${airavata.research-hub.adminApiKey}")
- private String adminApiKey;
-
- @Value("${airavata.research-hub.limit}")
- private int maxRHubSessions;
+ private final ResearchProperties researchProperties;
public ResearchHubHandler(
- ProjectHandler projectHandler, SessionHandler sessionHandler, ProjectRepository projectRepository) {
+ ProjectHandler projectHandler,
+ SessionHandler sessionHandler,
+ ProjectRepository projectRepository,
+ ResearchProperties researchProperties) {
this.projectHandler = projectHandler;
this.sessionHandler = sessionHandler;
this.projectRepository = projectRepository;
+ this.researchProperties = researchProperties;
}
public boolean stopSession(String sessionId) {
String userId = UserContext.userId();
- String url = String.format(SERVERS_API_URL, csHubUrl, userId, sessionId);
+ String url = String.format(SERVERS_API_URL, researchProperties.getHubUrl(), userId, sessionId);
HttpHeaders headers = new HttpHeaders();
- headers.set("Authorization", "token " + adminApiKey);
+ headers.set("Authorization", "token " + researchProperties.getAdminApiKey());
HttpEntity<Void> request = new HttpEntity<>(headers);
ResponseEntity<Void> response = new RestTemplate().exchange(url, HttpMethod.DELETE, request, Void.class);
@@ -90,10 +86,10 @@ public class ResearchHubHandler {
public boolean deleteSession(String sessionId) {
String userId = UserContext.userId();
- String url = String.format(SERVERS_API_URL, csHubUrl, userId, sessionId);
+ String url = String.format(SERVERS_API_URL, researchProperties.getHubUrl(), userId, sessionId);
HttpHeaders headers = new HttpHeaders();
- headers.set("Authorization", "token " + adminApiKey);
+ headers.set("Authorization", "token " + researchProperties.getAdminApiKey());
Map<String, Object> body = new HashMap<>();
body.put("remove", true);
@@ -113,7 +109,7 @@ public class ResearchHubHandler {
public String spinRHubSession(String projectId, String sessionName) {
String userId = UserContext.userId();
int alreadyCreated = sessionHandler.countSessionsByUserIdAndStatus(userId, SessionStatusEnum.CREATED);
- if (alreadyCreated >= maxRHubSessions) {
+ if (alreadyCreated >= researchProperties.getLimit()) {
throw new RuntimeException(
"Max number of active sessions (10) has already been reached. Please terminate or delete a session to continue.");
}
@@ -126,7 +122,7 @@ public class ResearchHubHandler {
String baseSpawnUrl = String.format(
RH_SPAWN_URL,
- csHubUrl,
+ researchProperties.getHubUrl(),
UserContext.userId(),
session.getId(),
project.getRepositoryResource().getRepositoryUrl());
@@ -153,7 +149,7 @@ public class ResearchHubHandler {
// TODO restrict this execution for owner
Session session = sessionHandler.findSession(sessionId);
- String sessionUrl = String.format(RH_SESSION_URL, csHubUrl, UserContext.userId(), session.getId());
+ String sessionUrl = String.format(RH_SESSION_URL, researchProperties.getHubUrl(), UserContext.userId(), session.getId());
LOGGER.debug("Generated the session url: {} for the user: {}", sessionUrl, UserContext.userId());
return sessionUrl;
}
diff --git a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/handlers/ResourceHandler.java b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/handlers/ResourceHandler.java
index d76b11aae6..02c30e963e 100644
--- a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/handlers/ResourceHandler.java
+++ b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/handlers/ResourceHandler.java
@@ -34,7 +34,7 @@ import org.apache.airavata.research.service.enums.PrivacyEnum;
import org.apache.airavata.research.service.enums.ResourceTypeEnum;
import org.apache.airavata.research.service.enums.StateEnum;
import org.apache.airavata.research.service.enums.StatusEnum;
-import org.apache.airavata.research.service.model.UserContext;
+import org.apache.airavata.common.security.UserContext;
import org.apache.airavata.research.service.model.entity.RepositoryResource;
import org.apache.airavata.research.service.model.entity.Resource;
import org.apache.airavata.research.service.model.entity.ResourceStar;
diff --git a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/handlers/SessionHandler.java b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/handlers/SessionHandler.java
index ae25f0caaf..6c1d442a44 100644
--- a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/handlers/SessionHandler.java
+++ b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/handlers/SessionHandler.java
@@ -23,7 +23,7 @@ import jakarta.persistence.EntityNotFoundException;
import java.util.List;
import java.util.UUID;
import org.apache.airavata.research.service.enums.SessionStatusEnum;
-import org.apache.airavata.research.service.model.UserContext;
+import org.apache.airavata.common.security.UserContext;
import org.apache.airavata.research.service.model.entity.Project;
import org.apache.airavata.research.service.model.entity.Session;
import org.apache.airavata.research.service.model.repo.SessionRepository;
diff --git a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/model/UserContext.java b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/model/UserContext.java
deleted file mode 100644
index b6c1b52887..0000000000
--- a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/model/UserContext.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
-*
-* 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.research.service.model;
-
-import org.apache.airavata.model.security.AuthzToken;
-import org.apache.airavata.model.user.UserProfile;
-
-public class UserContext {
-
- private static final ThreadLocal<AuthzToken> AUTHZ_TOKEN = new ThreadLocal<>();
- private static final ThreadLocal<UserProfile> CURRENT_USER = new ThreadLocal<>();
-
- public static AuthzToken authzToken() {
- return AUTHZ_TOKEN.get();
- }
-
- public static void setAuthzToken(AuthzToken token) {
- AUTHZ_TOKEN.set(token);
- }
-
- public static UserProfile user() {
- return CURRENT_USER.get();
- }
-
- public static void setUser(UserProfile user) {
- CURRENT_USER.set(user);
- }
-
- public static String userId() {
- return CURRENT_USER.get().getUserId();
- }
-
- public static String gatewayId() {
- return CURRENT_USER.get().getGatewayId();
- }
-
- public static boolean isAuthenticated() {
- return AUTHZ_TOKEN.get() != null;
- }
-
- public static void clear() {
- AUTHZ_TOKEN.remove();
- CURRENT_USER.remove();
- }
-}
diff --git a/modules/research-framework/research-service/src/main/resources/application.yml b/modules/research-framework/research-service/src/main/resources/application.yml
deleted file mode 100644
index 64657d99e0..0000000000
--- a/modules/research-framework/research-service/src/main/resources/application.yml
+++ /dev/null
@@ -1,76 +0,0 @@
-# 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.
-#
-
-grpc:
- server:
- port: 19908
-
-server:
- port: 18889
- address: localhost
-
-airavata:
- research-hub:
- url: http://localhost:20000
- dev-user: "airavata@apache.org"
- adminApiKey: "JUPYTER_ADMIN_API_KEY"
- limit: 10
- research-portal:
- url: http://localhost:5173
- dev-url: http://localhost:5173
- openid:
- url: "http://localhost:18080/realms/default"
- user-profile:
- server:
- url: localhost
- port: 8930
-
-spring:
- servlet:
- multipart:
- max-file-size: 200MB
- max-request-size: 200MB
- datasource:
- url: "jdbc:mariadb://localhost:13306/airavata"
- username: "airavata"
- password: "123456"
- driver-class-name: org.mariadb.jdbc.Driver
- hikari:
- pool-name: ResearchCatalogPool
- leak-detection-threshold: 20000
- jpa:
- hibernate:
- ddl-auto: update
- open-in-view: false
-
-springdoc:
- api-docs:
- enabled: true
- swagger-ui:
- path: /swagger-ui.html
- operationsSorter: alpha
- tagsSorter: alpha
- doc-expansion: none
- oauth:
- use-pkce-with-authorization-code-grant: true
- client-id: data-catalog-portal
-
-management:
- endpoints:
- web:
- exposure:
- include: health
-
diff --git a/modules/restproxy/src/main/assembly/restproxy-bin-assembly.xml b/modules/restproxy/src/main/assembly/restproxy-bin-assembly.xml
deleted file mode 100644
index de44ec314e..0000000000
--- a/modules/restproxy/src/main/assembly/restproxy-bin-assembly.xml
+++ /dev/null
@@ -1,75 +0,0 @@
-
-<!--
-
- 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.
-
--->
-<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.2.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.2.0 http://maven.apache.org/xsd/assembly-2.2.0.xsd">
- <id>bin</id>
- <includeBaseDirectory>true</includeBaseDirectory>
- <baseDirectory>${restproxy.dist.name}</baseDirectory>
- <formats>
- <format>tar.gz</format>
- </formats>
-
- <fileSets>
- <fileSet>
- <directory>src/main/resources/distribution/bin</directory>
- <outputDirectory>bin</outputDirectory>
- <fileMode>777</fileMode>
- <includes>
- <include>*.sh</include>
- </includes>
- </fileSet>
- <fileSet>
- <directory>src/main/resources/distribution/conf</directory>
- <outputDirectory>conf</outputDirectory>
- <includes>
- <include>application.properties</include>
- <include>log4j2.xml</include>
- </includes>
- </fileSet>
- <fileSet>
- <directory>./</directory>
- <outputDirectory>logs</outputDirectory>
- <excludes>
- <exclude>*/**</exclude>
- </excludes>
- </fileSet>
- <fileSet>
- <directory>target</directory>
- <outputDirectory>lib</outputDirectory>
- <includes>
- <include>*.jar</include>
- </includes>
- </fileSet>
- </fileSets>
-
- <dependencySets>
- <dependencySet>
- <useProjectArtifact>false</useProjectArtifact>
- <outputDirectory>lib</outputDirectory>
- <includes>
- <include>*</include>
- </includes>
- </dependencySet>
- </dependencySets>
-
-</assembly>
\ No newline at end of file
diff --git a/modules/restproxy/src/main/java/org/apache/airavata/restproxy/RestProxyApplication.java b/modules/restproxy/src/main/java/org/apache/airavata/restproxy/RestProxyApplication.java
deleted file mode 100644
index 9cf5dbee33..0000000000
--- a/modules/restproxy/src/main/java/org/apache/airavata/restproxy/RestProxyApplication.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
-*
-* 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.restproxy;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-
-@SpringBootApplication
-@EnableConfigurationProperties(RestProxyConfiguration.class)
-public class RestProxyApplication {
- public static void main(String[] args) {
- SpringApplication.run(RestProxyApplication.class, args);
- }
-}
diff --git a/modules/restproxy/src/main/resources/application.properties b/modules/restproxy/src/main/resources/application.properties
deleted file mode 100644
index 4c3005b8b6..0000000000
--- a/modules/restproxy/src/main/resources/application.properties
+++ /dev/null
@@ -1,4 +0,0 @@
-restproxy.broker.url=localhost:9092
-server.port=8082
-
-management.endpoints.web.exposure.include=health
diff --git a/modules/restproxy/src/main/resources/distribution/bin/restproxy.sh b/modules/restproxy/src/main/resources/distribution/bin/restproxy.sh
deleted file mode 100644
index 708d53aac4..0000000000
--- a/modules/restproxy/src/main/resources/distribution/bin/restproxy.sh
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env bash
-
-# 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.
-
-. $(dirname $0)/setenv.sh
-
-SERVICE_NAME="rest-proxy"
-MAIN_CLASS="org.apache.airavata.restproxy.RestProxyApplication"
-JAVA_OPTS="-Dairavata.config.dir=${AIRAVATA_HOME}/conf -Dairavata.home=${AIRAVATA_HOME} -Dlog4j.configurationFile=file:${AIRAVATA_HOME}/conf/log4j2.xml -Dspring.config.location=${AIRAVATA_HOME}/conf/"
-
-run_service "$SERVICE_NAME" "$MAIN_CLASS" "$JAVA_OPTS" "$@"
diff --git a/modules/restproxy/src/main/resources/distribution/bin/setenv.sh b/modules/restproxy/src/main/resources/distribution/bin/setenv.sh
deleted file mode 100644
index 9024de1d7b..0000000000
--- a/modules/restproxy/src/main/resources/distribution/bin/setenv.sh
+++ /dev/null
@@ -1,146 +0,0 @@
-#!/bin/bash
-
-# 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.
-
-# Resolve symlinks to get the real script location
-PRG="$0"
-while [ -L "$PRG" ]; do
- PRG=$(readlink "$PRG")
-done
-PRGDIR=$(dirname "$PRG")
-
-# Set AIRAVATA_HOME if not already set
-[ -z "$AIRAVATA_HOME" ] && AIRAVATA_HOME=$(cd "$PRGDIR/.." && pwd)
-
-# Build CLASSPATH from all JAR files
-CLASSPATH=$(printf "%s:" "$AIRAVATA_HOME"/lib/*.jar)
-CLASSPATH=${CLASSPATH%:} # Remove trailing colon
-
-export AIRAVATA_HOME CLASSPATH
-
-# Common function to run Airavata services
-# Usage: run_service <service_name> <main_class> <java_opts>
-run_service() {
- local SERVICE_NAME="$1" MAIN_CLASS="$2" JAVA_OPTS="$3"
- # Export SERVICE_NAME as environment variable for log4j2 configuration
- export SERVICE_NAME
- local CWD="$PWD" PID_PATH_NAME="${AIRAVATA_HOME}/bin/pid-${SERVICE_NAME}"
- local DEFAULT_LOG_FILE="${AIRAVATA_HOME}/logs/${SERVICE_NAME}.log"
- local LOG_FILE="$DEFAULT_LOG_FILE" DAEMON_MODE=false EXTRA_ARGS=""
-
- # Help text
- local HELP_TEXT="Usage: ${SERVICE_NAME}.sh
-
-command options:
- -d Run in daemon mode
- -xdebug Start ${SERVICE_NAME} under JPDA debugger
- -log <LOG_FILE> Where to redirect stdout/stderr (defaults to $DEFAULT_LOG_FILE)
- -h Display this help and exit
-
-Daemon mode commands (use with -d):
- start Start server in daemon mode
- stop Stop server running in daemon mode
- restart Restart server in daemon mode"
-
- cd "${AIRAVATA_HOME}/bin"
-
- # Helper function to stop daemon process
- stop_daemon() {
- if [[ -f "$PID_PATH_NAME" ]]; then
- local PID=$(cat "$PID_PATH_NAME")
- echo "$SERVICE_NAME stopping..."
- pkill -P "$PID"
- kill "$PID"
-
- local retry=0
- while kill -0 "$PID" 2>/dev/null && ((retry++ < 20)); do
- echo "[PID: $PID] Waiting for process to stop..."
- sleep 1
- done
-
- if kill -0 "$PID" 2>/dev/null; then
- echo "[PID: $PID] Forcefully killing non-responsive process..."
- pkill -9 -P "$PID"
- kill -9 "$PID"
- fi
-
- echo "$SERVICE_NAME is now stopped."
- rm "$PID_PATH_NAME"
- return 0
- else
- echo "$SERVICE_NAME is not running."
- return 1
- fi
- }
-
- # Helper function to start daemon process
- start_daemon() {
- echo "Starting $SERVICE_NAME ..."
- if [[ ! -f "$PID_PATH_NAME" ]]; then
- nohup java $JAVA_OPTS -classpath "$CLASSPATH" "$MAIN_CLASS" "$@" >"$LOG_FILE" 2>&1 &
- echo $! >"$PID_PATH_NAME"
- echo "$SERVICE_NAME now running: PID $(cat "$PID_PATH_NAME")"
- else
- echo "$SERVICE_NAME already running: PID $(cat "$PID_PATH_NAME")"
- fi
- }
-
- # Parse command arguments
- while (($# > 0)); do
- case "$1" in
- -d) DAEMON_MODE=true ;;
- -xdebug) JAVA_OPTS+=" -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,address=*:8000" ;;
- -log)
- shift
- LOG_FILE="$1"
- [[ "$LOG_FILE" != /* ]] && LOG_FILE="${CWD}/${LOG_FILE}"
- ;;
- start | stop | restart)
- if [[ "$DAEMON_MODE" == true ]]; then
- case "$1" in
- start) start_daemon "$@" ;;
- stop) stop_daemon ;;
- restart)
- stop_daemon
- start_daemon "$@"
- ;;
- esac
- exit 0
- else
- EXTRA_ARGS+=" $1"
- fi
- ;;
- -h)
- echo "$HELP_TEXT"
- exit 0
- ;;
- *) EXTRA_ARGS+=" $1" ;;
- esac
- shift
- done
-
- # Validate daemon mode usage
- if [[ "$DAEMON_MODE" == true ]]; then
- echo "Error: Daemon mode (-d) requires one of: start, stop, restart"
- echo "Use -h for help"
- exit 1
- fi
-
- # Run in foreground mode
- java $JAVA_OPTS -classpath "$CLASSPATH" "$MAIN_CLASS" $EXTRA_ARGS
-}
diff --git a/modules/restproxy/src/main/resources/distribution/conf/.gitkeep b/modules/restproxy/src/main/resources/distribution/conf/.gitkeep
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/modules/restproxy/src/main/resources/log4j2.xml b/modules/restproxy/src/main/resources/log4j2.xml
deleted file mode 100644
index 6e085a7f43..0000000000
--- a/modules/restproxy/src/main/resources/log4j2.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-
- 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.
-
--->
-<Configuration status="WARN">
- <Appenders>
- <Console name="Console" target="SYSTEM_OUT">
- <PatternLayout pattern="%d [%t] %-5p %c{30} %X - %m%n" />
- </Console>
- </Appenders>
- <Loggers>
- <logger name="ch.qos.logback" level="WARN" />
- <logger name="org.apache.helix" level="WARN" />
- <logger name="org.apache.zookeeper" level="ERROR" />
- <logger name="org.apache.airavata" level="INFO" />
- <logger name="org.hibernate" level="ERROR" />
- <Root level="INFO">
- <AppenderRef ref="Console" />
- </Root>
- </Loggers>
-</Configuration>
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 7c9fdd3dca..95789968d7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -74,7 +74,9 @@ under the License.
<module>modules/file-server</module>
<module>modules/agent-framework/agent-service</module>
<module>modules/research-framework/research-service</module>
- <module>modules/restproxy</module>
+ <module>airavata-rest-server</module>
+ <module>airavata-grpc-server</module>
+ <module>airavata-server</module>
</modules>
<properties>
@@ -252,11 +254,6 @@ under the License.
<artifactId>helix-core</artifactId>
<version>1.4.3</version>
</dependency>
- <dependency>
- <groupId>org.apache.openjpa</groupId>
- <artifactId>openjpa</artifactId>
- <version>4.1.1</version>
- </dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
@@ -760,11 +757,6 @@ under the License.
<artifactId>replacer</artifactId>
<version>1.5.3</version>
</plugin>
- <plugin>
- <groupId>org.apache.openjpa</groupId>
- <artifactId>openjpa-maven-plugin</artifactId>
- <version>4.1.1</version>
- </plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>