This is an automated email from the ASF dual-hosted git repository. yasith pushed a commit to branch feat/airavata-service-layer in repository https://gitbox.apache.org/repos/asf/airavata.git
commit 0a9ad48da148866fae905f9a864fe93a94988272 Author: yasithdev <[email protected]> AuthorDate: Thu Mar 26 10:09:40 2026 -0500 feat: add GatewayService and NotificationService Extract gateway and notification business logic from AiravataServerHandler into GatewayService and NotificationService with full Mockito test coverage. --- .../airavata/service/gateway/GatewayService.java | 166 +++++++++++++++++++++ .../service/notification/NotificationService.java | 63 ++++++++ .../service/gateway/GatewayServiceTest.java | 122 +++++++++++++++ .../notification/NotificationServiceTest.java | 98 ++++++++++++ 4 files changed, 449 insertions(+) diff --git a/airavata-api/src/main/java/org/apache/airavata/service/gateway/GatewayService.java b/airavata-api/src/main/java/org/apache/airavata/service/gateway/GatewayService.java new file mode 100644 index 0000000000..88fa6bfe3c --- /dev/null +++ b/airavata-api/src/main/java/org/apache/airavata/service/gateway/GatewayService.java @@ -0,0 +1,166 @@ +package org.apache.airavata.service.gateway; + +import org.apache.airavata.common.utils.ServerSettings; +import org.apache.airavata.model.group.ResourceType; +import org.apache.airavata.model.workspace.Gateway; +import org.apache.airavata.registry.api.service.handler.RegistryServerHandler; +import org.apache.airavata.service.context.RequestContext; +import org.apache.airavata.service.exception.ServiceException; +import org.apache.airavata.sharing.registry.models.Domain; +import org.apache.airavata.sharing.registry.models.EntityType; +import org.apache.airavata.sharing.registry.models.PermissionType; +import org.apache.airavata.sharing.registry.server.SharingRegistryServerHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +public class GatewayService { + + private static final Logger logger = LoggerFactory.getLogger(GatewayService.class); + + private final RegistryServerHandler registryHandler; + private final SharingRegistryServerHandler sharingHandler; + + public GatewayService(RegistryServerHandler registryHandler, SharingRegistryServerHandler sharingHandler) { + this.registryHandler = registryHandler; + this.sharingHandler = sharingHandler; + } + + public String addGateway(RequestContext ctx, Gateway gateway) throws ServiceException { + try { + String gatewayId = registryHandler.addGateway(gateway); + + if (isSharingEnabled()) { + Domain domain = new Domain(); + domain.setDomainId(gateway.getGatewayId()); + domain.setName(gateway.getGatewayName()); + domain.setDescription("Domain entry for " + domain.getName()); + sharingHandler.createDomain(domain); + + // Creating Entity Types for each domain + EntityType entityType = new EntityType(); + entityType.setEntityTypeId(domain.getDomainId() + ":PROJECT"); + entityType.setDomainId(domain.getDomainId()); + entityType.setName("PROJECT"); + entityType.setDescription("Project entity type"); + sharingHandler.createEntityType(entityType); + + entityType = new EntityType(); + entityType.setEntityTypeId(domain.getDomainId() + ":EXPERIMENT"); + entityType.setDomainId(domain.getDomainId()); + entityType.setName("EXPERIMENT"); + entityType.setDescription("Experiment entity type"); + sharingHandler.createEntityType(entityType); + + entityType = new EntityType(); + entityType.setEntityTypeId(domain.getDomainId() + ":FILE"); + entityType.setDomainId(domain.getDomainId()); + entityType.setName("FILE"); + entityType.setDescription("File entity type"); + sharingHandler.createEntityType(entityType); + + entityType = new EntityType(); + entityType.setEntityTypeId(domain.getDomainId() + ":" + ResourceType.APPLICATION_DEPLOYMENT.name()); + entityType.setDomainId(domain.getDomainId()); + entityType.setName("APPLICATION-DEPLOYMENT"); + entityType.setDescription("Application Deployment entity type"); + sharingHandler.createEntityType(entityType); + + entityType = new EntityType(); + entityType.setEntityTypeId(domain.getDomainId() + ":" + ResourceType.GROUP_RESOURCE_PROFILE.name()); + entityType.setDomainId(domain.getDomainId()); + entityType.setName(ResourceType.GROUP_RESOURCE_PROFILE.name()); + entityType.setDescription("Group Resource Profile entity type"); + sharingHandler.createEntityType(entityType); + + // Creating Permission Types for each domain + PermissionType permissionType = new PermissionType(); + permissionType.setPermissionTypeId(domain.getDomainId() + ":READ"); + permissionType.setDomainId(domain.getDomainId()); + permissionType.setName("READ"); + permissionType.setDescription("Read permission type"); + sharingHandler.createPermissionType(permissionType); + + permissionType = new PermissionType(); + permissionType.setPermissionTypeId(domain.getDomainId() + ":WRITE"); + permissionType.setDomainId(domain.getDomainId()); + permissionType.setName("WRITE"); + permissionType.setDescription("Write permission type"); + sharingHandler.createPermissionType(permissionType); + + permissionType = new PermissionType(); + permissionType.setPermissionTypeId(domain.getDomainId() + ":MANAGE_SHARING"); + permissionType.setDomainId(domain.getDomainId()); + permissionType.setName("MANAGE_SHARING"); + permissionType.setDescription("Sharing permission type"); + sharingHandler.createPermissionType(permissionType); + } + + logger.debug("Airavata successfully created the gateway with {}", gatewayId); + return gatewayId; + } catch (Exception e) { + throw new ServiceException("Error while adding gateway: " + e.getMessage(), e); + } + } + + public List<String> getAllUsersInGateway(RequestContext ctx, String gatewayId) throws ServiceException { + try { + return registryHandler.getAllUsersInGateway(gatewayId); + } catch (Exception e) { + throw new ServiceException("Error while retrieving users: " + e.getMessage(), e); + } + } + + public boolean updateGateway(RequestContext ctx, String gatewayId, Gateway updatedGateway) throws ServiceException { + try { + return registryHandler.updateGateway(gatewayId, updatedGateway); + } catch (Exception e) { + throw new ServiceException("Error while updating the gateway: " + e.getMessage(), e); + } + } + + public Gateway getGateway(RequestContext ctx, String gatewayId) throws ServiceException { + try { + Gateway result = registryHandler.getGateway(gatewayId); + logger.debug("Airavata found the gateway with {}", gatewayId); + return result; + } catch (Exception e) { + throw new ServiceException("Error while getting the gateway: " + e.getMessage(), e); + } + } + + public boolean deleteGateway(RequestContext ctx, String gatewayId) throws ServiceException { + try { + return registryHandler.deleteGateway(gatewayId); + } catch (Exception e) { + throw new ServiceException("Error while deleting the gateway: " + e.getMessage(), e); + } + } + + public List<Gateway> getAllGateways(RequestContext ctx) throws ServiceException { + try { + logger.debug("Airavata searching for all gateways"); + return registryHandler.getAllGateways(); + } catch (Exception e) { + throw new ServiceException("Error while getting all the gateways: " + e.getMessage(), e); + } + } + + public boolean isGatewayExist(RequestContext ctx, String gatewayId) throws ServiceException { + try { + logger.debug("Airavata verifying if the gateway with {} exists", gatewayId); + return registryHandler.isGatewayExist(gatewayId); + } catch (Exception e) { + throw new ServiceException("Error while getting gateway: " + e.getMessage(), e); + } + } + + private boolean isSharingEnabled() { + try { + return ServerSettings.isEnableSharing(); + } catch (Exception e) { + return false; + } + } +} diff --git a/airavata-api/src/main/java/org/apache/airavata/service/notification/NotificationService.java b/airavata-api/src/main/java/org/apache/airavata/service/notification/NotificationService.java new file mode 100644 index 0000000000..62693f54fe --- /dev/null +++ b/airavata-api/src/main/java/org/apache/airavata/service/notification/NotificationService.java @@ -0,0 +1,63 @@ +package org.apache.airavata.service.notification; + +import org.apache.airavata.model.workspace.Notification; +import org.apache.airavata.registry.api.service.handler.RegistryServerHandler; +import org.apache.airavata.service.context.RequestContext; +import org.apache.airavata.service.exception.ServiceException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +public class NotificationService { + + private static final Logger logger = LoggerFactory.getLogger(NotificationService.class); + + private final RegistryServerHandler registryHandler; + + public NotificationService(RegistryServerHandler registryHandler) { + this.registryHandler = registryHandler; + } + + public String createNotification(RequestContext ctx, Notification notification) throws ServiceException { + try { + return registryHandler.createNotification(notification); + } catch (Exception e) { + throw new ServiceException("Error while creating notification: " + e.getMessage(), e); + } + } + + public boolean updateNotification(RequestContext ctx, Notification notification) throws ServiceException { + try { + return registryHandler.updateNotification(notification); + } catch (Exception e) { + throw new ServiceException("Error while updating notification: " + e.getMessage(), e); + } + } + + public boolean deleteNotification(RequestContext ctx, String gatewayId, String notificationId) + throws ServiceException { + try { + return registryHandler.deleteNotification(gatewayId, notificationId); + } catch (Exception e) { + throw new ServiceException("Error while deleting notification: " + e.getMessage(), e); + } + } + + public Notification getNotification(RequestContext ctx, String gatewayId, String notificationId) + throws ServiceException { + try { + return registryHandler.getNotification(gatewayId, notificationId); + } catch (Exception e) { + throw new ServiceException("Error while retrieving notification: " + e.getMessage(), e); + } + } + + public List<Notification> getAllNotifications(RequestContext ctx, String gatewayId) throws ServiceException { + try { + return registryHandler.getAllNotifications(gatewayId); + } catch (Exception e) { + throw new ServiceException("Error while getting all notifications: " + e.getMessage(), e); + } + } +} diff --git a/airavata-api/src/test/java/org/apache/airavata/service/gateway/GatewayServiceTest.java b/airavata-api/src/test/java/org/apache/airavata/service/gateway/GatewayServiceTest.java new file mode 100644 index 0000000000..4e3016bae6 --- /dev/null +++ b/airavata-api/src/test/java/org/apache/airavata/service/gateway/GatewayServiceTest.java @@ -0,0 +1,122 @@ +package org.apache.airavata.service.gateway; + +import org.apache.airavata.model.workspace.Gateway; +import org.apache.airavata.registry.api.service.handler.RegistryServerHandler; +import org.apache.airavata.service.context.RequestContext; +import org.apache.airavata.sharing.registry.server.SharingRegistryServerHandler; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +class GatewayServiceTest { + + @Mock RegistryServerHandler registryHandler; + @Mock SharingRegistryServerHandler sharingHandler; + + GatewayService gatewayService; + RequestContext ctx; + + @BeforeEach + void setUp() { + gatewayService = new GatewayService(registryHandler, sharingHandler); + ctx = new RequestContext("testUser", "testGateway", "token123", + Map.of("userName", "testUser", "gatewayId", "testGateway")); + } + + @Test + void addGateway_returnsGatewayId() throws Exception { + Gateway gateway = new Gateway(); + gateway.setGatewayId("gw-1"); + gateway.setGatewayName("Test Gateway"); + + when(registryHandler.addGateway(gateway)).thenReturn("gw-1"); + + // isSharingEnabled() will return false (ServerSettings not configured in test) + String result = gatewayService.addGateway(ctx, gateway); + + assertEquals("gw-1", result); + verify(registryHandler).addGateway(gateway); + } + + @Test + void getGateway_delegatesToRegistry() throws Exception { + Gateway gateway = new Gateway(); + gateway.setGatewayId("gw-1"); + gateway.setGatewayName("Test Gateway"); + + when(registryHandler.getGateway("gw-1")).thenReturn(gateway); + + Gateway result = gatewayService.getGateway(ctx, "gw-1"); + + assertNotNull(result); + assertEquals("gw-1", result.getGatewayId()); + verify(registryHandler).getGateway("gw-1"); + } + + @Test + void getAllGateways_delegatesToRegistry() throws Exception { + Gateway g1 = new Gateway(); + g1.setGatewayId("gw-1"); + Gateway g2 = new Gateway(); + g2.setGatewayId("gw-2"); + + when(registryHandler.getAllGateways()).thenReturn(List.of(g1, g2)); + + List<Gateway> result = gatewayService.getAllGateways(ctx); + + assertEquals(2, result.size()); + verify(registryHandler).getAllGateways(); + } + + @Test + void updateGateway_delegatesToRegistry() throws Exception { + Gateway updatedGateway = new Gateway(); + updatedGateway.setGatewayId("gw-1"); + + when(registryHandler.updateGateway("gw-1", updatedGateway)).thenReturn(true); + + boolean result = gatewayService.updateGateway(ctx, "gw-1", updatedGateway); + + assertTrue(result); + verify(registryHandler).updateGateway("gw-1", updatedGateway); + } + + @Test + void deleteGateway_delegatesToRegistry() throws Exception { + when(registryHandler.deleteGateway("gw-1")).thenReturn(true); + + boolean result = gatewayService.deleteGateway(ctx, "gw-1"); + + assertTrue(result); + verify(registryHandler).deleteGateway("gw-1"); + } + + @Test + void isGatewayExist_delegatesToRegistry() throws Exception { + when(registryHandler.isGatewayExist("gw-1")).thenReturn(true); + + boolean result = gatewayService.isGatewayExist(ctx, "gw-1"); + + assertTrue(result); + verify(registryHandler).isGatewayExist("gw-1"); + } + + @Test + void getAllUsersInGateway_delegatesToRegistry() throws Exception { + when(registryHandler.getAllUsersInGateway("gw-1")).thenReturn(List.of("user1", "user2")); + + List<String> result = gatewayService.getAllUsersInGateway(ctx, "gw-1"); + + assertEquals(2, result.size()); + verify(registryHandler).getAllUsersInGateway("gw-1"); + } +} diff --git a/airavata-api/src/test/java/org/apache/airavata/service/notification/NotificationServiceTest.java b/airavata-api/src/test/java/org/apache/airavata/service/notification/NotificationServiceTest.java new file mode 100644 index 0000000000..6440c26e5c --- /dev/null +++ b/airavata-api/src/test/java/org/apache/airavata/service/notification/NotificationServiceTest.java @@ -0,0 +1,98 @@ +package org.apache.airavata.service.notification; + +import org.apache.airavata.model.workspace.Notification; +import org.apache.airavata.registry.api.service.handler.RegistryServerHandler; +import org.apache.airavata.service.context.RequestContext; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +class NotificationServiceTest { + + @Mock RegistryServerHandler registryHandler; + + NotificationService notificationService; + RequestContext ctx; + + @BeforeEach + void setUp() { + notificationService = new NotificationService(registryHandler); + ctx = new RequestContext("testUser", "testGateway", "token123", + Map.of("userName", "testUser", "gatewayId", "testGateway")); + } + + @Test + void createNotification_delegatesToRegistry() throws Exception { + Notification notification = new Notification(); + notification.setGatewayId("testGateway"); + + when(registryHandler.createNotification(notification)).thenReturn("notif-1"); + + String result = notificationService.createNotification(ctx, notification); + + assertEquals("notif-1", result); + verify(registryHandler).createNotification(notification); + } + + @Test + void getNotification_delegatesToRegistry() throws Exception { + Notification notification = new Notification(); + notification.setNotificationId("notif-1"); + notification.setGatewayId("testGateway"); + + when(registryHandler.getNotification("testGateway", "notif-1")).thenReturn(notification); + + Notification result = notificationService.getNotification(ctx, "testGateway", "notif-1"); + + assertNotNull(result); + assertEquals("notif-1", result.getNotificationId()); + verify(registryHandler).getNotification("testGateway", "notif-1"); + } + + @Test + void deleteNotification_delegatesToRegistry() throws Exception { + when(registryHandler.deleteNotification("testGateway", "notif-1")).thenReturn(true); + + boolean result = notificationService.deleteNotification(ctx, "testGateway", "notif-1"); + + assertTrue(result); + verify(registryHandler).deleteNotification("testGateway", "notif-1"); + } + + @Test + void updateNotification_delegatesToRegistry() throws Exception { + Notification notification = new Notification(); + notification.setNotificationId("notif-1"); + + when(registryHandler.updateNotification(notification)).thenReturn(true); + + boolean result = notificationService.updateNotification(ctx, notification); + + assertTrue(result); + verify(registryHandler).updateNotification(notification); + } + + @Test + void getAllNotifications_delegatesToRegistry() throws Exception { + Notification n1 = new Notification(); + n1.setNotificationId("notif-1"); + Notification n2 = new Notification(); + n2.setNotificationId("notif-2"); + + when(registryHandler.getAllNotifications("testGateway")).thenReturn(List.of(n1, n2)); + + List<Notification> result = notificationService.getAllNotifications(ctx, "testGateway"); + + assertEquals(2, result.size()); + verify(registryHandler).getAllNotifications("testGateway"); + } +}
