This is an automated email from the ASF dual-hosted git repository.
dimuthuupe 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 5b276ad615 initial airavata service integration with agent framework
5b276ad615 is described below
commit 5b276ad615b5d724a3449cfa1185ca9f4d00643d
Author: lahiruj <[email protected]>
AuthorDate: Thu Jul 18 11:14:05 2024 -0400
initial airavata service integration with agent framework
---
modules/agent-framework/connection-service/pom.xml | 36 +++++++++++
.../agent/connection/service/UserContext.java | 16 +++++
.../service/config/AuthzTokenFilter.java | 48 +++++++++++++++
.../service/handlers/ExperimentHandler.java | 68 +++++++++++++++++++++
.../service/services/AiravataService.java | 36 +++++++++++
.../src/main/resources/application.yml | 9 ++-
.../src/main/resources/truststore.jks | Bin 0 -> 1654 bytes
7 files changed, 212 insertions(+), 1 deletion(-)
diff --git a/modules/agent-framework/connection-service/pom.xml
b/modules/agent-framework/connection-service/pom.xml
index 25ece1a8e2..525c4aa7e5 100644
--- a/modules/agent-framework/connection-service/pom.xml
+++ b/modules/agent-framework/connection-service/pom.xml
@@ -74,6 +74,11 @@
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-api-stubs</artifactId>
+ <version>${project.version}</version>
+ </dependency>
</dependencies>
<build>
@@ -112,6 +117,37 @@
<target>14</target>
</configuration>
</plugin>
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <version>${spring.boot.version}</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>repackage</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <executable>true</executable>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-remote-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>bundle</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <includes>
+ <include>**/*.*</include>
+ </includes>
+ </configuration>
+ </plugin>
</plugins>
</build>
diff --git
a/modules/agent-framework/connection-service/src/main/java/org/apache/airavata/agent/connection/service/UserContext.java
b/modules/agent-framework/connection-service/src/main/java/org/apache/airavata/agent/connection/service/UserContext.java
new file mode 100644
index 0000000000..6187f3893f
--- /dev/null
+++
b/modules/agent-framework/connection-service/src/main/java/org/apache/airavata/agent/connection/service/UserContext.java
@@ -0,0 +1,16 @@
+package org.apache.airavata.agent.connection.service;
+
+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);
+ }
+}
diff --git
a/modules/agent-framework/connection-service/src/main/java/org/apache/airavata/agent/connection/service/config/AuthzTokenFilter.java
b/modules/agent-framework/connection-service/src/main/java/org/apache/airavata/agent/connection/service/config/AuthzTokenFilter.java
new file mode 100644
index 0000000000..8445cc91a9
--- /dev/null
+++
b/modules/agent-framework/connection-service/src/main/java/org/apache/airavata/agent/connection/service/config/AuthzTokenFilter.java
@@ -0,0 +1,48 @@
+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 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;
+
+import java.io.IOException;
+import java.util.Map;
+
+@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/connection-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/ExperimentHandler.java
b/modules/agent-framework/connection-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/ExperimentHandler.java
new file mode 100644
index 0000000000..b33958aba1
--- /dev/null
+++
b/modules/agent-framework/connection-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/ExperimentHandler.java
@@ -0,0 +1,68 @@
+package org.apache.airavata.agent.connection.service.handlers;
+
+import org.apache.airavata.agent.connection.service.UserContext;
+import org.apache.airavata.agent.connection.service.services.AiravataService;
+import org.apache.airavata.api.Airavata;
+import
org.apache.airavata.model.appcatalog.groupresourceprofile.GroupResourceProfile;
+import org.apache.airavata.model.experiment.ExperimentModel;
+import org.apache.thrift.TException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class ExperimentHandler {
+
+ private final static Logger LOGGER =
LoggerFactory.getLogger(ExperimentHandler.class);
+ private final AiravataService airavataService;
+
+ public ExperimentHandler(AiravataService airavataService) {
+ this.airavataService = airavataService;
+ }
+
+ public ExperimentModel getExperiment(String experimentId) {
+ try {
+ Airavata.Client airavata = airavataService.airavata();
+ ExperimentModel experiment =
airavata.getExperiment(UserContext.authzToken(), experimentId);
+ GroupResourceProfile groupResourceProfile =
airavata.getGroupResourceProfile(UserContext.authzToken(),
experiment.getUserConfigurationData().getGroupResourceProfileId());
+
+ // Always get the Default allocation
+ if
(!"Default".equalsIgnoreCase(groupResourceProfile.getGroupResourceProfileName()))
{
+ List<GroupResourceProfile> groupResourceList =
airavata.getGroupResourceList(UserContext.authzToken(),
experiment.getGatewayId());
+
+ groupResourceList.stream().filter(profile ->
"Default".equalsIgnoreCase(profile.getGroupResourceProfileName())).findFirst().ifPresent(profile
->
experiment.getUserConfigurationData().setGroupResourceProfileId(profile.getGroupResourceProfileId()));
+ }
+
+ return experiment;
+
+ } catch (TException e) {
+ LOGGER.error("Error while extracting the experiment with the id:
{}", experimentId);
+ throw new RuntimeException("Error while extracting the experiment
with the id: " + experimentId, e);
+ }
+ }
+
+ public String createAndLaunchExperiment(String gatewayId, ExperimentModel
experiment) {
+ try {
+ LOGGER.info("Creating an Airavata Experiment for {}",
experiment.getExperimentName());
+ String experimentId =
airavataService.airavata().createExperiment(UserContext.authzToken(),
gatewayId, experiment);
+ LOGGER.info("Launching the application, Id: {}, Name: {}",
experimentId, experiment.getExperimentName());
+
airavataService.airavata().launchExperiment(UserContext.authzToken(),
experimentId, gatewayId);
+ return experimentId;
+ } catch (TException e) {
+ LOGGER.error("Error while creating the experiment with the name:
{}", experiment.getExperimentName());
+ throw new RuntimeException("Error while creating the experiment
with the name: " + experiment.getExperimentName(), e);
+ }
+ }
+
+ public void terminateApplication(String gatewayId, String experimentId) {
+ try {
+ LOGGER.info("Terminating the application with experiment Id: {}",
experimentId);
+
airavataService.airavata().terminateExperiment(UserContext.authzToken(),
experimentId, gatewayId);
+ } catch (Exception e) {
+ LOGGER.error("Error while terminating the application with the
experiment Id: {}", experimentId);
+ throw new RuntimeException("Error while terminating the
application with the experiment Id: " + experimentId, e);
+ }
+ }
+}
diff --git
a/modules/agent-framework/connection-service/src/main/java/org/apache/airavata/agent/connection/service/services/AiravataService.java
b/modules/agent-framework/connection-service/src/main/java/org/apache/airavata/agent/connection/service/services/AiravataService.java
new file mode 100644
index 0000000000..212dbc3c75
--- /dev/null
+++
b/modules/agent-framework/connection-service/src/main/java/org/apache/airavata/agent/connection/service/services/AiravataService.java
@@ -0,0 +1,36 @@
+package org.apache.airavata.agent.connection.service.services;
+
+import org.apache.airavata.api.Airavata;
+import org.apache.airavata.api.client.AiravataClientFactory;
+import org.apache.airavata.model.error.AiravataClientException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+@Service
+public class AiravataService {
+
+ private static final Logger LOGGER =
LoggerFactory.getLogger(AiravataService.class);
+ private static final int TIMEOUT = 100000;
+
+ @Value("${airavata.server.url}, scigap02.sciencegateways.iu.edu")
+ private String serverUrl;
+
+ @Value("${airavata.server.port}, 9930")
+ private int port;
+
+ @Value("${airavata.server.truststore.path}")
+ private String trustStorePath;
+
+ public Airavata.Client airavata() {
+ try {
+ LOGGER.debug("Creating Airavata client with the TrustStore URL - "
+ trustStorePath);
+ return AiravataClientFactory.createAiravataSecureClient(serverUrl,
port, trustStorePath, "airavata", TIMEOUT);
+
+ } catch (AiravataClientException e) {
+ LOGGER.error("Error while creating Airavata client", e);
+ throw new RuntimeException("Error while creating Airavata client",
e);
+ }
+ }
+}
diff --git
a/modules/agent-framework/connection-service/src/main/resources/application.yml
b/modules/agent-framework/connection-service/src/main/resources/application.yml
index c05154f1fc..d5aa0bfede 100644
---
a/modules/agent-framework/connection-service/src/main/resources/application.yml
+++
b/modules/agent-framework/connection-service/src/main/resources/application.yml
@@ -3,4 +3,11 @@ grpc:
port: 19900
server:
- port: 18880
\ No newline at end of file
+ port: 18880
+
+airavata:
+ server:
+ url: scigap02.sciencegateways.iu.edu
+ port: 9930
+ truststore:
+ path: CHANGE_ME
diff --git
a/modules/agent-framework/connection-service/src/main/resources/truststore.jks
b/modules/agent-framework/connection-service/src/main/resources/truststore.jks
new file mode 100644
index 0000000000..6f4ee4e433
Binary files /dev/null and
b/modules/agent-framework/connection-service/src/main/resources/truststore.jks
differ