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

Reply via email to