diff --git a/api/src/com/cloud/api/commands/ListPrivateGatewaysCmd.java b/api/src/com/cloud/api/commands/ListPrivateGatewaysCmd.java index bc4cc1f7cfa..32767ca803f 100644 --- a/api/src/com/cloud/api/commands/ListPrivateGatewaysCmd.java +++ b/api/src/com/cloud/api/commands/ListPrivateGatewaysCmd.java @@ -49,6 +49,9 @@ public class ListPrivateGatewaysCmd extends BaseListProjectAndAccountResourcesCm @Parameter(name=ApiConstants.VPC_ID, type=CommandType.LONG, description="list gateways by vpc") private Long vpcId; + @Parameter(name=ApiConstants.STATE, type=CommandType.STRING, description="list gateways by state") + private String state; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -69,6 +72,10 @@ public class ListPrivateGatewaysCmd extends BaseListProjectAndAccountResourcesCm public Long getId() { return id; } + + public String getState() { + return state; + } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// diff --git a/api/src/com/cloud/api/response/PrivateGatewayResponse.java b/api/src/com/cloud/api/response/PrivateGatewayResponse.java index c94b5895a5e..fccc7c4122d 100644 --- a/api/src/com/cloud/api/response/PrivateGatewayResponse.java +++ b/api/src/com/cloud/api/response/PrivateGatewayResponse.java @@ -64,6 +64,9 @@ public class PrivateGatewayResponse extends BaseResponse implements ControlledEn @Param(description = "the domain associated with the private gateway") private String domainName; + @SerializedName(ApiConstants.STATE) @Param(description="State of the gateway, can be Creating, Ready, Deleting") + private String state; + public void setId(Long id) { this.id.setValue(id); @@ -125,5 +128,9 @@ public class PrivateGatewayResponse extends BaseResponse implements ControlledEn public void setProjectName(String projectName) { this.projectName = projectName; } + + public void setState(String state) { + this.state = state; + } } diff --git a/api/src/com/cloud/network/vpc/VpcGateway.java b/api/src/com/cloud/network/vpc/VpcGateway.java index 30e613cf6cf..a437cbe7f11 100644 --- a/api/src/com/cloud/network/vpc/VpcGateway.java +++ b/api/src/com/cloud/network/vpc/VpcGateway.java @@ -22,6 +22,12 @@ public interface VpcGateway extends Identity, ControlledEntity { Vpn } + public enum State { + Creating, + Ready, + Deleting + } + long getId(); /** @@ -63,4 +69,9 @@ public interface VpcGateway extends Identity, ControlledEntity { * @return */ String getVlanTag(); + + /** + * @return + */ + State getState(); } diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index a97f9bfd98d..b64b528a9e7 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -3736,6 +3736,7 @@ public class ApiResponseHelper implements ResponseGenerator { populateAccount(response, result.getAccountId()); populateDomain(response, result.getDomainId()); + response.setState(result.getState().toString()); response.setObjectName("privategateway"); diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index ec7433381cc..544ca73ee3c 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -1240,7 +1240,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian Network network = _networkDao.acquireInLockTable(guestNetwork.getId()); if (network == null) { throw new ConcurrentOperationException("Unable to lock network " + guestNetwork.getId()); - } + } try { //Check if providers are supported in the physical networks diff --git a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java index 541fc61099d..9751a188405 100644 --- a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java @@ -823,6 +823,7 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian createVpcAssociatePublicIPCommands(router, sourceNat, cmds); } + //add VPC router to guest networks for (Nic nic : guestNics.keySet()) { //plug guest nic PlugNicCommand plugNicCmd = new PlugNicCommand(_itMgr.toVmTO(profile), getNicTO(router, nic.getNetworkId())); diff --git a/server/src/com/cloud/network/vpc/PrivateGatewayProfile.java b/server/src/com/cloud/network/vpc/PrivateGatewayProfile.java index b98c5ae8c19..0959b04f1ef 100644 --- a/server/src/com/cloud/network/vpc/PrivateGatewayProfile.java +++ b/server/src/com/cloud/network/vpc/PrivateGatewayProfile.java @@ -91,4 +91,9 @@ public class PrivateGatewayProfile implements PrivateGateway{ public long getDomainId() { return vpcGateway.getDomainId(); } + + @Override + public State getState() { + return vpcGateway.getState(); + } } diff --git a/server/src/com/cloud/network/vpc/VpcGatewayVO.java b/server/src/com/cloud/network/vpc/VpcGatewayVO.java index 320984daf32..59f754dd362 100644 --- a/server/src/com/cloud/network/vpc/VpcGatewayVO.java +++ b/server/src/com/cloud/network/vpc/VpcGatewayVO.java @@ -76,6 +76,10 @@ public class VpcGatewayVO implements VpcGateway{ @Column(name = "domain_id") long domainId; + @Column(name="state") + @Enumerated(value=EnumType.STRING) + State state; + protected VpcGatewayVO(){ this.uuid = UUID.randomUUID().toString(); } @@ -106,6 +110,7 @@ public class VpcGatewayVO implements VpcGateway{ this.uuid = UUID.randomUUID().toString(); this.accountId = accountId; this.domainId = domainId; + this.state = State.Creating; } @Override @@ -174,4 +179,13 @@ public class VpcGatewayVO implements VpcGateway{ public long getDomainId() { return domainId; } + + @Override + public State getState() { + return state; + } + + public void setState(State state) { + this.state = state; + } } diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java index 8f5db9a8191..43a8ab4a498 100644 --- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java @@ -1132,43 +1132,71 @@ public class VpcManagerImpl implements VpcManager, Manager{ @Override + @DB public PrivateGateway applyVpcPrivateGateway(Long gatewayId) throws ConcurrentOperationException, ResourceUnavailableException { - PrivateGateway gateway = getVpcPrivateGateway(gatewayId); - if (getVpcElement().createPrivateGateway(gateway)) { - s_logger.debug("Private gateway " + gateway + " was applied succesfully on the backend"); - return gateway; - } else { - s_logger.warn("Private gateway " + gateway + " failed to apply on the backend"); - return null; + VpcGatewayVO vo = _vpcGatewayDao.acquireInLockTable(gatewayId); + if (vo == null) { + throw new ConcurrentOperationException("Unable to lock gateway " + gatewayId); + } + + try { + PrivateGateway gateway = getVpcPrivateGateway(gatewayId); + if (getVpcElement().createPrivateGateway(gateway)) { + s_logger.debug("Private gateway " + gateway + " was applied succesfully on the backend"); + if (vo.getState() != VpcGateway.State.Ready) { + vo.setState(VpcGateway.State.Ready); + _vpcGatewayDao.update(vo.getId(), vo); + s_logger.debug("Marke gateway " + gateway + " with state " + VpcGateway.State.Ready); + } + return getVpcPrivateGateway(gatewayId); + } else { + s_logger.warn("Private gateway " + gateway + " failed to apply on the backend"); + return null; + } + } finally { + if (vo != null) { + _vpcGatewayDao.releaseFromLockTable(gatewayId); + } } } @Override @ActionEvent(eventType = EventTypes.EVENT_PRIVATE_GATEWAY_DELETE, eventDescription = "deleting private gateway") + @DB public boolean deleteVpcPrivateGateway(Long gatewayId) throws ConcurrentOperationException, ResourceUnavailableException { - VpcGatewayVO gatewayVO = _vpcGatewayDao.findById(gatewayId); + VpcGatewayVO gatewayVO = _vpcGatewayDao.acquireInLockTable(gatewayId); if (gatewayVO == null || gatewayVO.getType() != VpcGateway.Type.Private) { - throw new InvalidParameterValueException("Can't find private gateway by id specified"); + throw new ConcurrentOperationException("Unable to lock gateway " + gatewayId); } - //don't allow to remove gateway when there are static routes associated with it - long routeCount = _staticRouteDao.countRoutesByGateway(gatewayVO.getId()); - if (routeCount > 0) { - throw new CloudRuntimeException("Can't delete private gateway " + gatewayVO + " as it has " + routeCount + - " static routes applied. Remove the routes first"); - } - - //1) delete the gateway on the backend - PrivateGateway gateway = getVpcPrivateGateway(gatewayId); - if (getVpcElement().deletePrivateGateway(gateway)) { - s_logger.debug("Private gateway " + gateway + " was applied succesfully on the backend"); - } else { - s_logger.warn("Private gateway " + gateway + " failed to apply on the backend"); - return false; - } - - //2) Delete private gateway from the DB - return deletePrivateGatewayFromTheDB(gateway); + try { + gatewayVO.setState(VpcGateway.State.Deleting); + _vpcGatewayDao.update(gatewayVO.getId(), gatewayVO); + s_logger.debug("Marked gateway " + gatewayVO + " with state " + VpcGateway.State.Deleting); + //don't allow to remove gateway when there are static routes associated with it + long routeCount = _staticRouteDao.countRoutesByGateway(gatewayVO.getId()); + if (routeCount > 0) { + throw new CloudRuntimeException("Can't delete private gateway " + gatewayVO + " as it has " + routeCount + + " static routes applied. Remove the routes first"); + } + + //1) delete the gateway on the backend + PrivateGateway gateway = getVpcPrivateGateway(gatewayId); + if (getVpcElement().deletePrivateGateway(gateway)) { + s_logger.debug("Private gateway " + gateway + " was applied succesfully on the backend"); + } else { + s_logger.warn("Private gateway " + gateway + " failed to apply on the backend"); + return false; + } + + //2) Delete private gateway from the DB + return deletePrivateGatewayFromTheDB(gateway); + + } finally { + if (gatewayVO != null) { + _vpcGatewayDao.releaseFromLockTable(gatewayId); + } + } } @DB @@ -1219,6 +1247,7 @@ public class VpcManagerImpl implements VpcManager, Manager{ String accountName = cmd.getAccountName(); Account caller = UserContext.current().getCaller(); List permittedAccounts = new ArrayList(); + String state = cmd.getState(); Filter searchFilter = new Filter(VpcGatewayVO.class, "id", false, cmd.getStartIndex(), cmd.getPageSizeVal()); Ternary domainIdRecursiveListProject = new Ternary