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 2017/06/12 16:24:44 UTC

airavata git commit: AIRAVATA-2408 Propogating user profile update to IAM server

Repository: airavata
Updated Branches:
  refs/heads/develop b3338ceb5 -> b1c390cb4


AIRAVATA-2408 Propogating user profile update to IAM server


Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/b1c390cb
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/b1c390cb
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/b1c390cb

Branch: refs/heads/develop
Commit: b1c390cb42c4f02a7a45231627e0d646fa7c23d5
Parents: b3338ce
Author: Marcus Christie <ma...@apache.org>
Authored: Mon Jun 12 12:24:09 2017 -0400
Committer: Marcus Christie <ma...@apache.org>
Committed: Mon Jun 12 12:24:09 2017 -0400

----------------------------------------------------------------------
 .../core/impl/TenantManagementKeycloakImpl.java |   39 +
 .../interfaces/TenantManagementInterface.java   |    8 +
 .../handlers/IamAdminServicesHandler.java       |   57 +-
 .../handlers/UserProfileServiceHandler.java     |   30 +-
 .../admin/services/cpi/IamAdminServices.java    | 1090 ++++++++++++++++++
 .../repositories/UserProfileRepository.java     |   15 +-
 .../iam-admin-services-cpi.thrift               |    4 +
 7 files changed, 1236 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/airavata/blob/b1c390cb/airavata-services/profile-service/iam-admin-services-core/src/main/java/org/apache/airavata/service/profile/iam/admin/services/core/impl/TenantManagementKeycloakImpl.java
----------------------------------------------------------------------
diff --git a/airavata-services/profile-service/iam-admin-services-core/src/main/java/org/apache/airavata/service/profile/iam/admin/services/core/impl/TenantManagementKeycloakImpl.java b/airavata-services/profile-service/iam-admin-services-core/src/main/java/org/apache/airavata/service/profile/iam/admin/services/core/impl/TenantManagementKeycloakImpl.java
index 22c3888..20b926c 100644
--- a/airavata-services/profile-service/iam-admin-services-core/src/main/java/org/apache/airavata/service/profile/iam/admin/services/core/impl/TenantManagementKeycloakImpl.java
+++ b/airavata-services/profile-service/iam-admin-services-core/src/main/java/org/apache/airavata/service/profile/iam/admin/services/core/impl/TenantManagementKeycloakImpl.java
@@ -405,4 +405,43 @@ public class TenantManagementKeycloakImpl implements TenantManagementInterface {
             throw exception;
         }
     }
