mirror of https://github.com/apache/cloudstack.git
bug 8270: Synchronize on 1) ipAddress object when create/delete ipForwarding/portForwardingRule and vpn service 2) on networkId when assignTo/removeFrom/deleteLoadBalancer
status 8270: resolved fixed
This commit is contained in:
parent
4c7fb08b33
commit
6f55c4dd7e
|
|
@ -29,10 +29,15 @@ import com.cloud.user.UserContext;
|
|||
* queryAsyncJobResult API command.
|
||||
*/
|
||||
public abstract class BaseAsyncCmd extends BaseCmd {
|
||||
private Object _job = null;
|
||||
public static final String ipAddressSyncObject = "ipaddress";
|
||||
public static final String networkSyncObject = "network";
|
||||
|
||||
|
||||
private AsyncJob job;
|
||||
|
||||
@Parameter(name="starteventid", type=CommandType.LONG)
|
||||
private Long startEventId;
|
||||
|
||||
|
||||
/**
|
||||
* For async commands the API framework needs to know the owner of the object being acted upon. This method is
|
||||
|
|
@ -64,12 +69,8 @@ public abstract class BaseAsyncCmd extends BaseCmd {
|
|||
return response;
|
||||
}
|
||||
|
||||
public void synchronizeCommand(String syncObjType, long syncObjId) {
|
||||
_responseGenerator.synchronizeCommand(_job, syncObjType, syncObjId);
|
||||
}
|
||||
|
||||
public void setJob(Object job) {
|
||||
_job = job;
|
||||
public void setJob(AsyncJob job) {
|
||||
this.job = job;
|
||||
}
|
||||
|
||||
public Long getStartEventId() {
|
||||
|
|
@ -85,7 +86,7 @@ public abstract class BaseAsyncCmd extends BaseCmd {
|
|||
* provide implementations of the two following methods, getInstanceId() and getInstanceType()
|
||||
*
|
||||
* getObjectId() should return the id of the object the async command is executing on
|
||||
* getObjectType() should return a type from the AsyncJobVO.Type enumeration
|
||||
* getObjectType() should return a type from the AsyncJob.Type enumeration
|
||||
*/
|
||||
public Long getInstanceId() {
|
||||
return null;
|
||||
|
|
@ -95,6 +96,18 @@ public abstract class BaseAsyncCmd extends BaseCmd {
|
|||
return AsyncJob.Type.None;
|
||||
}
|
||||
|
||||
public String getSyncObjType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Long getSyncObjId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public AsyncJob getJob() {
|
||||
return job;
|
||||
}
|
||||
|
||||
protected long saveStartedEvent(){
|
||||
return saveStartedEvent(getEventType(), "Executing job for "+getEventDescription(), getStartEventId());
|
||||
}
|
||||
|
|
@ -124,4 +137,6 @@ public abstract class BaseAsyncCmd extends BaseCmd {
|
|||
}
|
||||
return _mgr.saveCompletedEvent((userId == null) ? User.UID_SYSTEM : userId, getEntityOwnerId(), level, eventType, description, startEvent);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -145,8 +145,6 @@ public interface ResponseGenerator {
|
|||
|
||||
IpForwardingRuleResponse createIpForwardingRuleResponse(PortForwardingRule fwRule);
|
||||
|
||||
void synchronizeCommand(Object job, String syncObjType, Long syncObjId);
|
||||
|
||||
User findUserById(Long userId);
|
||||
|
||||
UserVm findUserVmById(Long vmId);
|
||||
|
|
|
|||
|
|
@ -99,4 +99,12 @@ public class AssignToLoadBalancerRuleCmd extends BaseAsyncCmd {
|
|||
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to assign load balancer rule");
|
||||
}
|
||||
}
|
||||
|
||||
public String getSyncObjType() {
|
||||
return this.networkSyncObject;
|
||||
}
|
||||
|
||||
public Long getSyncObjId() {
|
||||
return _lbService.findById(id).getNetworkId();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -171,5 +171,14 @@ public class AssociateIPAddrCmd extends BaseAsyncCreateCmd {
|
|||
s_logger.trace(ex);
|
||||
throw new ServerApiException(BaseCmd.INSUFFICIENT_CAPACITY_ERROR, ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String getSyncObjType() {
|
||||
return this.networkSyncObject;
|
||||
}
|
||||
|
||||
public Long getSyncObjId() {
|
||||
return getNetworkId();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -237,5 +237,15 @@ public class CreateIpForwardingRuleCmd extends BaseAsyncCreateCmd implements Por
|
|||
throw new InvalidParameterValueException("Ip address id=" + ipAddressId + " doesn't have 1-1 Nat feature enabled");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSyncObjType() {
|
||||
return this.ipAddressSyncObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getSyncObjId() {
|
||||
return ipAddressId;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -228,5 +228,15 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements
|
|||
public boolean isOneToOneNat() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSyncObjType() {
|
||||
return this.ipAddressSyncObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getSyncObjId() {
|
||||
return ipAddressId;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -150,5 +150,16 @@ public class CreateRemoteAccessVpnCmd extends BaseAsyncCreateCmd {
|
|||
s_logger.warn("Exception: ", ex);
|
||||
throw new ServerApiException(BaseCmd.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getSyncObjType() {
|
||||
return this.ipAddressSyncObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getSyncObjId() {
|
||||
return publicIpId;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,5 +99,15 @@ public class DeleteIpForwardingRuleCmd extends BaseAsyncCmd {
|
|||
public String getEventDescription() {
|
||||
return ("Deleting an ipforwarding 1:1 NAT rule id:"+id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSyncObjType() {
|
||||
return this.ipAddressSyncObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getSyncObjId() {
|
||||
return _rulesService.getPortForwardigRule(id).getSourceIpAddressId();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,4 +89,14 @@ public class DeleteLoadBalancerRuleCmd extends BaseAsyncCmd {
|
|||
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to delete load balancer");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSyncObjType() {
|
||||
return this.networkSyncObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getSyncObjId() {
|
||||
return _lbService.findById(id).getNetworkId();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,4 +90,15 @@ public class DeletePortForwardingRuleCmd extends BaseAsyncCmd {
|
|||
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to delete port forwarding rule");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getSyncObjType() {
|
||||
return this.ipAddressSyncObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getSyncObjId() {
|
||||
return _rulesService.getPortForwardigRule(id).getSourceIpAddressId();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,7 +77,17 @@ public class DeleteRemoteAccessVpnCmd extends BaseAsyncCmd {
|
|||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException {
|
||||
_ravService.destroyRemoteAccessVpn(publicIpId, getStartEventId());
|
||||
_ravService.destroyRemoteAccessVpn(publicIpId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSyncObjType() {
|
||||
return this.ipAddressSyncObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getSyncObjId() {
|
||||
return publicIpId;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,4 +84,15 @@ public class DisableStaticNat extends BaseAsyncCmd {
|
|||
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to disable static nat");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getSyncObjType() {
|
||||
return this.ipAddressSyncObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getSyncObjId() {
|
||||
return ipAddressId;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,4 +99,14 @@ public class RemoveFromLoadBalancerRuleCmd extends BaseAsyncCmd {
|
|||
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to remove instance from load balancer rule");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSyncObjType() {
|
||||
return this.networkSyncObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getSyncObjId() {
|
||||
return _lbService.findById(id).getNetworkId();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,4 +57,5 @@ public interface AsyncJob {
|
|||
String getSessionKey();
|
||||
String getCmdOriginator();
|
||||
boolean isFromPreviousSession();
|
||||
SyncQueueItem getSyncSource();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
package com.cloud.async;
|
||||
|
||||
public interface SyncQueueItem {
|
||||
|
||||
String getContentType();
|
||||
Long getContentId();
|
||||
|
||||
}
|
||||
|
|
@ -63,5 +63,7 @@ public interface LoadBalancingRulesService {
|
|||
List<? extends LoadBalancer> searchForLoadBalancers(ListLoadBalancerRulesCmd cmd);
|
||||
|
||||
List<LoadBalancingRule> listByNetworkId(long networkId);
|
||||
|
||||
LoadBalancer findById(long LoadBalancer);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,4 +61,6 @@ public interface RulesService {
|
|||
|
||||
List<PortForwardingRuleTO> buildPortForwardingTOrules(List<? extends PortForwardingRule> pfRules);
|
||||
|
||||
PortForwardingRule getPortForwardigRule(long ruleId);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ import com.cloud.network.VpnUser;
|
|||
public interface RemoteAccessVpnService {
|
||||
|
||||
RemoteAccessVpn createRemoteAccessVpn(long vpnServerAddressId, String ipRange) throws NetworkRuleConflictException;
|
||||
void destroyRemoteAccessVpn(long vpnServerAddressId, long startEventId) throws ResourceUnavailableException;
|
||||
void destroyRemoteAccessVpn(long vpnServerAddressId) throws ResourceUnavailableException;
|
||||
RemoteAccessVpn startRemoteAccessVpn(long vpnServerAddressId) throws ResourceUnavailableException;
|
||||
|
||||
VpnUser addVpnUser(long vpnOwnerId, String userName, String password);
|
||||
|
|
|
|||
|
|
@ -333,7 +333,8 @@ public class AsyncJobVO implements AsyncJob {
|
|||
public void setCmdOriginator(String cmdOriginator) {
|
||||
this.cmdOriginator = cmdOriginator;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SyncQueueItemVO getSyncSource() {
|
||||
return syncSource;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import javax.persistence.Table;
|
|||
|
||||
@Entity
|
||||
@Table(name="sync_queue_item")
|
||||
public class SyncQueueItemVO {
|
||||
public class SyncQueueItemVO implements SyncQueueItem{
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy=GenerationType.IDENTITY)
|
||||
|
|
@ -69,7 +69,8 @@ public class SyncQueueItemVO {
|
|||
public void setQueueId(Long queueId) {
|
||||
this.queueId = queueId;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
|
@ -77,7 +78,8 @@ public class SyncQueueItemVO {
|
|||
public void setContentType(String contentType) {
|
||||
this.contentType = contentType;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Long getContentId() {
|
||||
return contentId;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ import com.cloud.host.dao.HostDao;
|
|||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.network.IPAddressVO;
|
||||
import com.cloud.network.LoadBalancerVO;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.Network.Capability;
|
||||
import com.cloud.network.Network.Service;
|
||||
import com.cloud.network.NetworkManager;
|
||||
|
|
@ -88,10 +87,8 @@ import com.cloud.user.dao.UserStatisticsDao;
|
|||
import com.cloud.uservm.UserVm;
|
||||
import com.cloud.utils.DateUtil;
|
||||
import com.cloud.utils.component.ComponentLocator;
|
||||
import com.cloud.utils.net.Ip;
|
||||
import com.cloud.vm.DomainRouterVO;
|
||||
import com.cloud.vm.InstanceGroupVO;
|
||||
import com.cloud.vm.Nic;
|
||||
import com.cloud.vm.NicProfile;
|
||||
import com.cloud.vm.UserVmManager;
|
||||
import com.cloud.vm.UserVmVO;
|
||||
|
|
@ -502,10 +499,6 @@ public class ApiDBUtils {
|
|||
return _networkMgr.getNetworkProfile(networkId);
|
||||
}
|
||||
|
||||
public static void synchronizeCommand(Object job, String syncObjType, long syncObjId) {
|
||||
_asyncMgr.syncAsyncJobExecution((AsyncJobVO)job, syncObjType, syncObjId);
|
||||
}
|
||||
|
||||
public static NetworkOfferingVO findNetworkOfferingById(long networkOfferingId) {
|
||||
return _networkOfferingDao.findByIdIncludingRemoved(networkOfferingId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import org.apache.log4j.Logger;
|
|||
|
||||
import com.cloud.api.BaseCmd.CommandType;
|
||||
import com.cloud.async.AsyncCommandQueued;
|
||||
import com.cloud.event.EventVO;
|
||||
import com.cloud.async.AsyncJobManager;
|
||||
import com.cloud.exception.AccountLimitException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
|
|
@ -49,7 +49,8 @@ import com.cloud.utils.exception.CloudRuntimeException;
|
|||
public class ApiDispatcher {
|
||||
private static final Logger s_logger = Logger.getLogger(ApiDispatcher.class.getName());
|
||||
|
||||
ComponentLocator _locator = null;
|
||||
ComponentLocator _locator;
|
||||
AsyncJobManager _asyncMgr;
|
||||
|
||||
// singleton class
|
||||
private static ApiDispatcher s_instance = new ApiDispatcher();
|
||||
|
|
@ -60,6 +61,7 @@ public class ApiDispatcher {
|
|||
|
||||
private ApiDispatcher() {
|
||||
_locator = ComponentLocator.getLocator(ManagementServer.Name);
|
||||
_asyncMgr = _locator.getManager(AsyncJobManager.class);
|
||||
}
|
||||
|
||||
public void dispatchCreateCmd(BaseAsyncCreateCmd cmd, Map<String, String> params) {
|
||||
|
|
@ -128,8 +130,15 @@ public class ApiDispatcher {
|
|||
ctx.setAccountId(asyncCmd.getEntityOwnerId());
|
||||
String startEventId = params.get("ctxStartEventId");
|
||||
ctx.setStartEventId(Long.valueOf(startEventId));
|
||||
|
||||
//Synchronise job on the object if needed
|
||||
if (asyncCmd.getJob() != null && asyncCmd.getSyncObjId() != null && asyncCmd.getSyncObjType() != null) {
|
||||
_asyncMgr.syncAsyncJobExecution(asyncCmd.getJob(), asyncCmd.getSyncObjType(), asyncCmd.getSyncObjId().longValue());
|
||||
}
|
||||
}
|
||||
|
||||
cmd.execute();
|
||||
|
||||
} catch (Throwable t) {
|
||||
if (t instanceof InvalidParameterValueException || t instanceof IllegalArgumentException) {
|
||||
s_logger.info(t.getMessage());
|
||||
|
|
|
|||
|
|
@ -1261,11 +1261,6 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||
return vmResponse;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void synchronizeCommand(Object job, String syncObjType, Long syncObjId) {
|
||||
ApiDBUtils.synchronizeCommand(job, syncObjType, syncObjId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User findUserById(Long userId) {
|
||||
return ApiDBUtils.findUserById(userId);
|
||||
|
|
|
|||
|
|
@ -416,7 +416,7 @@ public class ApiServer implements HttpRequestHandler {
|
|||
}
|
||||
job.setCmd(cmdObj.getClass().getName());
|
||||
job.setCmdInfo(ApiGsonHelper.getBuilder().create().toJson(params));
|
||||
|
||||
|
||||
long jobId = _asyncMgr.submitAsyncJob(job);
|
||||
|
||||
if (jobId == 0L) {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@ import com.cloud.exception.InvalidParameterValueException;
|
|||
import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.utils.component.Manager;
|
||||
|
||||
public interface AsyncJobManager extends Manager {
|
||||
public interface AsyncJobManager extends Manager {
|
||||
|
||||
public AsyncJobExecutorContext getExecutorContext();
|
||||
|
||||
public AsyncJobVO getAsyncJob(long jobId);
|
||||
|
|
@ -39,10 +40,11 @@ public interface AsyncJobManager extends Manager {
|
|||
public void completeAsyncJob(long jobId, int jobStatus, int resultCode, Object resultObject);
|
||||
public void updateAsyncJobStatus(long jobId, int processStatus, Object resultObject);
|
||||
public void updateAsyncJobAttachment(long jobId, String instanceType, Long instanceId);
|
||||
|
||||
public void syncAsyncJobExecution(AsyncJobVO job, String syncObjType, long syncObjId);
|
||||
|
||||
public void releaseSyncSource(AsyncJobExecutor executor);
|
||||
|
||||
public void syncAsyncJobExecution(AsyncJob job, String syncObjType, long syncObjId);
|
||||
|
||||
/**
|
||||
* Queries for the status or final result of an async job.
|
||||
* @param cmd the command that specifies the job id
|
||||
|
|
|
|||
|
|
@ -233,7 +233,7 @@ public class AsyncJobManagerImpl implements AsyncJobManager, ClusterManagerListe
|
|||
}
|
||||
|
||||
@Override
|
||||
public void syncAsyncJobExecution(AsyncJobVO job, String syncObjType, long syncObjId) {
|
||||
public void syncAsyncJobExecution(AsyncJob job, String syncObjType, long syncObjId) {
|
||||
// This method is re-entrant. If an API developer wants to synchronized on an object, e.g. the router,
|
||||
// when executing business logic, they will call this method (actually a method in BaseAsyncCmd that calls this).
|
||||
// This method will get called every time their business logic executes. The first time it exectues for a job
|
||||
|
|
|
|||
|
|
@ -1378,5 +1378,10 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesManager,
|
|||
}
|
||||
return lbRules;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoadBalancerVO findById(long lbId) {
|
||||
return _lbDao.findById(lbId);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -700,5 +700,9 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PortForwardingRule getPortForwardigRule(long ruleId) {
|
||||
return _forwardingDao.findById(ruleId);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
|
|||
}
|
||||
|
||||
@Override @DB
|
||||
public void destroyRemoteAccessVpn(long ipId, long startEventId) throws ResourceUnavailableException {
|
||||
public void destroyRemoteAccessVpn(long ipId) throws ResourceUnavailableException {
|
||||
Account caller = UserContext.current().getCaller();
|
||||
|
||||
RemoteAccessVpnVO vpn = _remoteAccessVpnDao.findById(ipId);
|
||||
|
|
|
|||
Loading…
Reference in New Issue