This is an automated email from the ASF dual-hosted git repository. yasith pushed a commit to branch feat/grpc-armeria-migration in repository https://gitbox.apache.org/repos/asf/airavata.git
commit 17effd4a4b1586d620bebb00ec5b48be6a7ee65c Author: yasithdev <[email protected]> AuthorDate: Tue Mar 31 02:42:25 2026 -0400 feat: add Armeria config, auth interceptor, gRPC status mapper --- .../server/grpc/AiravataArmeriaConfig.java | 65 ++++++++++++++++++++++ .../server/grpc/AiravataGrpcServerConfig.java | 31 ----------- .../airavata/server/grpc/GrpcStatusMapper.java | 44 +++++++++++++++ .../server/grpc/config/GrpcAuthInterceptor.java | 4 +- 4 files changed, 111 insertions(+), 33 deletions(-) diff --git a/airavata-server/grpc/src/main/java/org/apache/airavata/server/grpc/AiravataArmeriaConfig.java b/airavata-server/grpc/src/main/java/org/apache/airavata/server/grpc/AiravataArmeriaConfig.java new file mode 100644 index 0000000000..a6bf9b5edf --- /dev/null +++ b/airavata-server/grpc/src/main/java/org/apache/airavata/server/grpc/AiravataArmeriaConfig.java @@ -0,0 +1,65 @@ +/** +* +* 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.grpc; + +import com.linecorp.armeria.common.HttpMethod; +import com.linecorp.armeria.server.cors.CorsService; +import com.linecorp.armeria.server.docs.DocService; +import com.linecorp.armeria.server.grpc.GrpcService; +import com.linecorp.armeria.spring.ArmeriaServerConfigurator; +import io.grpc.BindableService; +import org.apache.airavata.common.config.ConditionalOnServer; +import org.apache.airavata.server.grpc.config.GrpcAuthInterceptor; +import org.apache.airavata.agent.connection.service.config.AgentServiceConfig; +import org.apache.airavata.research.service.config.ResearchServiceConfig; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + +import java.util.List; + +@Configuration +@ConditionalOnServer("grpc") +@Import({AgentServiceConfig.class, ResearchServiceConfig.class}) +public class AiravataArmeriaConfig { + + @Bean + public ArmeriaServerConfigurator grpcServerConfigurator( + List<BindableService> grpcServices, + GrpcAuthInterceptor authInterceptor) { + return builder -> { + GrpcService grpcService = GrpcService.builder() + .addServices(grpcServices) + .intercept(authInterceptor) + .enableHttpJsonTranscoding(true) + .build(); + + builder.service(grpcService); + + builder.serviceUnder("/docs", DocService.builder().build()); + + builder.decorator(CorsService.builderForAnyOrigin() + .allowRequestMethods(HttpMethod.GET, HttpMethod.POST, + HttpMethod.PUT, HttpMethod.DELETE, HttpMethod.OPTIONS) + .allowRequestHeaders("Authorization", "Content-Type", "X-Claims") + .build()); + }; + } +} diff --git a/airavata-server/grpc/src/main/java/org/apache/airavata/server/grpc/AiravataGrpcServerConfig.java b/airavata-server/grpc/src/main/java/org/apache/airavata/server/grpc/AiravataGrpcServerConfig.java deleted file mode 100644 index 936ff4c20b..0000000000 --- a/airavata-server/grpc/src/main/java/org/apache/airavata/server/grpc/AiravataGrpcServerConfig.java +++ /dev/null @@ -1,31 +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.server.grpc; - -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; - -@Configuration -@ConditionalOnServer("grpc") -@Import({AgentServiceConfig.class, ResearchServiceConfig.class}) -public class AiravataGrpcServerConfig {} diff --git a/airavata-server/grpc/src/main/java/org/apache/airavata/server/grpc/GrpcStatusMapper.java b/airavata-server/grpc/src/main/java/org/apache/airavata/server/grpc/GrpcStatusMapper.java new file mode 100644 index 0000000000..98bbc02287 --- /dev/null +++ b/airavata-server/grpc/src/main/java/org/apache/airavata/server/grpc/GrpcStatusMapper.java @@ -0,0 +1,44 @@ +/** +* +* 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.grpc; + +import io.grpc.Status; +import io.grpc.StatusRuntimeException; + +public final class GrpcStatusMapper { + + private GrpcStatusMapper() {} + + public static StatusRuntimeException toStatusException(Exception e) { + String className = e.getClass().getSimpleName(); + String message = e.getMessage() != null ? e.getMessage() : className; + + Status status = switch (className) { + case "EntityNotFoundException" -> Status.NOT_FOUND; + case "AuthorizationException" -> Status.PERMISSION_DENIED; + case "AuthenticationException" -> Status.UNAUTHENTICATED; + case "ValidationException" -> Status.INVALID_ARGUMENT; + case "DuplicateEntityException" -> Status.ALREADY_EXISTS; + default -> Status.INTERNAL; + }; + + return status.withDescription(message).withCause(e).asRuntimeException(); + } +} diff --git a/airavata-server/grpc/src/main/java/org/apache/airavata/server/grpc/config/GrpcAuthInterceptor.java b/airavata-server/grpc/src/main/java/org/apache/airavata/server/grpc/config/GrpcAuthInterceptor.java index 0448bc8961..c73b22ef7e 100644 --- a/airavata-server/grpc/src/main/java/org/apache/airavata/server/grpc/config/GrpcAuthInterceptor.java +++ b/airavata-server/grpc/src/main/java/org/apache/airavata/server/grpc/config/GrpcAuthInterceptor.java @@ -29,13 +29,13 @@ import io.grpc.ServerInterceptor; import io.grpc.Status; import java.util.HashMap; import java.util.Map; -import net.devh.boot.grpc.server.interceptor.GrpcGlobalServerInterceptor; import org.apache.airavata.common.security.UserContext; +import org.springframework.stereotype.Component; import org.apache.airavata.model.security.AuthzToken; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@GrpcGlobalServerInterceptor +@Component public class GrpcAuthInterceptor implements ServerInterceptor { private static final Logger log = LoggerFactory.getLogger(GrpcAuthInterceptor.class);
