You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by ma...@apache.org on 2018/05/23 20:49:01 UTC

[airavata] 02/02: AIRAVATA-2787 GatewayGroupsInitializer

This is an automated email from the ASF dual-hosted git repository.

machristie pushed a commit to branch group-based-auth
in repository https://gitbox.apache.org/repos/asf/airavata.git

commit 692d57144a867ff71b259c9c52998b0c1bab73c1
Author: Marcus Christie <ma...@apache.org>
AuthorDate: Wed May 23 16:48:24 2018 -0400

    AIRAVATA-2787 GatewayGroupsInitializer
---
 airavata-api/airavata-api-server/pom.xml           |   6 +
 .../api/server/handler/AiravataServerHandler.java  |   7 +-
 .../api/server/util/GatewayGroupsInitializer.java  | 168 +++++++++++++++++++++
 .../server/util/GatewayGroupsInitializerTest.java  | 125 +++++++++++++++
 .../messaging/SharingServiceDBEventHandler.java    |  21 ++-
 5 files changed, 315 insertions(+), 12 deletions(-)

diff --git a/airavata-api/airavata-api-server/pom.xml b/airavata-api/airavata-api-server/pom.xml
index 0e96478..35fe98a 100644
--- a/airavata-api/airavata-api-server/pom.xml
+++ b/airavata-api/airavata-api-server/pom.xml
@@ -168,6 +168,12 @@
             <artifactId>profile-service-stubs</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.jmockit</groupId>
+            <artifactId>jmockit</artifactId>
+            <version>1.39</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
 </project>
diff --git a/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/handler/AiravataServerHandler.java b/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/handler/AiravataServerHandler.java
index 5d0d062..ae84664 100644
--- a/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/handler/AiravataServerHandler.java
+++ b/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/handler/AiravataServerHandler.java
@@ -25,6 +25,7 @@ import org.apache.airavata.accountprovisioning.SSHAccountProvisionerFactory;
 import org.apache.airavata.accountprovisioning.SSHAccountProvisionerProvider;
 import org.apache.airavata.api.Airavata;
 import org.apache.airavata.api.airavata_apiConstants;
+import org.apache.airavata.api.server.util.GatewayGroupsInitializer;
 import org.apache.airavata.common.exception.AiravataException;
 import org.apache.airavata.common.exception.ApplicationSettingsException;
 import org.apache.airavata.common.utils.AiravataUtils;
@@ -5656,6 +5657,10 @@ public class AiravataServerHandler implements Airavata.Iface {
 
     private GatewayGroups retrieveGatewayGroups(RegistryService.Client regClient, String gatewayId) throws TException {
 
-        return regClient.getGatewayGroups(gatewayId);
+        if (regClient.isGatewayGroupsExists(gatewayId)) {
+            return regClient.getGatewayGroups(gatewayId);
+        } else {
+            return GatewayGroupsInitializer.initializeGatewayGroups(gatewayId);
+        }
     }
 }
