From 4ea36b82e9bb88e75f98982f8c302719f7520f2d Mon Sep 17 00:00:00 2001 From: kishan Date: Fri, 24 Aug 2012 15:59:59 +0530 Subject: [PATCH] propogate account changes to other Regions --- api/src/com/cloud/api/ApiConstants.java | 5 +- .../cloud/api/commands/CreateAccountCmd.java | 41 +++- .../cloud/api/commands/DeleteAccountCmd.java | 18 +- .../cloud/api/commands/DisableAccountCmd.java | 24 ++- .../cloud/api/commands/EnableAccountCmd.java | 16 +- .../cloud/api/commands/UpdateAccountCmd.java | 16 +- api/src/com/cloud/region/RegionService.java | 6 + api/src/com/cloud/user/Account.java | 4 + api/src/com/cloud/user/AccountService.java | 2 +- core/src/com/cloud/user/AccountVO.java | 4 +- core/src/com/cloud/user/UserVO.java | 7 +- .../cloud/projects/ProjectManagerImpl.java | 2 +- .../src/com/cloud/region/RegionManager.java | 7 +- .../com/cloud/region/RegionManagerImpl.java | 198 ++++++++++++++++-- server/src/com/cloud/region/RegionVO.java | 8 +- server/src/com/cloud/user/AccountManager.java | 2 +- .../com/cloud/user/AccountManagerImpl.java | 83 ++++++-- .../com/cloud/user/dao/AccountDaoImpl.java | 7 - 18 files changed, 380 insertions(+), 70 deletions(-) diff --git a/api/src/com/cloud/api/ApiConstants.java b/api/src/com/cloud/api/ApiConstants.java index 69e7939c82c..b5e60026086 100755 --- a/api/src/com/cloud/api/ApiConstants.java +++ b/api/src/com/cloud/api/ApiConstants.java @@ -358,7 +358,10 @@ public class ApiConstants { public static final String VSM_DEVICE_STATE = "vsmdevicestate"; public static final String ADD_VSM_FLAG = "addvsmflag"; public static final String END_POINT = "endpoint"; - + //public static final String REGION_DETAILS = "regiondetails"; + public static final String REGION_ID = "regionid"; + public static final String IS_PROPAGATE = "ispropagate"; + public enum HostDetails { all, capacity, events, stats, min; } diff --git a/api/src/com/cloud/api/commands/CreateAccountCmd.java b/api/src/com/cloud/api/commands/CreateAccountCmd.java index 00e87761c5d..9fc7d2d560c 100755 --- a/api/src/com/cloud/api/commands/CreateAccountCmd.java +++ b/api/src/com/cloud/api/commands/CreateAccountCmd.java @@ -76,6 +76,20 @@ public class CreateAccountCmd extends BaseCmd { @Parameter(name = ApiConstants.ACCOUNT_DETAILS, type = CommandType.MAP, description = "details for account used to store specific parameters") private Map details; + + //@Parameter(name = ApiConstants.REGION_DETAILS, type = CommandType.MAP, description = "details for account used to store region specific parameters") + //private Map regionDetails; + + @Parameter(name=ApiConstants.ACCOUNT_ID, type=CommandType.STRING, description="Account UUID, required for adding account from another Region") + private String accountUUID; + + @Parameter(name=ApiConstants.USER_ID, type=CommandType.STRING, description="User UUID, required for adding account from another Region") + private String userUUID; + + @Parameter(name=ApiConstants.REGION_ID, type=CommandType.LONG, description="Id of the Region creating the account") + private Long regionId; + + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -130,11 +144,31 @@ public class CreateAccountCmd extends BaseCmd { return params; } + /*public Map getRegionDetails() { + if (regionDetails == null || regionDetails.isEmpty()) { + return null; + } + + return regionDetails; + }*/ + + public String getAccountUUID() { + return accountUUID; + } + + public String getUserUUID() { + return userUUID; + } + + public Long getRegionId() { + return regionId; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// - @Override + @Override public String getCommandName() { return s_name; } @@ -144,10 +178,11 @@ public class CreateAccountCmd extends BaseCmd { return Account.ACCOUNT_ID_SYSTEM; } - @Override + @Override public void execute(){ UserContext.current().setEventDetails("Account Name: "+getAccountName()+", Domain Id:"+getDomainId()); - UserAccount userAccount = _accountService.createUserAccount(getUsername(), getPassword(), getFirstName(), getLastName(), getEmail(), getTimeZone(), getAccountName(), getAccountType(), getDomainId(), getNetworkDomain(), getDetails()); + UserAccount userAccount = _accountService.createUserAccount(getUsername(), getPassword(), getFirstName(), getLastName(), getEmail(), getTimeZone(), getAccountName(), getAccountType(), getDomainId(), getNetworkDomain(), getDetails(), + getAccountUUID(), getUserUUID(), getRegionId()); if (userAccount != null) { AccountResponse response = _responseGenerator.createUserAccountResponse(userAccount); response.setResponseName(getCommandName()); diff --git a/api/src/com/cloud/api/commands/DeleteAccountCmd.java b/api/src/com/cloud/api/commands/DeleteAccountCmd.java index a7bfca78359..9b40e6bb1d7 100755 --- a/api/src/com/cloud/api/commands/DeleteAccountCmd.java +++ b/api/src/com/cloud/api/commands/DeleteAccountCmd.java @@ -46,15 +46,21 @@ public class DeleteAccountCmd extends BaseAsyncCmd { @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="Account id") private Long id; + @Parameter(name=ApiConstants.IS_PROPAGATE, type=CommandType.BOOLEAN, description="True if command is sent from another Region") + private Boolean isPropagate; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// - public Long getId() { + + public Long getId() { return id; } - + + public Boolean getIsPropagate() { + return isPropagate; + } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// @@ -93,7 +99,13 @@ public class DeleteAccountCmd extends BaseAsyncCmd { @Override public void execute(){ UserContext.current().setEventDetails("Account Id: "+getId()); - boolean result = _accountService.deleteUserAccount(getId()); + boolean isPopagate = (getIsPropagate() != null ) ? getIsPropagate() : false; + boolean result = false; + if(isPopagate){ + result = _accountService.deleteUserAccount(getId()); + } else { + result = _regionService.deleteUserAccount(getId()); + } if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); this.setResponseObject(response); diff --git a/api/src/com/cloud/api/commands/DisableAccountCmd.java b/api/src/com/cloud/api/commands/DisableAccountCmd.java index 7c5e5e38331..ba22166f2dc 100644 --- a/api/src/com/cloud/api/commands/DisableAccountCmd.java +++ b/api/src/com/cloud/api/commands/DisableAccountCmd.java @@ -25,6 +25,7 @@ import com.cloud.api.IdentityMapper; import com.cloud.api.Implementation; import com.cloud.api.Parameter; import com.cloud.api.ServerApiException; +import com.cloud.api.BaseCmd.CommandType; import com.cloud.api.response.AccountResponse; import com.cloud.async.AsyncJob; import com.cloud.event.EventTypes; @@ -55,6 +56,9 @@ public class DisableAccountCmd extends BaseAsyncCmd { @Parameter(name=ApiConstants.LOCK, type=CommandType.BOOLEAN, required=true, description="If true, only lock the account; else disable the account") private Boolean lockRequested; + @Parameter(name=ApiConstants.IS_PROPAGATE, type=CommandType.BOOLEAN, description="True if command is sent from another Region") + private Boolean isPropagate; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -71,6 +75,10 @@ public class DisableAccountCmd extends BaseAsyncCmd { return domainId; } + public Boolean getIsPropagate() { + return isPropagate; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @@ -109,10 +117,18 @@ public class DisableAccountCmd extends BaseAsyncCmd { public void execute() throws ConcurrentOperationException, ResourceUnavailableException{ UserContext.current().setEventDetails("Account Name: "+getAccountName()+", Domain Id:"+getDomainId()); Account result = null; - if(lockRequested) - result = _accountService.lockAccount(getAccountName(), getDomainId(), getId()); - else - result = _accountService.disableAccount(getAccountName(), getDomainId(), getId()); + boolean isPopagate = (getIsPropagate() != null ) ? getIsPropagate() : false; + if(isPopagate){ + if(lockRequested) + result = _accountService.lockAccount(getAccountName(), getDomainId(), getId()); + else + result = _accountService.disableAccount(getAccountName(), getDomainId(), getId()); + } else { + if(lockRequested) + result = _regionService.lockAccount(getAccountName(), getDomainId(), getId()); + else + result = _regionService.disableAccount(getAccountName(), getDomainId(), getId()); + } if (result != null){ AccountResponse response = _responseGenerator.createAccountResponse(result); response.setResponseName(getCommandName()); diff --git a/api/src/com/cloud/api/commands/EnableAccountCmd.java b/api/src/com/cloud/api/commands/EnableAccountCmd.java index 576f9354892..536358e21cc 100644 --- a/api/src/com/cloud/api/commands/EnableAccountCmd.java +++ b/api/src/com/cloud/api/commands/EnableAccountCmd.java @@ -24,6 +24,7 @@ import com.cloud.api.IdentityMapper; import com.cloud.api.Implementation; import com.cloud.api.Parameter; import com.cloud.api.ServerApiException; +import com.cloud.api.BaseCmd.CommandType; import com.cloud.api.response.AccountResponse; import com.cloud.user.Account; @@ -46,6 +47,9 @@ public class EnableAccountCmd extends BaseCmd { @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="Enables specified account in this domain.") private Long domainId; + @Parameter(name=ApiConstants.IS_PROPAGATE, type=CommandType.BOOLEAN, description="True if command is sent from another Region") + private Boolean isPropagate; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -62,6 +66,10 @@ public class EnableAccountCmd extends BaseCmd { return domainId; } + public Boolean getIsPropagate() { + return isPropagate; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @@ -88,7 +96,13 @@ public class EnableAccountCmd extends BaseCmd { @Override public void execute(){ - Account result = _accountService.enableAccount(getAccountName(), getDomainId(), getId()); + boolean isPopagate = (getIsPropagate() != null ) ? getIsPropagate() : false; + Account result = null; + if(isPopagate){ + result = _accountService.enableAccount(getAccountName(), getDomainId(), getId()); + } else { + result = _regionService.enableAccount(getAccountName(), getDomainId(), getId()); + } if (result != null){ AccountResponse response = _responseGenerator.createAccountResponse(result); response.setResponseName(getCommandName()); diff --git a/api/src/com/cloud/api/commands/UpdateAccountCmd.java b/api/src/com/cloud/api/commands/UpdateAccountCmd.java index 8e3ef4364b3..377a61b24f0 100755 --- a/api/src/com/cloud/api/commands/UpdateAccountCmd.java +++ b/api/src/com/cloud/api/commands/UpdateAccountCmd.java @@ -27,6 +27,7 @@ import com.cloud.api.IdentityMapper; import com.cloud.api.Implementation; import com.cloud.api.Parameter; import com.cloud.api.ServerApiException; +import com.cloud.api.BaseCmd.CommandType; import com.cloud.api.response.AccountResponse; import com.cloud.user.Account; @@ -59,6 +60,9 @@ public class UpdateAccountCmd extends BaseCmd{ @Parameter(name = ApiConstants.ACCOUNT_DETAILS, type = CommandType.MAP, description = "details for account used to store specific parameters") private Map details; + @Parameter(name=ApiConstants.IS_PROPAGATE, type=CommandType.BOOLEAN, description="True if command is sent from another Region") + private Boolean isPropagate; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -93,6 +97,10 @@ public class UpdateAccountCmd extends BaseCmd{ return params; } + public Boolean getIsPropagate() { + return isPropagate; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @@ -118,7 +126,13 @@ public class UpdateAccountCmd extends BaseCmd{ @Override public void execute(){ - Account result = _accountService.updateAccount(this); + boolean isPopagate = (getIsPropagate() != null ) ? getIsPropagate() : false; + Account result = null; + if(isPopagate){ + result = _accountService.updateAccount(this); + } else { + result = _regionService.updateAccount(this); + } if (result != null){ AccountResponse response = _responseGenerator.createAccountResponse(result); response.setResponseName(getCommandName()); diff --git a/api/src/com/cloud/region/RegionService.java b/api/src/com/cloud/region/RegionService.java index e149776ad54..f9cfeba6aca 100644 --- a/api/src/com/cloud/region/RegionService.java +++ b/api/src/com/cloud/region/RegionService.java @@ -19,6 +19,7 @@ package com.cloud.region; import java.util.List; import com.cloud.api.commands.ListRegionsCmd; +import com.cloud.api.commands.UpdateAccountCmd; import com.cloud.user.Account; @@ -27,4 +28,9 @@ public interface RegionService { public Region updateRegion(long id, String name, String endPoint); public boolean removeRegion(long id); public List listRegions(ListRegionsCmd cmd); + boolean deleteUserAccount(long accountId); + Account updateAccount(UpdateAccountCmd cmd); + public Account lockAccount(String accountName, Long domainId, Long id); + public Account disableAccount(String accountName, Long domainId, Long id); + public Account enableAccount(String accountName, Long domainId, Long id); } diff --git a/api/src/com/cloud/user/Account.java b/api/src/com/cloud/user/Account.java index 18f585be75b..6ae93e2b3e4 100755 --- a/api/src/com/cloud/user/Account.java +++ b/api/src/com/cloud/user/Account.java @@ -61,4 +61,8 @@ public interface Account extends ControlledEntity { public String getNetworkDomain(); public Long getDefaultZoneId(); + + public long getRegionId(); + + public String getUuid(); } diff --git a/api/src/com/cloud/user/AccountService.java b/api/src/com/cloud/user/AccountService.java index 02e9b27f0f5..0cb36d4da3f 100755 --- a/api/src/com/cloud/user/AccountService.java +++ b/api/src/com/cloud/user/AccountService.java @@ -62,7 +62,7 @@ public interface AccountService { * @return the user if created successfully, null otherwise */ UserAccount createUserAccount(String userName, String password, String firstName, String lastName, String email, String timezone, String accountName, short accountType, Long domainId, String networkDomain, - Map details); + Map details, String accountUUID, String userUUID, Long regionId); /** * Deletes a user by userId diff --git a/core/src/com/cloud/user/AccountVO.java b/core/src/com/cloud/user/AccountVO.java index a9bb51a9fba..629869d42bd 100644 --- a/core/src/com/cloud/user/AccountVO.java +++ b/core/src/com/cloud/user/AccountVO.java @@ -75,12 +75,14 @@ public class AccountVO implements Account, Identity { this.uuid = UUID.randomUUID().toString(); } - public AccountVO(String accountName, long domainId, String networkDomain, short type) { + public AccountVO(String accountName, long domainId, String networkDomain, short type, String uuid, long regionId) { this.accountName = accountName; this.domainId = domainId; this.networkDomain = networkDomain; this.type = type; this.state = State.enabled; + this.uuid = uuid; + this.regionId = regionId; } public void setNeedsCleanup(boolean value) { diff --git a/core/src/com/cloud/user/UserVO.java b/core/src/com/cloud/user/UserVO.java index efb0583f5a0..96e4465fee8 100644 --- a/core/src/com/cloud/user/UserVO.java +++ b/core/src/com/cloud/user/UserVO.java @@ -101,7 +101,7 @@ public class UserVO implements User, Identity { this.uuid = UUID.randomUUID().toString(); } - public UserVO(long accountId, String username, String password, String firstName, String lastName, String email, String timezone) { + public UserVO(long accountId, String username, String password, String firstName, String lastName, String email, String timezone, String uuid, long regionId) { this.accountId = accountId; this.username = username; this.password = password; @@ -110,9 +110,10 @@ public class UserVO implements User, Identity { this.email = email; this.timezone = timezone; this.state = State.enabled; - this.uuid = UUID.randomUUID().toString(); + this.uuid = uuid; + this.regionId = regionId; } - + @Override public long getId() { return id; diff --git a/server/src/com/cloud/projects/ProjectManagerImpl.java b/server/src/com/cloud/projects/ProjectManagerImpl.java index 01fdeda84a9..b37e18302c3 100755 --- a/server/src/com/cloud/projects/ProjectManagerImpl.java +++ b/server/src/com/cloud/projects/ProjectManagerImpl.java @@ -199,7 +199,7 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ StringBuilder acctNm = new StringBuilder("PrjAcct-"); acctNm.append(name).append("-").append(owner.getDomainId()); - Account projectAccount = _accountMgr.createAccount(acctNm.toString(), Account.ACCOUNT_TYPE_PROJECT, domainId, null, null); + Account projectAccount = _accountMgr.createAccount(acctNm.toString(), Account.ACCOUNT_TYPE_PROJECT, domainId, null, null, "", 0L); Project project = _projectDao.persist(new ProjectVO(name, displayText, owner.getDomainId(), projectAccount.getId())); diff --git a/server/src/com/cloud/region/RegionManager.java b/server/src/com/cloud/region/RegionManager.java index 4b61bed5e54..65b5cd64fab 100644 --- a/server/src/com/cloud/region/RegionManager.java +++ b/server/src/com/cloud/region/RegionManager.java @@ -16,11 +16,12 @@ // under the License. package com.cloud.region; +import java.util.Map; + public interface RegionManager { - public boolean propogateAddResource(); - public boolean propogateUpdateResource(); - public boolean propogateDeleteResource(); + public boolean propogateAddAccount(String userName, String password, String firstName, String lastName, String email, String timezone, String accountName, short accountType, Long domainId, String networkDomain, + Map details, String accountUUID, String userUUID, long regionId); public boolean addResource(); public boolean updateResource(); public boolean deleteResource(); diff --git a/server/src/com/cloud/region/RegionManagerImpl.java b/server/src/com/cloud/region/RegionManagerImpl.java index a44087196f5..804c1468fdd 100755 --- a/server/src/com/cloud/region/RegionManagerImpl.java +++ b/server/src/com/cloud/region/RegionManagerImpl.java @@ -16,6 +16,7 @@ // under the License. package com.cloud.region; +import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -23,13 +24,23 @@ import java.util.Map; import javax.ejb.Local; import javax.naming.ConfigurationException; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpException; +import org.apache.commons.httpclient.HttpMethod; +import org.apache.commons.httpclient.methods.GetMethod; import org.apache.log4j.Logger; import com.cloud.api.commands.ListRegionsCmd; +import com.cloud.api.commands.UpdateAccountCmd; import com.cloud.exception.InvalidParameterValueException; import com.cloud.region.dao.RegionDao; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.user.AccountVO; +import com.cloud.user.dao.AccountDao; import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; +import com.cloud.utils.exception.CloudRuntimeException; @Local(value = { RegionManager.class, RegionService.class }) public class RegionManagerImpl implements RegionManager, RegionService, Manager{ @@ -37,9 +48,13 @@ public class RegionManagerImpl implements RegionManager, RegionService, Manager{ @Inject private RegionDao _regionDao; + @Inject + private AccountDao _accountDao; + @Inject + private AccountManager _accountMgr; private String _name; - private long _id = 1; //ToDo, get this from config + private long _id = 1; //ToDo, get this from config or db.properties @Override public boolean configure(final String name, final Map params) throws ConfigurationException { @@ -63,23 +78,161 @@ public class RegionManagerImpl implements RegionManager, RegionService, Manager{ } @Override - public boolean propogateAddResource() { - // TODO Auto-generated method stub - return false; + public boolean propogateAddAccount(String userName, String password, String firstName, String lastName, String email, String timezone, + String accountName, short accountType, Long domainId, String networkDomain, Map details, String accountUUID, String userUUID, long regionId) { + List regions = _regionDao.listAll(); + StringBuffer params = new StringBuffer("/api?command=createAccount"); + params.append("&username="+userName); + params.append("&password="+password); + params.append("&firstname="+firstName); + params.append("&lastname="+lastName); + params.append("&email="+email); + if(timezone != null){ + params.append("&timezone="+timezone); + } + if(accountName != null){ + params.append("&account="+accountName); + } + params.append("&accounttype="+accountType); + if(domainId != null){ + params.append("&domainid="+domainId); //use UUID + } + if(networkDomain != null){ + params.append("&networkdomain="+networkDomain); + } + if(details != null){ + params.append("&accountdetails="+details); //ToDo change to Map + } + params.append("&accountid="+accountUUID); + params.append("&userid="+userUUID); + params.append("®ionid="+regionId); + + for (Region region : regions){ + if(region.getId() == getId()){ + continue; + } + s_logger.debug("Adding account :"+accountName+" to Region: "+region.getId()); + String url = region.getEndPoint() + params; + if (makeAPICall(url)) { + s_logger.debug("Successfully added account :"+accountName+" to Region: "+region.getId()); + } else { + s_logger.error("Error while Adding account :"+accountName+" to Region: "+region.getId()); + //Send Account delete to all Regions where account is added successfully + break; + } + } + return true; } @Override - public boolean propogateUpdateResource() { - // TODO Auto-generated method stub - return false; + public boolean deleteUserAccount(long accountId) { + AccountVO account = _accountDao.findById(accountId); + //Check null account + String accountUUID = account.getUuid(); + long regionId = account.getRegionId(); + String params = "/api?command=deleteAccount&id="+accountUUID+"&ispropagate=true"; + if(getId() == regionId){ + if(_accountMgr.deleteUserAccount(accountId)){ + List regions = _regionDao.listAll(); + for (Region region : regions){ + if(region.getId() == getId()){ + continue; + } + String url = region.getEndPoint() + params; + if (makeAPICall(url)) { + s_logger.debug("Successfully deleted account :"+accountUUID+" in Region: "+region.getId()); + } else { + s_logger.error("Error while deleted account :"+accountUUID+" in Region: "+region.getId()); + } + } + return true; + } else { + return false; + } + } else { + //First delete in the Region where account is created + params = "/api?command=deleteAccount&id="+accountUUID; + Region region = _regionDao.findById(regionId); + String url = region.getEndPoint() + params; + if (makeAPICall(url)) { + s_logger.debug("Successfully deleted account :"+accountUUID+" in Region: "+region.getId()); + return true; + } else { + s_logger.error("Error while deleted account :"+accountUUID+" in Region: "+region.getId()); + return false; + } + } } - + @Override - public boolean propogateDeleteResource() { - // TODO Auto-generated method stub - return false; + public Account updateAccount(UpdateAccountCmd cmd) { + Long accountId = cmd.getId(); + Long domainId = cmd.getDomainId(); + String accountName = cmd.getAccountName(); + String newAccountName = cmd.getNewName(); + String networkDomain = cmd.getNetworkDomain(); + Map details = cmd.getDetails(); + + AccountVO account = _accountDao.findById(accountId); + //Check null account + String accountUUID = account.getUuid(); + long regionId = account.getRegionId(); + if(getId() == regionId){ + Account updateAccount = _accountMgr.updateAccount(cmd); + if(updateAccount != null){ + List regions = _regionDao.listAll(); + StringBuffer params = new StringBuffer("/api?command=updateAccount"+"&ispropagate=true"); + for (Region region : regions){ + if(region.getId() == getId()){ + continue; + } + String url = region.getEndPoint() + params; + if (makeAPICall(url)) { + s_logger.debug("Successfully updated account :"+accountUUID+" in Region: "+region.getId()); + } else { + s_logger.error("Error while updated account :"+accountUUID+" in Region: "+region.getId()); + } + } + } + return updateAccount; + } else { + //First update in the Region where account is created + StringBuffer params = new StringBuffer("/api?command=updateAccount"); + //add params + Region region = _regionDao.findById(regionId); + String url = region.getEndPoint() + params; + if (makeAPICall(url)) { + s_logger.debug("Successfully updated account :"+accountUUID+" in source Region: "+region.getId()); + //return Account object + return null; + } else { + s_logger.error("Error while updated account :"+accountUUID+" in source Region: "+region.getId()); + //throw exception; + return null; + } + } } + private boolean makeAPICall(String url){ + try { + + HttpClient client = new HttpClient(); + HttpMethod method = new GetMethod(url); + if( client.executeMethod(method) == 200){ + return true; + } else { + return false; + } + } catch (HttpException e) { + s_logger.error(e.getMessage()); + return false; + } catch (IOException e) { + s_logger.error(e.getMessage()); + return false; + } + + } + @Override public boolean addResource() { // TODO Auto-generated method stub @@ -115,7 +268,8 @@ public class RegionManagerImpl implements RegionManager, RegionService, Manager{ region.setEndPoint(endPoint); } - return region; + _regionDao.update(id, region); + return _regionDao.findById(id); } @Override @@ -145,5 +299,23 @@ public class RegionManagerImpl implements RegionManager, RegionService, Manager{ } return _regionDao.listAll(); } - + + @Override + public Account lockAccount(String accountName, Long domainId, Long id) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Account disableAccount(String accountName, Long domainId, Long id) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Account enableAccount(String accountName, Long domainId, Long id) { + // TODO Auto-generated method stub + return null; + } + } diff --git a/server/src/com/cloud/region/RegionVO.java b/server/src/com/cloud/region/RegionVO.java index 3a3efd5219f..483659470f1 100644 --- a/server/src/com/cloud/region/RegionVO.java +++ b/server/src/com/cloud/region/RegionVO.java @@ -34,17 +34,17 @@ public class RegionVO implements Region{ @Id @Column(name="id") - long id; + private long id; @Column(name="name") - String name; + private String name; @Column(name="end_point") - String endPoint; + private String endPoint; @Column(name="status") @Enumerated(value=EnumType.STRING) - Region.State status; + private Region.State status; @Column(name=GenericDao.REMOVED_COLUMN) private Date removed; diff --git a/server/src/com/cloud/user/AccountManager.java b/server/src/com/cloud/user/AccountManager.java index a7f5a68c83f..6904da7380d 100755 --- a/server/src/com/cloud/user/AccountManager.java +++ b/server/src/com/cloud/user/AccountManager.java @@ -45,7 +45,7 @@ public interface AccountManager extends AccountService { Long checkAccessAndSpecifyAuthority(Account caller, Long zoneId); - Account createAccount(String accountName, short accountType, Long domainId, String networkDomain, Map details); + Account createAccount(String accountName, short accountType, Long domainId, String networkDomain, Map details, String uuid, long regionId); UserVO createUser(long accountId, String userName, String password, String firstName, String lastName, String email, String timezone); diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java index cd63b4dd3cc..c174e5c6bad 100755 --- a/server/src/com/cloud/user/AccountManagerImpl.java +++ b/server/src/com/cloud/user/AccountManagerImpl.java @@ -85,6 +85,7 @@ import com.cloud.projects.ProjectManager; import com.cloud.projects.ProjectVO; import com.cloud.projects.dao.ProjectAccountDao; import com.cloud.projects.dao.ProjectDao; +import com.cloud.region.RegionManager; import com.cloud.server.auth.UserAuthenticator; import com.cloud.storage.StorageManager; import com.cloud.storage.VMTemplateVO; @@ -199,8 +200,8 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag private ProjectAccountDao _projectAccountDao; @Inject private IPAddressDao _ipAddressDao; - //@Inject - //private RegionManager _regionMgr; + @Inject + private RegionManager _regionMgr; private Adapters _userAuthenticators; @@ -678,7 +679,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag @DB @ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_CREATE, eventDescription = "creating Account") public UserAccount createUserAccount(String userName, String password, String firstName, String lastName, String email, String timezone, String accountName, short accountType, Long domainId, String networkDomain, - Map details) { + Map details, String accountUUID, String userUUID, Long regionId) { if (accountName == null) { accountName = userName; @@ -720,25 +721,51 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag } } - Transaction txn = Transaction.currentTxn(); - txn.start(); + if(regionId == null){ + Transaction txn = Transaction.currentTxn(); + txn.start(); - // create account - Account account = createAccount(accountName, accountType, domainId, networkDomain, details); - long accountId = account.getId(); + // create account + AccountVO account = createAccount(accountName, accountType, domainId, networkDomain, details, UUID.randomUUID().toString(), _regionMgr.getId()); + long accountId = account.getId(); - // create the first user for the account - UserVO user = createUser(accountId, userName, password, firstName, lastName, email, timezone); + // create the first user for the account + UserVO user = createUser(accountId, userName, password, firstName, lastName, email, timezone); - if (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) { - // set registration token - byte[] bytes = (domainId + accountName + userName + System.currentTimeMillis()).getBytes(); - String registrationToken = UUID.nameUUIDFromBytes(bytes).toString(); - user.setRegistrationToken(registrationToken); + if (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) { + // set registration token + byte[] bytes = (domainId + accountName + userName + System.currentTimeMillis()).getBytes(); + String registrationToken = UUID.nameUUIDFromBytes(bytes).toString(); + user.setRegistrationToken(registrationToken); + } + txn.commit(); + //Propogate Add account to other Regions + _regionMgr.propogateAddAccount(userName, password, firstName, lastName, email, timezone, accountName, accountType, domainId, + networkDomain, details, account.getUuid(), user.getUuid(), _regionMgr.getId()); + //check success + return _userAccountDao.findById(user.getId()); + } else { + // Account is propogated from another Region + + Transaction txn = Transaction.currentTxn(); + txn.start(); + + // create account + AccountVO account = createAccount(accountName, accountType, domainId, networkDomain, details, accountUUID, regionId); + long accountId = account.getId(); + + // create the first user for the account + UserVO user = createUser(accountId, userName, password, firstName, lastName, email, timezone, userUUID, regionId); + + if (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) { + // set registration token + byte[] bytes = (domainId + accountName + userName + System.currentTimeMillis()).getBytes(); + String registrationToken = UUID.nameUUIDFromBytes(bytes).toString(); + user.setRegistrationToken(registrationToken); + } + txn.commit(); + return _userAccountDao.findById(user.getId()); } - - txn.commit(); - return _userAccountDao.findById(user.getId()); } @Override @@ -1061,7 +1088,6 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag throw new InvalidParameterValueException("The account id=" + accountId + " manages project(s) with ids " + projectIds + "and can't be removed"); } - return deleteAccount(account, callerUserId, caller); } @@ -1161,7 +1187,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag String newAccountName = cmd.getNewName(); String networkDomain = cmd.getNetworkDomain(); Map details = cmd.getDetails(); - + boolean success = false; Account account = null; if (accountId != null) { @@ -1516,7 +1542,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag @Override @DB - public Account createAccount(String accountName, short accountType, Long domainId, String networkDomain, Map details) { + public AccountVO createAccount(String accountName, short accountType, Long domainId, String networkDomain, Map details, String uuid, long regionId) { // Validate domain Domain domain = _domainMgr.getDomain(domainId); if (domain == null) { @@ -1560,7 +1586,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag Transaction txn = Transaction.currentTxn(); txn.start(); - Account account = _accountDao.persist(new AccountVO(accountName, domainId, networkDomain, accountType)); + AccountVO account = _accountDao.persist(new AccountVO(accountName, domainId, networkDomain, accountType, uuid, regionId)); if (account == null) { throw new CloudRuntimeException("Failed to create account name " + accountName + " in domain id=" + domainId); @@ -1589,7 +1615,18 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag if (s_logger.isDebugEnabled()) { s_logger.debug("Creating user: " + userName + ", accountId: " + accountId + " timezone:" + timezone); } - UserVO user = _userDao.persist(new UserVO(accountId, userName, password, firstName, lastName, email, timezone)); + + UserVO user = _userDao.persist(new UserVO(accountId, userName, password, firstName, lastName, email, timezone, UUID.randomUUID().toString(), _regionMgr.getId())); + + return user; + } + + //ToDo Add events?? + public UserVO createUser(long accountId, String userName, String password, String firstName, String lastName, String email, String timezone, String uuid, long regionId) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Creating user: " + userName + ", accountId: " + accountId + " timezone:" + timezone); + } + UserVO user = _userDao.persist(new UserVO(accountId, userName, password, firstName, lastName, email, timezone, uuid, regionId)); return user; } diff --git a/server/src/com/cloud/user/dao/AccountDaoImpl.java b/server/src/com/cloud/user/dao/AccountDaoImpl.java index be14ec3e899..a7c399b8487 100755 --- a/server/src/com/cloud/user/dao/AccountDaoImpl.java +++ b/server/src/com/cloud/user/dao/AccountDaoImpl.java @@ -49,7 +49,6 @@ public class AccountDaoImpl extends GenericDaoBase implements A protected final SearchBuilder CleanupForRemovedAccountsSearch; protected final SearchBuilder CleanupForDisabledAccountsSearch; protected final SearchBuilder NonProjectAccountSearch; - private final long _regionId = 1; protected AccountDaoImpl() { AllFieldsSearch = createSearchBuilder(); @@ -260,10 +259,4 @@ public class AccountDaoImpl extends GenericDaoBase implements A } } - @Override - @DB - public AccountVO persist(AccountVO account) { - account.setRegionId(_regionId); - return super.persist(account); - } }