+
+    @Override
+    public void updateUserProfile(PasswordCredential realmAdminCreds, String gatewayId, String username, UserProfile userDetails) throws IamAdminServicesException {
+
+        Keycloak client = null;
+        try{
+            client = TenantManagementKeycloakImpl.getClient(ServerSettings.getIamServerUrl(), gatewayId, realmAdminCreds);
+            List<UserRepresentation> retrieveUserList = client.realm(gatewayId).users().search(username,
+                    null,
+                    null,
+                    null,
+                    0, 1);
+            if(!retrieveUserList.isEmpty())
+            {
+                UserRepresentation userRepresentation = retrieveUserList.get(0);
+                userRepresentation.setFirstName(userDetails.getFirstName());
+                userRepresentation.setLastName(userDetails.getLastName());
+                userRepresentation.setEmail(userDetails.getEmails().get(0));
+                UserResource userResource = client.realm(gatewayId).users().get(userRepresentation.getId());
+                userResource.update(userRepresentation);
+            }else{
+                throw new IamAdminServicesException("User [" + username + "] wasn't found in Keycloak!");
+            }
+        } catch (ApplicationSettingsException ex) {
+            logger.error("Error getting values from property file, reason: " + ex.getMessage(), ex);
+            IamAdminServicesException exception = new IamAdminServicesException();
+            exception.setMessage("Error getting values from property file, reason " + ex.getMessage());
+            throw exception;
+        } catch (Exception ex){
+            logger.error("Error updating user profile in keycloak server, reason: " + ex.getMessage(), ex);
+            IamAdminServicesException exception = new IamAdminServicesException();
+            exception.setMessage("Error updating user profile in keycloak server, reason: " + ex.getMessage());
+            throw exception;
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/airavata/blob/b1c390cb/airavata-services/profile-service/iam-admin-services-core/src/main/java/org/apache/airavata/service/profile/iam/admin/services/core/interfaces/TenantManagementInterface.java
----------------------------------------------------------------------
diff --git a/airavata-services/profile-service/iam-admin-services-core/src/main/java/org/apache/airavata/service/profile/iam/admin/services/core/interfaces/TenantManagementInterface.java b/airavata-services/profile-service/iam-admin-services-core/src/main/java/org/apache/airavata/service/profile/iam/admin/services/core/interfaces/TenantManagementInterface.java
index a7b61f3..b413eb0 100644
--- a/airavata-services/profile-service/iam-admin-services-core/src/main/java/org/apache/airavata/service/profile/iam/admin/services/core/interfaces/TenantManagementInterface.java
+++ b/airavata-services/profile-service/iam-admin-services-core/src/main/java/org/apache/airavata/service/profile/iam/admin/services/core/interfaces/TenantManagementInterface.java
@@ -98,4 +98,12 @@ public interface TenantManagementInterface {
      */
     List<UserProfile> findUser(PasswordCredential realmAdminCreds, String gatewayID, String email, String userName) throws IamAdminServicesException;
 
+    /**
+     * Update the user's profile in the Identity Server
+     * @param realmAdminCreds
+     * @param gatewayId
+     * @param username
+     * @param userDetails
+     */
+    void updateUserProfile(PasswordCredential realmAdminCreds, String gatewayId, String username, UserProfile userDetails) throws IamAdminServicesException;
 }

http://git-wip-us.apache.org/repos/asf/airavata/blob/b1c390cb/airavata-services/profile-service/profile-service-server/src/main/java/org/apache/airavata/service/profile/handlers/IamAdminServicesHandler.java
----------------------------------------------------------------------
diff --git a/airavata-services/profile-service/profile-service-server/src/main/java/org/apache/airavata/service/profile/handlers/IamAdminServicesHandler.java b/airavata-services/profile-service/profile-service-server/src/main/java/org/apache/airavata/service/profile/handlers/IamAdminServicesHandler.java
index 9f33cd5..4dd49c4 100644
--- a/airavata-services/profile-service/profile-service-server/src/main/java/org/apache/airavata/service/profile/handlers/IamAdminServicesHandler.java
+++ b/airavata-services/profile-service/profile-service-server/src/main/java/org/apache/airavata/service/profile/handlers/IamAdminServicesHandler.java
@@ -21,13 +21,21 @@
 
 package org.apache.airavata.service.profile.handlers;
 
+import org.apache.airavata.common.exception.ApplicationSettingsException;
+import org.apache.airavata.common.utils.Constants;
 import org.apache.airavata.common.utils.ServerSettings;
+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.gatewayprofile.GatewayResourceProfile;
 import org.apache.airavata.model.credential.store.PasswordCredential;
 import org.apache.airavata.model.error.AuthorizationException;
 import org.apache.airavata.model.security.AuthzToken;
 import org.apache.airavata.model.user.UserProfile;
 import org.apache.airavata.model.workspace.Gateway;
-import org.apache.airavata.security.util.TrustStoreManager;
+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.service.profile.iam.admin.services.core.impl.TenantManagementKeycloakImpl;
 import org.apache.airavata.service.profile.iam.admin.services.cpi.IamAdminServices;
 import org.apache.airavata.service.profile.iam.admin.services.cpi.exception.IamAdminServicesException;
@@ -37,10 +45,6 @@ import org.apache.thrift.TException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.URL;
 import java.util.List;
 
 public class IamAdminServicesHandler implements IamAdminServices.Iface {
@@ -134,4 +138,47 @@ public class IamAdminServicesHandler implements IamAdminServices.Iface {
             throw ex;
         }
     }
+
+    @Override
+    public void updateUserProfile(AuthzToken authzToken, UserProfile userDetails) throws IamAdminServicesException, AuthorizationException, TException {
+
+        TenantManagementKeycloakImpl keycloakclient = new TenantManagementKeycloakImpl();
+        try {
+            String username = authzToken.getClaimsMap().get(Constants.USER_NAME);
+            String gatewayId = authzToken.getClaimsMap().get(Constants.GATEWAY_ID);
+            if (gatewayId.equals(userDetails.getGatewayId())) {
+                throw new IamAdminServicesException("gatewayId in user profile doesn't match authorization token!");
+            }
+            if (username.equals(userDetails.getUserId())) {
+                throw new IamAdminServicesException("userId in user profile doesn't match authorization token!");
+            }
+            GatewayResourceProfile gwrp = getRegistryServiceClient().getGatewayResourceProfile(gatewayId);
+
+            CredentialStoreService.Client csClient = getCredentialStoreServiceClient();
+            PasswordCredential credential = csClient.getPasswordCredential(gwrp.getIdentityServerPwdCredToken(), gwrp.getGatewayID());
+            keycloakclient.updateUserProfile(credential, gatewayId, username, userDetails);
+        } catch (ApplicationSettingsException e) {
+            throw new IamAdminServicesException("Unable to create service clients. Reason: " + e.getMessage());
+        }
+    }
+
+    private RegistryService.Client getRegistryServiceClient() throws TException, ApplicationSettingsException {
+        final int serverPort = Integer.parseInt(ServerSettings.getRegistryServerPort());
+        final String serverHost = ServerSettings.getRegistryServerHost();
+        try {
+            return RegistryServiceClientFactory.createRegistryClient(serverHost, serverPort);
+        } catch (RegistryServiceException e) {
+            throw new TException("Unable to create registry client...", e);
+        }
+    }
+
+    private CredentialStoreService.Client getCredentialStoreServiceClient() throws TException, ApplicationSettingsException {
+        final int serverPort = Integer.parseInt(ServerSettings.getCredentialStoreServerPort());
+        final String serverHost = ServerSettings.getCredentialStoreServerHost();
+        try {
+            return CredentialStoreClientFactory.createAiravataCSClient(serverHost, serverPort);
+        } catch (CredentialStoreException e) {
+            throw new TException("Unable to create credential store client...", e);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/airavata/blob/b1c390cb/airavata-services/profile-service/profile-service-server/src/main/java/org/apache/airavata/service/profile/handlers/UserProfileServiceHandler.java
----------------------------------------------------------------------
diff --git a/airavata-services/profile-service/profile-service-server/src/main/java/org/apache/airavata/service/profile/handlers/UserProfileServiceHandler.java b/airavata-services/profile-service/profile-service-server/src/main/java/org/apache/airavata/service/profile/handlers/UserProfileServiceHandler.java
index 6ade73c..8e2e989 100644
--- a/airavata-services/profile-service/profile-service-server/src/main/java/org/apache/airavata/service/profile/handlers/UserProfileServiceHandler.java
+++ b/airavata-services/profile-service/profile-service-server/src/main/java/org/apache/airavata/service/profile/handlers/UserProfileServiceHandler.java
@@ -20,14 +20,19 @@
 */
 package org.apache.airavata.service.profile.handlers;
 
+import org.apache.airavata.common.exception.ApplicationSettingsException;
 import org.apache.airavata.common.utils.DBEventManagerConstants;
 import org.apache.airavata.common.utils.DBEventService;
+import org.apache.airavata.common.utils.ServerSettings;
 import org.apache.airavata.model.dbevent.CrudType;
 import org.apache.airavata.model.dbevent.EntityType;
 import org.apache.airavata.model.error.AuthorizationException;
 import org.apache.airavata.model.security.AuthzToken;
 import org.apache.airavata.model.user.UserProfile;
+import org.apache.airavata.service.profile.client.ProfileServiceClientFactory;
 import org.apache.airavata.service.profile.commons.user.entities.UserProfileEntity;
+import org.apache.airavata.service.profile.iam.admin.services.cpi.IamAdminServices;
+import org.apache.airavata.service.profile.iam.admin.services.cpi.exception.IamAdminServicesException;
 import org.apache.airavata.service.profile.user.core.repositories.UserProfileRepository;
 import org.apache.airavata.service.profile.user.cpi.UserProfileService;
 import org.apache.airavata.service.profile.user.cpi.exception.UserProfileServiceException;
@@ -79,7 +84,18 @@ public class UserProfileServiceHandler implements UserProfileService.Iface {
     @SecurityCheck
     public boolean updateUserProfile(AuthzToken authzToken, UserProfile userProfile) throws UserProfileServiceException, AuthorizationException, TException {
         try {
-            if(userProfileRepository.update(userProfile) != null) {
+            // After updating the user profile in the database but before committing the transaction, the
+            // following will update the user profile in the IAM service also. If the update in the IAM service
+            // fails then the transaction will be rolled back.
+            IamAdminServices.Client iamAdminServicesClient = getIamAdminServicesClient();
+            Runnable iamUserProfileUpdater = () -> {
+                try {
+                    iamAdminServicesClient.updateUserProfile(authzToken, userProfile);
+                } catch (TException e) {
+                    throw new RuntimeException("Failed to update user profile in IAM service", e);
+                }
+            };
+            if(userProfileRepository.updateUserProfile(userProfile, iamUserProfileUpdater) != null) {
                 logger.info("Updated UserProfile with userId: " + userProfile.getUserId());
                 // replicate userProfile at end-places
                 ProfileServiceUtils.getDbEventPublisher().publish(
@@ -170,4 +186,16 @@ public class UserProfileServiceHandler implements UserProfileService.Iface {
             throw exception;
         }
     }
+
+    private IamAdminServices.Client getIamAdminServicesClient() throws UserProfileServiceException {
+        try {
+            final int serverPort = Integer.parseInt(ServerSettings.getProfileServiceServerPort());
+            final String serverHost = ServerSettings.getProfileServiceServerHost();
+            return ProfileServiceClientFactory.createIamAdminServiceClient(serverHost, serverPort);
+        } catch (IamAdminServicesException|ApplicationSettingsException e) {
+            logger.error("Failed to create IAM Admin Services client", e);
+            UserProfileServiceException ex = new UserProfileServiceException("Failed to create IAM Admin Services client");
+            throw ex;
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/airavata/blob/b1c390cb/airavata-services/profile-service/profile-service-stubs/src/main/java/org/apache/airavata/service/profile/iam/admin/services/cpi/IamAdminServices.java
----------------------------------------------------------------------
diff --git a/airavata-services/profile-service/profile-service-stubs/src/main/java/org/apache/airavata/service/profile/iam/admin/services/cpi/IamAdminServices.java b/airavata-services/profile-service/profile-service-stubs/src/main/java/org/apache/airavata/service/profile/iam/admin/services/cpi/IamAdminServices.java
index ce4dc8f..bfdcd7e 100644
--- a/airavata-services/profile-service/profile-service-stubs/src/main/java/org/apache/airavata/service/profile/iam/admin/services/cpi/IamAdminServices.java
+++ b/airavata-services/profile-service/profile-service-stubs/src/main/java/org/apache/airavata/service/profile/iam/admin/services/cpi/IamAdminServices.java
@@ -67,6 +67,8 @@ public class IamAdminServices {
 
     public List<org.apache.airavata.model.user.UserProfile> findUsers(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String email, String userId, org.apache.airavata.model.credential.store.PasswordCredential isRealmAdminCredentials) throws org.apache.airavata.service.profile.iam.admin.services.cpi.exception.IamAdminServicesException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;
 
+    public void updateUserProfile(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.user.UserProfile userDetails) throws org.apache.airavata.service.profile.iam.admin.services.cpi.exception.IamAdminServicesException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;
+
   }
 
   public interface AsyncIface {
@@ -83,6 +85,8 @@ public class IamAdminServices {
 
     public void findUsers(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String email, String userId, org.apache.airavata.model.credential.store.PasswordCredential isRealmAdminCredentials, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
 
+    public void updateUserProfile(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.user.UserProfile userDetails, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+
   }
 
   public static class Client extends org.apache.thrift.TServiceClient implements Iface {
@@ -293,6 +297,33 @@ public class IamAdminServices {
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "findUsers failed: unknown result");
     }
 
+    public void updateUserProfile(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.user.UserProfile userDetails) throws org.apache.airavata.service.profile.iam.admin.services.cpi.exception.IamAdminServicesException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
+    {
+      send_updateUserProfile(authzToken, userDetails);
+      recv_updateUserProfile();
+    }
+
+    public void send_updateUserProfile(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.user.UserProfile userDetails) throws org.apache.thrift.TException
+    {
+      updateUserProfile_args args = new updateUserProfile_args();
+      args.setAuthzToken(authzToken);
+      args.setUserDetails(userDetails);
+      sendBase("updateUserProfile", args);
+    }
+
+    public void recv_updateUserProfile() throws org.apache.airavata.service.profile.iam.admin.services.cpi.exception.IamAdminServicesException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
+    {
+      updateUserProfile_result result = new updateUserProfile_result();
+      receiveBase(result, "updateUserProfile");
+      if (result.Idse != null) {
+        throw result.Idse;
+      }
+      if (result.ae != null) {
+        throw result.ae;
+      }
+      return;
+    }
+
   }
   public static class AsyncClient extends org.apache.thrift.async.TAsyncClient implements AsyncIface {
     public static class Factory implements org.apache.thrift.async.TAsyncClientFactory<AsyncClient> {
@@ -545,6 +576,41 @@ public class IamAdminServices {
       }
     }
 
+    public void updateUserProfile(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.user.UserProfile userDetails, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      updateUserProfile_call method_call = new updateUserProfile_call(authzToken, userDetails, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class updateUserProfile_call extends org.apache.thrift.async.TAsyncMethodCall {
+      private org.apache.airavata.model.security.AuthzToken authzToken;
+      private org.apache.airavata.model.user.UserProfile userDetails;
+      public updateUserProfile_call(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.user.UserProfile userDetails, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.authzToken = authzToken;
+        this.userDetails = userDetails;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updateUserProfile", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        updateUserProfile_args args = new updateUserProfile_args();
+        args.setAuthzToken(authzToken);
+        args.setUserDetails(userDetails);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public void getResult() throws org.apache.airavata.service.profile.iam.admin.services.cpi.exception.IamAdminServicesException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        (new Client(prot)).recv_updateUserProfile();
+      }
+    }
+
   }
 
   public static class Processor<I extends Iface> extends org.apache.thrift.TBaseProcessor<I> implements org.apache.thrift.TProcessor {
@@ -564,6 +630,7 @@ public class IamAdminServices {
       processMap.put("enableUser", new enableUser());
       processMap.put("resetUserPassword", new resetUserPassword());
       processMap.put("findUsers", new findUsers());
+      processMap.put("updateUserProfile", new updateUserProfile());
       return processMap;
     }
 
@@ -726,6 +793,32 @@ public class IamAdminServices {
       }
     }
 
+    public static class updateUserProfile<I extends Iface> extends org.apache.thrift.ProcessFunction<I, updateUserProfile_args> {
+      public updateUserProfile() {
+        super("updateUserProfile");
+      }
+
+      public updateUserProfile_args getEmptyArgsInstance() {
+        return new updateUserProfile_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public updateUserProfile_result getResult(I iface, updateUserProfile_args args) throws org.apache.thrift.TException {
+        updateUserProfile_result result = new updateUserProfile_result();
+        try {
+          iface.updateUserProfile(args.authzToken, args.userDetails);
+        } catch (org.apache.airavata.service.profile.iam.admin.services.cpi.exception.IamAdminServicesException Idse) {
+          result.Idse = Idse;
+        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
+          result.ae = ae;
+        }
+        return result;
+      }
+    }
+
   }
 
   public static class AsyncProcessor<I extends AsyncIface> extends org.apache.thrift.TBaseAsyncProcessor<I> {
@@ -745,6 +838,7 @@ public class IamAdminServices {
       processMap.put("enableUser", new enableUser());
       processMap.put("resetUserPassword", new resetUserPassword());
       processMap.put("findUsers", new findUsers());
+      processMap.put("updateUserProfile", new updateUserProfile());
       return processMap;
     }
 
@@ -1123,6 +1217,67 @@ public class IamAdminServices {
       }
     }
 
+    public static class updateUserProfile<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, updateUserProfile_args, Void> {
+      public updateUserProfile() {
+        super("updateUserProfile");
+      }
+
+      public updateUserProfile_args getEmptyArgsInstance() {
+        return new updateUserProfile_args();
+      }
+
+      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new AsyncMethodCallback<Void>() { 
+          public void onComplete(Void o) {
+            updateUserProfile_result result = new updateUserProfile_result();
+            try {
+              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+              return;
+            } catch (Exception e) {
+              LOGGER.error("Exception writing to internal frame buffer", e);
+            }
+            fb.close();
+          }
+          public void onError(Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TBase msg;
+            updateUserProfile_result result = new updateUserProfile_result();
+            if (e instanceof org.apache.airavata.service.profile.iam.admin.services.cpi.exception.IamAdminServicesException) {
+                        result.Idse = (org.apache.airavata.service.profile.iam.admin.services.cpi.exception.IamAdminServicesException) e;
+                        result.setIdseIsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof org.apache.airavata.model.error.AuthorizationException) {
+                        result.ae = (org.apache.airavata.model.error.AuthorizationException) e;
+                        result.setAeIsSet(true);
+                        msg = result;
+            }
+             else 
+            {
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+              return;
+            } catch (Exception ex) {
+              LOGGER.error("Exception writing to internal frame buffer", ex);
+            }
+            fb.close();
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, updateUserProfile_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+        iface.updateUserProfile(args.authzToken, args.userDetails,resultHandler);
+      }
+    }
+
   }
 
   public static class getAPIVersion_args implements org.apache.thrift.TBase<getAPIVersion_args, getAPIVersion_args._Fields>, java.io.Serializable, Cloneable, Comparable<getAPIVersion_args>   {
@@ -8237,4 +8392,939 @@ public class IamAdminServices {
 
   }
 
+  public static class updateUserProfile_args implements org.apache.thrift.TBase<updateUserProfile_args, updateUserProfile_args._Fields>, java.io.Serializable, Cloneable, Comparable<updateUserProfile_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateUserProfile_args");
+
+    private static final org.apache.thrift.protocol.TField AUTHZ_TOKEN_FIELD_DESC = new org.apache.thrift.protocol.TField("authzToken", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+    private static final org.apache.thrift.protocol.TField USER_DETAILS_FIELD_DESC = new org.apache.thrift.protocol.TField("userDetails", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new updateUserProfile_argsStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new updateUserProfile_argsTupleSchemeFactory());
+    }
+
+    public org.apache.airavata.model.security.AuthzToken authzToken; // required
+    public org.apache.airavata.model.user.UserProfile userDetails; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      AUTHZ_TOKEN((short)1, "authzToken"),
+      USER_DETAILS((short)2, "userDetails");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // AUTHZ_TOKEN
+            return AUTHZ_TOKEN;
+          case 2: // USER_DETAILS
+            return USER_DETAILS;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.AUTHZ_TOKEN, new org.apache.thrift.meta_data.FieldMetaData("authzToken", org.apache.thrift.TFieldRequirementType.REQUIRED, 
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.security.AuthzToken.class)));
+      tmpMap.put(_Fields.USER_DETAILS, new org.apache.thrift.meta_data.FieldMetaData("userDetails", org.apache.thrift.TFieldRequirementType.REQUIRED, 
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.user.UserProfile.class)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateUserProfile_args.class, metaDataMap);
+    }
+
+    public updateUserProfile_args() {
+    }
+
+    public updateUserProfile_args(
+      org.apache.airavata.model.security.AuthzToken authzToken,
+      org.apache.airavata.model.user.UserProfile userDetails)
+    {
+      this();
+      this.authzToken = authzToken;
+      this.userDetails = userDetails;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public updateUserProfile_args(updateUserProfile_args other) {
+      if (other.isSetAuthzToken()) {
+        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
+      }
+      if (other.isSetUserDetails()) {
+        this.userDetails = new org.apache.airavata.model.user.UserProfile(other.userDetails);
+      }
+    }
+
+    public updateUserProfile_args deepCopy() {
+      return new updateUserProfile_args(this);
+    }
+
+    @Override
+    public void clear() {
+      this.authzToken = null;
+      this.userDetails = null;
+    }
+
+    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
+      return this.authzToken;
+    }
+
+    public updateUserProfile_args setAuthzToken(org.apache.airavata.model.security.AuthzToken authzToken) {
+      this.authzToken = authzToken;
+      return this;
+    }
+
+    public void unsetAuthzToken() {
+      this.authzToken = null;
+    }
+
+    /** Returns true if field authzToken is set (has been assigned a value) and false otherwise */
+    public boolean isSetAuthzToken() {
+      return this.authzToken != null;
+    }
+
+    public void setAuthzTokenIsSet(boolean value) {
+      if (!value) {
+        this.authzToken = null;
+      }
+    }
+
+    public org.apache.airavata.model.user.UserProfile getUserDetails() {
+      return this.userDetails;
+    }
+
+    public updateUserProfile_args setUserDetails(org.apache.airavata.model.user.UserProfile userDetails) {
+      this.userDetails = userDetails;
+      return this;
+    }
+
+    public void unsetUserDetails() {
+      this.userDetails = null;
+    }
+
+    /** Returns true if field userDetails is set (has been assigned a value) and false otherwise */
+    public boolean isSetUserDetails() {
+      return this.userDetails != null;
+    }
+
+    public void setUserDetailsIsSet(boolean value) {
+      if (!value) {
+        this.userDetails = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case AUTHZ_TOKEN:
+        if (value == null) {
+          unsetAuthzToken();
+        } else {
+          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
+        }
+        break;
+
+      case USER_DETAILS:
+        if (value == null) {
+          unsetUserDetails();
+        } else {
+          setUserDetails((org.apache.airavata.model.user.UserProfile)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case AUTHZ_TOKEN:
+        return getAuthzToken();
+
+      case USER_DETAILS:
+        return getUserDetails();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case AUTHZ_TOKEN:
+        return isSetAuthzToken();
+      case USER_DETAILS:
+        return isSetUserDetails();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof updateUserProfile_args)
+        return this.equals((updateUserProfile_args)that);
+      return false;
+    }
+
+    public boolean equals(updateUserProfile_args that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_authzToken = true && this.isSetAuthzToken();
+      boolean that_present_authzToken = true && that.isSetAuthzToken();
+      if (this_present_authzToken || that_present_authzToken) {
+        if (!(this_present_authzToken && that_present_authzToken))
+          return false;
+        if (!this.authzToken.equals(that.authzToken))
+          return false;
+      }
+
+      boolean this_present_userDetails = true && this.isSetUserDetails();
+      boolean that_present_userDetails = true && that.isSetUserDetails();
+      if (this_present_userDetails || that_present_userDetails) {
+        if (!(this_present_userDetails && that_present_userDetails))
+          return false;
+        if (!this.userDetails.equals(that.userDetails))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_authzToken = true && (isSetAuthzToken());
+      list.add(present_authzToken);
+      if (present_authzToken)
+        list.add(authzToken);
+
+      boolean present_userDetails = true && (isSetUserDetails());
+      list.add(present_userDetails);
+      if (present_userDetails)
+        list.add(userDetails);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(updateUserProfile_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetAuthzToken()).compareTo(other.isSetAuthzToken());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetAuthzToken()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.authzToken, other.authzToken);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetUserDetails()).compareTo(other.isSetUserDetails());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetUserDetails()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userDetails, other.userDetails);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("updateUserProfile_args(");
+      boolean first = true;
+
+      sb.append("authzToken:");
+      if (this.authzToken == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.authzToken);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("userDetails:");
+      if (this.userDetails == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.userDetails);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      if (authzToken == null) {
+        throw new org.apache.thrift.protocol.TProtocolException("Required field 'authzToken' was not present! Struct: " + toString());
+      }
+      if (userDetails == null) {
+        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userDetails' was not present! Struct: " + toString());
+      }
+      // check for sub-struct validity
+      if (authzToken != null) {
+        authzToken.validate();
+      }
+      if (userDetails != null) {
+        userDetails.validate();
+      }
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class updateUserProfile_argsStandardSchemeFactory implements SchemeFactory {
+      public updateUserProfile_argsStandardScheme getScheme() {
+        return new updateUserProfile_argsStandardScheme();
+      }
+    }
+
+    private static class updateUserProfile_argsStandardScheme extends StandardScheme<updateUserProfile_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, updateUserProfile_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // AUTHZ_TOKEN
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
+                struct.authzToken.read(iprot);
+                struct.setAuthzTokenIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // USER_DETAILS
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.userDetails = new org.apache.airavata.model.user.UserProfile();
+                struct.userDetails.read(iprot);
+                struct.setUserDetailsIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, updateUserProfile_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.authzToken != null) {
+          oprot.writeFieldBegin(AUTHZ_TOKEN_FIELD_DESC);
+          struct.authzToken.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.userDetails != null) {
+          oprot.writeFieldBegin(USER_DETAILS_FIELD_DESC);
+          struct.userDetails.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class updateUserProfile_argsTupleSchemeFactory implements SchemeFactory {
+      public updateUserProfile_argsTupleScheme getScheme() {
+        return new updateUserProfile_argsTupleScheme();
+      }
+    }
+
+    private static class updateUserProfile_argsTupleScheme extends TupleScheme<updateUserProfile_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, updateUserProfile_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        struct.authzToken.write(oprot);
+        struct.userDetails.write(oprot);
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, updateUserProfile_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
+        struct.authzToken.read(iprot);
+        struct.setAuthzTokenIsSet(true);
+        struct.userDetails = new org.apache.airavata.model.user.UserProfile();
+        struct.userDetails.read(iprot);
+        struct.setUserDetailsIsSet(true);
+      }
+    }
+
+  }
+
+  public static class updateUserProfile_result implements org.apache.thrift.TBase<updateUserProfile_result, updateUserProfile_result._Fields>, java.io.Serializable, Cloneable, Comparable<updateUserProfile_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateUserProfile_result");
+
+    private static final org.apache.thrift.protocol.TField IDSE_FIELD_DESC = new org.apache.thrift.protocol.TField("Idse", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+    private static final org.apache.thrift.protocol.TField AE_FIELD_DESC = new org.apache.thrift.protocol.TField("ae", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new updateUserProfile_resultStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new updateUserProfile_resultTupleSchemeFactory());
+    }
+
+    public org.apache.airavata.service.profile.iam.admin.services.cpi.exception.IamAdminServicesException Idse; // required
+    public org.apache.airavata.model.error.AuthorizationException ae; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      IDSE((short)1, "Idse"),
+      AE((short)2, "ae");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // IDSE
+            return IDSE;
+          case 2: // AE
+            return AE;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.IDSE, new org.apache.thrift.meta_data.FieldMetaData("Idse", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateUserProfile_result.class, metaDataMap);
+    }
+
+    public updateUserProfile_result() {
+    }
+
+    public updateUserProfile_result(
+      org.apache.airavata.service.profile.iam.admin.services.cpi.exception.IamAdminServicesException Idse,
+      org.apache.airavata.model.error.AuthorizationException ae)
+    {
+      this();
+      this.Idse = Idse;
+      this.ae = ae;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public updateUserProfile_result(updateUserProfile_result other) {
+      if (other.isSetIdse()) {
+        this.Idse = new org.apache.airavata.service.profile.iam.admin.services.cpi.exception.IamAdminServicesException(other.Idse);
+      }
+      if (other.isSetAe()) {
+        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
+      }
+    }
+
+    public updateUserProfile_result deepCopy() {
+      return new updateUserProfile_result(this);
+    }
+
+    @Override
+    public void clear() {
+      this.Idse = null;
+      this.ae = null;
+    }
+
+    public org.apache.airavata.service.profile.iam.admin.services.cpi.exception.IamAdminServicesException getIdse() {
+      return this.Idse;
+    }
+
+    public updateUserProfile_result setIdse(org.apache.airavata.service.profile.iam.admin.services.cpi.exception.IamAdminServicesException Idse) {
+      this.Idse = Idse;
+      return this;
+    }
+
+    public void unsetIdse() {
+      this.Idse = null;
+    }
+
+    /** Returns true if field Idse is set (has been assigned a value) and false otherwise */
+    public boolean isSetIdse() {
+      return this.Idse != null;
+    }
+
+    public void setIdseIsSet(boolean value) {
+      if (!value) {
+        this.Idse = null;
+      }
+    }
+
+    public org.apache.airavata.model.error.AuthorizationException getAe() {
+      return this.ae;
+    }
+
+    public updateUserProfile_result setAe(org.apache.airavata.model.error.AuthorizationException ae) {
+      this.ae = ae;
+      return this;
+    }
+
+    public void unsetAe() {
+      this.ae = null;
+    }
+
+    /** Returns true if field ae is set (has been assigned a value) and false otherwise */
+    public boolean isSetAe() {
+      return this.ae != null;
+    }
+
+    public void setAeIsSet(boolean value) {
+      if (!value) {
+        this.ae = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case IDSE:
+        if (value == null) {
+          unsetIdse();
+        } else {
+          setIdse((org.apache.airavata.service.profile.iam.admin.services.cpi.exception.IamAdminServicesException)value);
+        }
+        break;
+
+      case AE:
+        if (value == null) {
+          unsetAe();
+        } else {
+          setAe((org.apache.airavata.model.error.AuthorizationException)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case IDSE:
+        return getIdse();
+
+      case AE:
+        return getAe();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case IDSE:
+        return isSetIdse();
+      case AE:
+        return isSetAe();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof updateUserProfile_result)
+        return this.equals((updateUserProfile_result)that);
+      return false;
+    }
+
+    public boolean equals(updateUserProfile_result that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_Idse = true && this.isSetIdse();
+      boolean that_present_Idse = true && that.isSetIdse();
+      if (this_present_Idse || that_present_Idse) {
+        if (!(this_present_Idse && that_present_Idse))
+          return false;
+        if (!this.Idse.equals(that.Idse))
+          return false;
+      }
+
+      boolean this_present_ae = true && this.isSetAe();
+      boolean that_present_ae = true && that.isSetAe();
+      if (this_present_ae || that_present_ae) {
+        if (!(this_present_ae && that_present_ae))
+          return false;
+        if (!this.ae.equals(that.ae))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_Idse = true && (isSetIdse());
+      list.add(present_Idse);
+      if (present_Idse)
+        list.add(Idse);
+
+      boolean present_ae = true && (isSetAe());
+      list.add(present_ae);
+      if (present_ae)
+        list.add(ae);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(updateUserProfile_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetIdse()).compareTo(other.isSetIdse());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetIdse()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.Idse, other.Idse);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetAe()).compareTo(other.isSetAe());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetAe()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ae, other.ae);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+      }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("updateUserProfile_result(");
+      boolean first = true;
+
+      sb.append("Idse:");
+      if (this.Idse == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.Idse);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ae:");
+      if (this.ae == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ae);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class updateUserProfile_resultStandardSchemeFactory implements SchemeFactory {
+      public updateUserProfile_resultStandardScheme getScheme() {
+        return new updateUserProfile_resultStandardScheme();
+      }
+    }
+
+    private static class updateUserProfile_resultStandardScheme extends StandardScheme<updateUserProfile_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, updateUserProfile_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // IDSE
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.Idse = new org.apache.airavata.service.profile.iam.admin.services.cpi.exception.IamAdminServicesException();
+                struct.Idse.read(iprot);
+                struct.setIdseIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // AE
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ae = new org.apache.airavata.model.error.AuthorizationException();
+                struct.ae.read(iprot);
+                struct.setAeIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, updateUserProfile_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.Idse != null) {
+          oprot.writeFieldBegin(IDSE_FIELD_DESC);
+          struct.Idse.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ae != null) {
+          oprot.writeFieldBegin(AE_FIELD_DESC);
+          struct.ae.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class updateUserProfile_resultTupleSchemeFactory implements SchemeFactory {
+      public updateUserProfile_resultTupleScheme getScheme() {
+        return new updateUserProfile_resultTupleScheme();
+      }
+    }
+
+    private static class updateUserProfile_resultTupleScheme extends TupleScheme<updateUserProfile_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, updateUserProfile_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetIdse()) {
+          optionals.set(0);
+        }
+        if (struct.isSetAe()) {
+          optionals.set(1);
+        }
+        oprot.writeBitSet(optionals, 2);
+        if (struct.isSetIdse()) {
+          struct.Idse.write(oprot);
+        }
+        if (struct.isSetAe()) {
+          struct.ae.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, updateUserProfile_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(2);
+        if (incoming.get(0)) {
+          struct.Idse = new org.apache.airavata.service.profile.iam.admin.services.cpi.exception.IamAdminServicesException();
+          struct.Idse.read(iprot);
+          struct.setIdseIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
+          struct.ae.read(iprot);
+          struct.setAeIsSet(true);
+        }
+      }
+    }
+
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/airavata/blob/b1c390cb/airavata-services/profile-service/profile-user-core/src/main/java/org/apache/airavata/service/profile/user/core/repositories/UserProfileRepository.java
----------------------------------------------------------------------
diff --git a/airavata-services/profile-service/profile-user-core/src/main/java/org/apache/airavata/service/profile/user/core/repositories/UserProfileRepository.java b/airavata-services/profile-service/profile-user-core/src/main/java/org/apache/airavata/service/profile/user/core/repositories/UserProfileRepository.java
index 41823c9..98796a4 100644
--- a/airavata-services/profile-service/profile-user-core/src/main/java/org/apache/airavata/service/profile/user/core/repositories/UserProfileRepository.java
+++ b/airavata-services/profile-service/profile-user-core/src/main/java/org/apache/airavata/service/profile/user/core/repositories/UserProfileRepository.java
@@ -23,12 +23,13 @@ package org.apache.airavata.service.profile.user.core.repositories;
 import org.apache.airavata.model.user.UserProfile;
 import org.apache.airavata.service.profile.commons.repositories.AbstractRepository;
 import org.apache.airavata.service.profile.commons.user.entities.UserProfileEntity;
+import org.apache.airavata.service.profile.commons.utils.JPAUtils;
+import org.apache.airavata.service.profile.commons.utils.ObjectMapperSingleton;
 import org.apache.airavata.service.profile.commons.utils.QueryConstants;
 import org.dozer.Mapper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -70,6 +71,18 @@ public class UserProfileRepository extends AbstractRepository<UserProfile, UserP
         return  resultList;
     }
 
+    public UserProfile updateUserProfile(UserProfile userProfile, Runnable postUpdateAction) {
+
+        Mapper mapper = ObjectMapperSingleton.getInstance();
+        UserProfileEntity entity = mapper.map(userProfile, UserProfileEntity.class);
+        UserProfileEntity persistedCopy = JPAUtils.execute(entityManager -> {
+            UserProfileEntity result = entityManager.merge(entity);
+            postUpdateAction.run();
+            return result;
+        });
+        return mapper.map(persistedCopy, UserProfile.class);
+    }
+
 //    public static void main(String args[]) {
 //        Mapper mapper = ObjectMapperSingleton.getInstance();
 //        UserProfile up = new UserProfile();

http://git-wip-us.apache.org/repos/asf/airavata/blob/b1c390cb/thrift-interface-descriptions/service-cpis/profile-service/iam-admin-services/iam-admin-services-cpi.thrift
----------------------------------------------------------------------
diff --git a/thrift-interface-descriptions/service-cpis/profile-service/iam-admin-services/iam-admin-services-cpi.thrift b/thrift-interface-descriptions/service-cpis/profile-service/iam-admin-services/iam-admin-services-cpi.thrift
index fdb5493..32a9c67 100644
--- a/thrift-interface-descriptions/service-cpis/profile-service/iam-admin-services/iam-admin-services-cpi.thrift
+++ b/thrift-interface-descriptions/service-cpis/profile-service/iam-admin-services/iam-admin-services-cpi.thrift
@@ -78,4 +78,8 @@ service IamAdminServices {
                                 throws (1: iam_admin_services_cpi_errors.IamAdminServicesException Idse,
                                                             2: airavata_errors.AuthorizationException ae)
 
+    void updateUserProfile(1: required security_model.AuthzToken authzToken,
+                           2: required user_profile_model.UserProfile userDetails)
+        throws (1: iam_admin_services_cpi_errors.IamAdminServicesException Idse,
+                2: airavata_errors.AuthorizationException ae)
 }
\ No newline at end of file