\ No newline at end of file
diff --git a/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/util/GatewayGroupsInitializer.java b/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/util/GatewayGroupsInitializer.java
new file mode 100644
index 0000000..30eb2a8
--- /dev/null
+++ b/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/util/GatewayGroupsInitializer.java
@@ -0,0 +1,168 @@
+/*
+ * 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.api.server.util;
+
+import org.apache.airavata.common.exception.ApplicationSettingsException;
+import org.apache.airavata.common.utils.AiravataUtils;
+import org.apache.airavata.common.utils.ServerSettings;
+import org.apache.airavata.common.utils.ThriftUtils;
+import org.apache.airavata.credential.store.client.CredentialStoreClientFactory;
+import org.apache.airavata.credential.store.cpi.CredentialStoreService;
+import org.apache.airavata.credential.store.exception.CredentialStoreException;
+import org.apache.airavata.model.appcatalog.gatewaygroups.GatewayGroups;
+import org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile;
+import org.apache.airavata.model.credential.store.PasswordCredential;
+import org.apache.airavata.registry.api.RegistryService;
+import org.apache.airavata.registry.api.client.RegistryServiceClientFactory;
+import org.apache.airavata.registry.api.exception.RegistryServiceException;
+import org.apache.airavata.sharing.registry.client.SharingRegistryServiceClientFactory;
+import org.apache.airavata.sharing.registry.models.*;
+import org.apache.airavata.sharing.registry.service.cpi.SharingRegistryService;
+import org.apache.thrift.TException;
+
+/**
+ * Create and save an initial set of user management groups for a gateway.
+ */
+public class GatewayGroupsInitializer {
+
+    public static GatewayGroups initializeGatewayGroups(String gatewayId) {
+
+        SharingRegistryService.Client sharingRegistryClient = createSharingRegistryClient();
+        RegistryService.Client registryClient = createRegistryClient();
+        CredentialStoreService.Client credentialStoreClient = createCredentialStoreClient();
+        try {
+            GatewayGroupsInitializer gatewayGroupsInitializer = new GatewayGroupsInitializer(registryClient, sharingRegistryClient, credentialStoreClient);
+            return gatewayGroupsInitializer.initialize(gatewayId);
+        } catch (Exception e) {
+            throw new RuntimeException("Failed to initialize a GatewayGroups instance for gateway: " + gatewayId, e);
+        } finally {
+            ThriftUtils.close(sharingRegistryClient);
+            ThriftUtils.close(registryClient);
+            ThriftUtils.close(credentialStoreClient);
+        }
+    }
+
+    private RegistryService.Client registryClient;
+    private SharingRegistryService.Client sharingRegistryClient;
+    private CredentialStoreService.Client credentialStoreClient;
+
+    public GatewayGroupsInitializer(RegistryService.Client registryClient, SharingRegistryService.Client sharingRegistryClient, CredentialStoreService.Client credentialStoreClient) {
+
+        this.registryClient = registryClient;
+        this.sharingRegistryClient = sharingRegistryClient;
+        this.credentialStoreClient = credentialStoreClient;
+    }
+
+    public GatewayGroups initialize(String gatewayId) throws TException {
+
+        GatewayGroups gatewayGroups = new GatewayGroups();
+        gatewayGroups.setGatewayId(gatewayId);
+
+        String adminOwnerUsername = getAdminOwnerUsername(registryClient, credentialStoreClient, gatewayId);
+        String ownerId = adminOwnerUsername + "@" + gatewayId;
+        if (!sharingRegistryClient.isUserExists(gatewayId, ownerId)) {
+            User adminUser = new User();
+            adminUser.setUserId(ownerId);
+            adminUser.setDomainId(gatewayId);
+            adminUser.setCreatedTime(System.currentTimeMillis());
+            adminUser.setUpdatedTime(System.currentTimeMillis());
+            adminUser.setUserName(adminOwnerUsername);
+            sharingRegistryClient.createUser(adminUser);
+        }
+
+        // Gateway Users
+        UserGroup gatewayUsersGroup = createGroup(sharingRegistryClient, gatewayId, ownerId,
+                "Gateway Users",
+                "Default group for users of the gateway.");
+        gatewayGroups.setDefaultGatewayUsersGroupId(gatewayUsersGroup.groupId);
+        // Admin Users
+        UserGroup adminUsersGroup = createGroup(sharingRegistryClient, gatewayId, ownerId,
+                "Admin Users",
+                "Admin users group.");
+        gatewayGroups.setAdminsGroupId(adminUsersGroup.groupId);
+        // Read Only Admin Users
+        UserGroup readOnlyAdminsGroup = createGroup(sharingRegistryClient, gatewayId, ownerId,
+                "Read Only Admin Users",
+                "Group of admin users with read-only access.");
+        gatewayGroups.setReadOnlyAdminsGroupId(readOnlyAdminsGroup.groupId);
+
+        registryClient.createGatewayGroups(gatewayGroups);
+
+        return gatewayGroups;
+    }
+
+
+    private UserGroup createGroup(SharingRegistryService.Client sharingRegistryClient, String gatewayId, String ownerId, String groupName, String groupDescription) throws TException {
+
+        UserGroup userGroup = new UserGroup();
+        userGroup.setGroupId(AiravataUtils.getId(groupName));
+        userGroup.setDomainId(gatewayId);
+        userGroup.setGroupCardinality(GroupCardinality.MULTI_USER);
+        userGroup.setCreatedTime(System.currentTimeMillis());
+        userGroup.setUpdatedTime(System.currentTimeMillis());
+        userGroup.setName(groupName);
+        userGroup.setDescription(groupDescription);
+        userGroup.setOwnerId(ownerId);
+        userGroup.setGroupType(GroupType.DOMAIN_LEVEL_GROUP);
+        sharingRegistryClient.createGroup(userGroup);
+
+        return userGroup;
+    }
+
+    private String getAdminOwnerUsername(RegistryService.Client registryClient, CredentialStoreService.Client credentialStoreClient, String gatewayId) throws TException {
+
+        GatewayResourceProfile gatewayResourceProfile = registryClient.getGatewayResourceProfile(gatewayId);
+        PasswordCredential credential = credentialStoreClient.getPasswordCredential(
+                    gatewayResourceProfile.getIdentityServerPwdCredToken(), gatewayResourceProfile.getGatewayID());
+        String adminUsername = credential.getLoginUserName();
+        return adminUsername;
+    }
+
+    private static SharingRegistryService.Client createSharingRegistryClient() {
+        final int serverPort = Integer.parseInt(ServerSettings.getSharingRegistryPort());
+        final String serverHost = ServerSettings.getSharingRegistryHost();
+        try {
+            return SharingRegistryServiceClientFactory.createSharingRegistryClient(serverHost, serverPort);
+        } catch (SharingRegistryException e) {
+            throw new RuntimeException("Unable to create sharing registry client...", e);
+        }
+    }
+
+    private static RegistryService.Client createRegistryClient() {
+        try {
+            final int serverPort = Integer.parseInt(ServerSettings.getRegistryServerPort());
+            final String serverHost = ServerSettings.getRegistryServerHost();
+            return RegistryServiceClientFactory.createRegistryClient(serverHost, serverPort);
+        } catch (ApplicationSettingsException|RegistryServiceException e) {
+            throw new RuntimeException("Unable to create registry client...", e);
+        }
+    }
+
+    private static CredentialStoreService.Client createCredentialStoreClient() {
+        try {
+            final int serverPort = Integer.parseInt(ServerSettings.getCredentialStoreServerPort());
+            final String serverHost = ServerSettings.getCredentialStoreServerHost();
+            return CredentialStoreClientFactory.createAiravataCSClient(serverHost, serverPort);
+        } catch (ApplicationSettingsException|CredentialStoreException e) {
+            throw new RuntimeException("Unable to create credential store client...", e);
+        }
+    }
+}
diff --git a/airavata-api/airavata-api-server/src/test/java/org/apache/airavata/api/server/util/GatewayGroupsInitializerTest.java b/airavata-api/airavata-api-server/src/test/java/org/apache/airavata/api/server/util/GatewayGroupsInitializerTest.java
new file mode 100644
index 0000000..133ef79
--- /dev/null
+++ b/airavata-api/airavata-api-server/src/test/java/org/apache/airavata/api/server/util/GatewayGroupsInitializerTest.java
@@ -0,0 +1,125 @@
+/*
+ * 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.api.server.util;
+
+import mockit.Expectations;
+import mockit.Mocked;
+import mockit.Verifications;
+import mockit.integration.junit4.JMockit;
+import org.apache.airavata.credential.store.cpi.CredentialStoreService;
+import org.apache.airavata.model.appcatalog.gatewaygroups.GatewayGroups;
+import org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile;
+import org.apache.airavata.model.credential.store.PasswordCredential;
+import org.apache.airavata.registry.api.RegistryService;
+import org.apache.airavata.sharing.registry.models.GroupCardinality;
+import org.apache.airavata.sharing.registry.models.User;
+import org.apache.airavata.sharing.registry.models.UserGroup;
+import org.apache.airavata.sharing.registry.service.cpi.SharingRegistryService;
+import org.apache.thrift.TException;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(JMockit.class)
+public class GatewayGroupsInitializerTest {
+    public static final String GATEWAY_ID = "test-gateway";
+    public static final String IDENTITY_SERVER_PWD_CRED_TOKEN = "identity-server-pwd-cred-token";
+    public static final String TEST_ADMIN_USERNAME = "test-admin-username";
+    public static final String ADMIN_OWNER_ID = TEST_ADMIN_USERNAME + "@" + GATEWAY_ID;
+    @Mocked
+    RegistryService.Client mockRegistryClient;
+    @Mocked
+    SharingRegistryService.Client mockSharingRegistryClient;
+    @Mocked
+    CredentialStoreService.Client mockCredentialStoreClient;
+
+    GatewayGroupsInitializer gatewayGroupsInitializer;
+
+    @Before
+    public void setUp() {
+
+        gatewayGroupsInitializer = new GatewayGroupsInitializer(mockRegistryClient, mockSharingRegistryClient, mockCredentialStoreClient);
+    }
+
+    @Test
+    public void testWithoutAdminUser() throws TException {
+        runTest(false);
+    }
+
+    @Test
+    public void testWithAdminUser() throws TException {
+        runTest(true);
+    }
+
+    private void runTest(boolean doesAdminUserExist) throws TException {
+        GatewayResourceProfile gatewayResourceProfile = new GatewayResourceProfile();
+        gatewayResourceProfile.setGatewayID(GATEWAY_ID);
+        gatewayResourceProfile.setIdentityServerPwdCredToken(IDENTITY_SERVER_PWD_CRED_TOKEN);
+
+        PasswordCredential passwordCredential = new PasswordCredential();
+        passwordCredential.setLoginUserName(TEST_ADMIN_USERNAME);
+        passwordCredential.setGatewayId(GATEWAY_ID);
+        passwordCredential.setToken(IDENTITY_SERVER_PWD_CRED_TOKEN);
+
+        new Expectations() {{
+            mockRegistryClient.getGatewayResourceProfile(GATEWAY_ID); result = gatewayResourceProfile;
+            mockCredentialStoreClient.getPasswordCredential(IDENTITY_SERVER_PWD_CRED_TOKEN, GATEWAY_ID); result = passwordCredential;
+            mockSharingRegistryClient.isUserExists(GATEWAY_ID, ADMIN_OWNER_ID); result = doesAdminUserExist;
+        }};
+
+        GatewayGroups gatewayGroups = gatewayGroupsInitializer.initialize(GATEWAY_ID);
+        Assert.assertEquals(GATEWAY_ID, gatewayGroups.getGatewayId());
+
+        new Verifications() {{
+            User adminUser;
+
+            if (!doesAdminUserExist) {
+                mockSharingRegistryClient.createUser(adminUser = withCapture());
+                Assert.assertEquals(adminUser.getUserId(), ADMIN_OWNER_ID);
+                Assert.assertEquals(adminUser.getUserName(), TEST_ADMIN_USERNAME);
+                Assert.assertEquals(adminUser.getDomainId(), GATEWAY_ID);
+            }
+
+            List<UserGroup> groups = new ArrayList<>();
+            mockSharingRegistryClient.createGroup(withCapture(groups));
+            Assert.assertEquals(3, groups.size());
+            groups.forEach(group -> {
+                Assert.assertEquals(GATEWAY_ID, group.getDomainId());
+                Assert.assertEquals(ADMIN_OWNER_ID, group.getOwnerId());
+                Assert.assertEquals(GroupCardinality.MULTI_USER, group.getGroupCardinality());
+            });
+            groups.forEach(group -> Assert.assertEquals(GATEWAY_ID, group.getDomainId()));
+            UserGroup gatewayUsersGroup = groups.get(0);
+            UserGroup adminsGroup = groups.get(1);
+            UserGroup readOnlyAdminsGroup = groups.get(2);
+            Assert.assertEquals("Gateway Users", gatewayUsersGroup.getName());
+            Assert.assertEquals(gatewayGroups.getDefaultGatewayUsersGroupId(), gatewayUsersGroup.getGroupId());
+            Assert.assertEquals("Admin Users", adminsGroup.getName());
+            Assert.assertEquals(gatewayGroups.getAdminsGroupId(), adminsGroup.getGroupId());
+            Assert.assertEquals("Read Only Admin Users", readOnlyAdminsGroup.getName());
+            Assert.assertEquals(gatewayGroups.getReadOnlyAdminsGroupId(), readOnlyAdminsGroup.getGroupId());
+        }};
+    }
+}
diff --git a/modules/sharing-registry/sharing-registry-server/src/main/java/org/apache/airavata/sharing/registry/messaging/SharingServiceDBEventHandler.java b/modules/sharing-registry/sharing-registry-server/src/main/java/org/apache/airavata/sharing/registry/messaging/SharingServiceDBEventHandler.java
index 61dfe4e..f90dc86 100644
--- a/modules/sharing-registry/sharing-registry-server/src/main/java/org/apache/airavata/sharing/registry/messaging/SharingServiceDBEventHandler.java
+++ b/modules/sharing-registry/sharing-registry-server/src/main/java/org/apache/airavata/sharing/registry/messaging/SharingServiceDBEventHandler.java
@@ -90,10 +90,17 @@ public class SharingServiceDBEventHandler implements MessageHandler {
                         switch (dBEventMessageContext.getPublisher().getPublisherContext().getCrudType()){
 
                             case CREATE:
-                                log.info("Creating user. User Id : " + user.getUserId());
+                            case UPDATE:
 
-                                sharingRegistryClient.createUser(user);
-                                log.debug("User created. User Id : " + user.getUserId());
+                                if (!sharingRegistryClient.isUserExists(user.getDomainId(), user.getUserId())) {
+                                    log.info("Creating user. User Id : " + user.getUserId());
+                                    sharingRegistryClient.createUser(user);
+                                    log.debug("User created. User Id : " + user.getUserId());
+                                } else {
+                                    log.info("Updating user. User Id : " + user.getUserId());
+                                    sharingRegistryClient.updatedUser(user);
+                                    log.debug("User updated. User Id : " + user.getUserId());
+                                }
 
                                 break;
 
@@ -101,14 +108,6 @@ public class SharingServiceDBEventHandler implements MessageHandler {
                                 //FIXME: Remove if not required
                                 break;
 
-                            case UPDATE:
-                                log.info("Updating user. User Id : " + user.getUserId());
-
-                                sharingRegistryClient.updatedUser(user);
-                                log.debug("User updated. User Id : " + user.getUserId());
-
-                                break;
-
                             case DELETE:
                                 log.info("Deleting user. User Id : " + user.getUserId());
 

-- 
To stop receiving notification emails like this one, please contact
machristie@apache.org.