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.