This is an automated email from the ASF dual-hosted git repository. yasith pushed a commit to branch feat/spring-module-reorg in repository https://gitbox.apache.org/repos/asf/airavata.git
commit fb059f2caec3264ed59e7f6612cf2fc9c192a058 Author: yasithdev <[email protected]> AuthorDate: Fri Mar 27 22:01:29 2026 -0500 feat: add @ConditionalOnServer, AiravataServerProperties, unified UserContext --- airavata-api/pom.xml | 12 +++++++ .../common/config/AiravataServerProperties.java | 16 +++++++++ .../common/config/ConditionalOnServer.java | 12 +++++++ .../airavata/common/config/OnServerCondition.java | 19 ++++++++++ .../airavata/common/security/UserContext.java | 41 ++++++++++++++++++++++ 5 files changed, 100 insertions(+) diff --git a/airavata-api/pom.xml b/airavata-api/pom.xml index 402d15879e..3cfd280c24 100644 --- a/airavata-api/pom.xml +++ b/airavata-api/pom.xml @@ -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> 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(); + } +}
