From c75b0044efe40bbbaff7da8857a9d534661df5be Mon Sep 17 00:00:00 2001 From: Kelven Yang Date: Tue, 7 Jan 2014 17:11:48 -0800 Subject: [PATCH] CLOUDSTACK-5765: cleanup internal serialization and exception propagation issues --- .../com/cloud/deploy/DeployDestination.java | 21 ++++---- .../com/cloud/deploy/DeploymentPlanner.java | 5 +- .../com/cloud/exception/CloudException.java | 9 ++-- .../exception/OperationTimedoutException.java | 24 ++++++--- .../com/cloud/vm/VirtualMachineManager.java | 24 +++++---- .../com/cloud/vm/VmWorkJobHandlerProxy.java | 11 ++-- .../cloud/vm/VirtualMachineManagerImpl.java | 42 ++++++++------- .../src/com/cloud/vm/VmWorkJobDispatcher.java | 6 +-- .../src/com/cloud/vm/VmWorkReconfigure.java | 23 ++++---- .../com/cloud/service/ServiceOfferingVO.java | 48 ++++++++++------- .../cloud/storage/VolumeApiServiceImpl.java | 2 +- .../vm/snapshot/VMSnapshotManagerImpl.java | 2 +- .../exception/CloudRuntimeException.java | 52 +++++++++++++++++-- .../utils/exception/ExceptionProxyObject.java | 18 ++++--- 14 files changed, 180 insertions(+), 107 deletions(-) diff --git a/api/src/com/cloud/deploy/DeployDestination.java b/api/src/com/cloud/deploy/DeployDestination.java index e00d3c6afd6..6b6e5e877cb 100644 --- a/api/src/com/cloud/deploy/DeployDestination.java +++ b/api/src/com/cloud/deploy/DeployDestination.java @@ -16,6 +16,7 @@ // under the License. package com.cloud.deploy; +import java.io.Serializable; import java.util.Map; import com.cloud.dc.DataCenter; @@ -26,7 +27,9 @@ import com.cloud.storage.StoragePool; import com.cloud.storage.Volume; import com.cloud.utils.NumbersUtil; -public class DeployDestination { +public class DeployDestination implements Serializable { + private static final long serialVersionUID = 7113840781939014695L; + DataCenter _dc; Pod _pod; Cluster _cluster; @@ -76,28 +79,28 @@ public class DeployDestination { @Override public boolean equals(Object obj) { DeployDestination that = (DeployDestination) obj; - if (this._dc == null || that._dc == null) { + if (_dc == null || that._dc == null) { return false; } - if (this._dc.getId() != that._dc.getId()) { + if (_dc.getId() != that._dc.getId()) { return false; } - if (this._pod == null || that._pod == null) { + if (_pod == null || that._pod == null) { return false; } - if (this._pod.getId() != that._pod.getId()) { + if (_pod.getId() != that._pod.getId()) { return false; } - if (this._cluster == null || that._cluster == null) { + if (_cluster == null || that._cluster == null) { return false; } - if (this._cluster.getId() != that._cluster.getId()) { + if (_cluster.getId() != that._cluster.getId()) { return false; } - if (this._host == null || that._host == null) { + if (_host == null || that._host == null) { return false; } - return this._host.getId() == that._host.getId(); + return _host.getId() == that._host.getId(); } @Override diff --git a/api/src/com/cloud/deploy/DeploymentPlanner.java b/api/src/com/cloud/deploy/DeploymentPlanner.java index 88cfc74ca29..5dcaacfe8bf 100644 --- a/api/src/com/cloud/deploy/DeploymentPlanner.java +++ b/api/src/com/cloud/deploy/DeploymentPlanner.java @@ -16,6 +16,7 @@ // under the License. package com.cloud.deploy; +import java.io.Serializable; import java.util.Collection; import java.util.HashSet; import java.util.Set; @@ -93,7 +94,9 @@ public interface DeploymentPlanner extends Adapter { Shared, Dedicated; } - public static class ExcludeList { + public static class ExcludeList implements Serializable { + private static final long serialVersionUID = -482175549460148301L; + private Set _dcIds; private Set _podIds; private Set _clusterIds; diff --git a/api/src/com/cloud/exception/CloudException.java b/api/src/com/cloud/exception/CloudException.java index 0b71ce89a92..06bda423405 100644 --- a/api/src/com/cloud/exception/CloudException.java +++ b/api/src/com/cloud/exception/CloudException.java @@ -27,8 +27,9 @@ import com.cloud.utils.exception.CSExceptionErrorCode; */ public class CloudException extends Exception { + private static final long serialVersionUID = 8784427323859682503L; - // This holds a list of uuids and their names. Add uuid:fieldname pairs + // This holds a list of uuids and their names. Add uuid:fieldname pairs protected ArrayList idList = new ArrayList(); protected Integer csErrorCode; @@ -43,8 +44,6 @@ public class CloudException extends Exception { setCSErrorCode(CSExceptionErrorCode.getCSErrCode(this.getClass().getName())); } - - public CloudException() { super(); setCSErrorCode(CSExceptionErrorCode.getCSErrCode(this.getClass().getName())); @@ -60,10 +59,10 @@ public class CloudException extends Exception { } public void setCSErrorCode(int cserrcode) { - this.csErrorCode = cserrcode; + csErrorCode = cserrcode; } public int getCSErrorCode() { - return this.csErrorCode; + return csErrorCode; } } diff --git a/api/src/com/cloud/exception/OperationTimedoutException.java b/api/src/com/cloud/exception/OperationTimedoutException.java index 2eeec3780aa..c4a2b9ce2ac 100644 --- a/api/src/com/cloud/exception/OperationTimedoutException.java +++ b/api/src/com/cloud/exception/OperationTimedoutException.java @@ -24,13 +24,21 @@ import com.cloud.utils.SerialVersionUID; */ public class OperationTimedoutException extends CloudException { private static final long serialVersionUID = SerialVersionUID.OperationTimedoutException; - + long _agentId; long _seqId; int _time; - Command[] _cmds; + + // TODO + // I did a reference search on usage of getCommands() and found none + // + // to prevent serialization problems across boundaries, I'm disabling serialization of _cmds here + // getCommands() will still be available within the same serialization boundary, but it will be lost + // when exception is propagated across job boundaries. + // + transient Command[] _cmds; boolean _isActive; - + public OperationTimedoutException(Command[] cmds, long agentId, long seqId, int time, boolean isActive) { super("Commands " + seqId + " to Host " + agentId + " timed out after " + time); _agentId = agentId; @@ -39,23 +47,23 @@ public class OperationTimedoutException extends CloudException { _cmds = cmds; _isActive = isActive; } - + public long getAgentId() { return _agentId; } - + public long getSequenceId() { return _seqId; } - + public int getWaitTime() { return _time; } - + public Command[] getCommands() { return _cmds; } - + public boolean isActive() { return _isActive; } diff --git a/engine/api/src/com/cloud/vm/VirtualMachineManager.java b/engine/api/src/com/cloud/vm/VirtualMachineManager.java index 203a4ac9779..5e57b85db6e 100644 --- a/engine/api/src/com/cloud/vm/VirtualMachineManager.java +++ b/engine/api/src/com/cloud/vm/VirtualMachineManager.java @@ -20,6 +20,8 @@ import java.net.URI; import java.util.LinkedHashMap; import java.util.Map; +import org.apache.cloudstack.framework.config.ConfigKey; + import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.deploy.DeployDestination; @@ -41,7 +43,6 @@ import com.cloud.template.VirtualMachineTemplate; import com.cloud.utils.Pair; import com.cloud.utils.component.Manager; import com.cloud.utils.fsm.NoTransitionException; -import org.apache.cloudstack.framework.config.ConfigKey; /** * Manages allocating resources to vms. @@ -56,12 +57,12 @@ public interface VirtualMachineManager extends Manager { public interface Topics { public static final String VM_POWER_STATE = "vm.powerstate"; } - + /** * Allocates a new virtual machine instance in the CloudStack DB. This * orchestrates the creation of all virtual resources needed in CloudStack * DB to bring up a VM. - * + * * @param vmInstanceName Instance name of the VM. This name uniquely * a VM in CloudStack's deploy environment. The caller gets to * define this VM but it must be unqiue for all of CloudStack. @@ -121,9 +122,9 @@ public interface VirtualMachineManager extends Manager { void migrateAway(String vmUuid, long hostId, DeploymentPlanner planner) throws InsufficientServerCapacityException; void migrate(String vmUuid, long srcHostId, DeployDestination dest) throws ResourceUnavailableException, ConcurrentOperationException; - + void migrateWithStorage(String vmUuid, long srcId, long destId, Map volumeToPool) throws ResourceUnavailableException, ConcurrentOperationException; - + void reboot(String vmUuid, Map params) throws InsufficientCapacityException, ResourceUnavailableException; void advanceReboot(String vmUuid, Map params) throws InsufficientCapacityException, ResourceUnavailableException, @@ -131,13 +132,13 @@ public interface VirtualMachineManager extends Manager { /** * Check to see if a virtual machine can be upgraded to the given service offering - * + * * @param vm * @param offering * @return true if the host can handle the upgrade, false otherwise */ boolean isVirtualMachineUpgradable(final VirtualMachine vm, final ServiceOffering offering); - + VirtualMachine findById(long vmId); void storageMigration(String vmUuid, StoragePool storagePoolId); @@ -166,7 +167,7 @@ public interface VirtualMachineManager extends Manager { */ NicProfile addVmToNetwork(VirtualMachine vm, Network network, NicProfile requested) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; - + /** * @param vm * @param nic @@ -185,7 +186,7 @@ public interface VirtualMachineManager extends Manager { * @throws ConcurrentOperationException */ boolean removeVmFromNetwork(VirtualMachine vm, Network network, URI broadcastUri) throws ConcurrentOperationException, ResourceUnavailableException; - + /** * @param nic * @param hypervisorType @@ -200,8 +201,9 @@ public interface VirtualMachineManager extends Manager { */ VirtualMachineTO toVmTO(VirtualMachineProfile profile); - VirtualMachine reConfigureVm(String vmUuid, ServiceOffering newServiceOffering, boolean sameHost) throws ResourceUnavailableException, ConcurrentOperationException; - + VirtualMachine reConfigureVm(String vmUuid, ServiceOffering newServiceOffering, boolean sameHost) throws ResourceUnavailableException, ConcurrentOperationException, + InsufficientServerCapacityException; + void findHostAndMigrate(String vmUuid, Long newSvcOfferingId, DeploymentPlanner.ExcludeList excludeHostList) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException; diff --git a/engine/components-api/src/com/cloud/vm/VmWorkJobHandlerProxy.java b/engine/components-api/src/com/cloud/vm/VmWorkJobHandlerProxy.java index dfc551d77f5..ce10a83c7cd 100644 --- a/engine/components-api/src/com/cloud/vm/VmWorkJobHandlerProxy.java +++ b/engine/components-api/src/com/cloud/vm/VmWorkJobHandlerProxy.java @@ -116,19 +116,18 @@ public class VmWorkJobHandlerProxy implements VmWorkJobHandler { // legacy CloudStack code relies on checked exception for error handling // we need to re-throw the real exception here - if (e.getCause() != null && e.getCause() instanceof Exception) + if (e.getCause() != null && e.getCause() instanceof Exception) { + s_logger.info("Rethrow exception " + e.getCause()); throw (Exception)e.getCause(); + } throw e; } } else { s_logger.error("Unable to find handler for VM work job: " + work.getClass().getName() + _gsonLogger.toJson(work)); - RuntimeException e = new RuntimeException("Unsupported VM work job: " + work.getClass().getName() + _gsonLogger.toJson(work)); - String exceptionJson = JobSerializerHelper.toSerializedString(e); - - s_logger.error("Serialize exception object into json: " + exceptionJson); - return new Pair(JobInfo.Status.FAILED, exceptionJson); + RuntimeException ex = new RuntimeException("Unable to find handler for VM work job: " + work.getClass().getName()); + return new Pair(JobInfo.Status.FAILED, JobSerializerHelper.toObjectSerializedString(ex)); } } } diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java index d069c018f6b..f959b935c4e 100755 --- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -40,7 +40,6 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; import org.apache.log4j.Logger; import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao; @@ -48,6 +47,7 @@ import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; import org.apache.cloudstack.framework.config.ConfigDepot; import org.apache.cloudstack.framework.config.ConfigKey; @@ -336,7 +336,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac // TODO, remove it after transient period is over static final ConfigKey VmJobEnabled = new ConfigKey("Advanced", - Boolean.class, "vm.job.enabled", "true", + Boolean.class, "vm.job.enabled", "false", "True to enable new VM sync model. false to use the old way", false); static final ConfigKey VmJobCheckInterval = new ConfigKey("Advanced", @@ -3698,7 +3698,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac @Override public VMInstanceVO reConfigureVm(String vmUuid, ServiceOffering oldServiceOffering, boolean reconfiguringOnExistingHost) - throws ResourceUnavailableException, ConcurrentOperationException { + throws ResourceUnavailableException, InsufficientServerCapacityException, ConcurrentOperationException { AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (!VmJobEnabled.value() || jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) { @@ -3716,20 +3716,21 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac throw new RuntimeException("Execution excetion", e); } - AsyncJobVO jobVo = _entityMgr.findById(AsyncJobVO.class, outcome.getJob().getId()); - if(jobVo.getResultCode() == JobInfo.Status.SUCCEEDED.ordinal()) { - return _entityMgr.findById(VMInstanceVO.class, vm.getId()); - } else { - Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob()); - if (jobResult != null) { - if (jobResult instanceof ResourceUnavailableException) - throw (ResourceUnavailableException)jobResult; - else if (jobResult instanceof ConcurrentOperationException) - throw (ConcurrentOperationException)jobResult; - } + Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob()); + if (jobResult != null) { + if (jobResult instanceof ResourceUnavailableException) + throw (ResourceUnavailableException)jobResult; + else if (jobResult instanceof ConcurrentOperationException) + throw (ConcurrentOperationException)jobResult; + else if (jobResult instanceof InsufficientServerCapacityException) + throw (InsufficientServerCapacityException)jobResult; + else if (jobResult instanceof Throwable) { + s_logger.error("Unhandled exception", (Throwable)jobResult); + throw new RuntimeException("Unhandled exception", (Throwable)jobResult); + } + } - throw new RuntimeException("Failed with un-handled exception"); - } + return (VMInstanceVO)vm; } } @@ -4668,7 +4669,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } public Outcome reconfigureVmThroughJobQueue( - final String vmUuid, final ServiceOffering oldServiceOffering, final boolean reconfiguringOnExistingHost) { + final String vmUuid, final ServiceOffering newServiceOffering, final boolean reconfiguringOnExistingHost) { final CallContext context = CallContext.current(); final User user = context.getCallingUser(); @@ -4705,7 +4706,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac // save work context info (there are some duplications) VmWorkReconfigure workInfo = new VmWorkReconfigure(user.getId(), account.getId(), vm.getId(), - VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, oldServiceOffering, reconfiguringOnExistingHost); + VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, newServiceOffering.getId(), reconfiguringOnExistingHost); workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo)); _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); @@ -4833,7 +4834,10 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac s_logger.info("Unable to find vm " + work.getVmId()); } assert (vm != null); - reConfigureVm(vm.getUuid(), work.getNewServiceOffering(), + + ServiceOffering newServiceOffering = _offeringDao.findById(vm.getId(), work.getNewServiceOfferingId()); + + reConfigureVm(vm.getUuid(), newServiceOffering, work.isSameHost()); return new Pair(JobInfo.Status.SUCCEEDED, null); } diff --git a/engine/orchestration/src/com/cloud/vm/VmWorkJobDispatcher.java b/engine/orchestration/src/com/cloud/vm/VmWorkJobDispatcher.java index 3cce1e6bcf8..bea09b19888 100644 --- a/engine/orchestration/src/com/cloud/vm/VmWorkJobDispatcher.java +++ b/engine/orchestration/src/com/cloud/vm/VmWorkJobDispatcher.java @@ -26,7 +26,6 @@ import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.framework.jobs.AsyncJob; import org.apache.cloudstack.framework.jobs.AsyncJobDispatcher; import org.apache.cloudstack.framework.jobs.AsyncJobManager; -import org.apache.cloudstack.framework.jobs.impl.JobSerializerHelper; import org.apache.cloudstack.jobs.JobInfo; import com.cloud.utils.Pair; @@ -104,9 +103,8 @@ public class VmWorkJobDispatcher extends AdapterBase implements AsyncJobDispatch } catch(Throwable e) { s_logger.error("Unable to complete " + job + ", job origin:" + job.getRelated(), e); - String exceptionJson = JobSerializerHelper.toSerializedString(e); - s_logger.info("Serialize exception object into json: " + exceptionJson + ", job origin: " + job.getRelated()); - _asyncJobMgr.completeAsyncJob(job.getId(), JobInfo.Status.FAILED, 0, exceptionJson); + RuntimeException ex = new RuntimeException("Job failed due to exception " + e.getMessage()); + _asyncJobMgr.completeAsyncJob(job.getId(), JobInfo.Status.FAILED, 0, _asyncJobMgr.marshallResultObject(ex)); } finally { CallContext.unregister(); } diff --git a/engine/orchestration/src/com/cloud/vm/VmWorkReconfigure.java b/engine/orchestration/src/com/cloud/vm/VmWorkReconfigure.java index bfc5735c121..11415775fe3 100644 --- a/engine/orchestration/src/com/cloud/vm/VmWorkReconfigure.java +++ b/engine/orchestration/src/com/cloud/vm/VmWorkReconfigure.java @@ -16,27 +16,26 @@ // under the License. package com.cloud.vm; -import com.cloud.offering.ServiceOffering; public class VmWorkReconfigure extends VmWork { private static final long serialVersionUID = -4517030323758086615L; - - ServiceOffering newServiceOffering; + + Long newServiceOfferingId; boolean sameHost; - + public VmWorkReconfigure(long userId, long accountId, long vmId, String handlerName, - ServiceOffering newServiceOffering, boolean sameHost) { - + Long newServiceOfferingId, boolean sameHost) { + super(userId, accountId, vmId, handlerName); - - this.newServiceOffering = newServiceOffering; + + this.newServiceOfferingId = newServiceOfferingId; this.sameHost = sameHost; } - - public ServiceOffering getNewServiceOffering() { - return newServiceOffering; + + public Long getNewServiceOfferingId() { + return newServiceOfferingId; } - + public boolean isSameHost() { return sameHost; } diff --git a/engine/schema/src/com/cloud/service/ServiceOfferingVO.java b/engine/schema/src/com/cloud/service/ServiceOfferingVO.java index 17b824bdcad..fd847349772 100755 --- a/engine/schema/src/com/cloud/service/ServiceOfferingVO.java +++ b/engine/schema/src/com/cloud/service/ServiceOfferingVO.java @@ -18,7 +18,12 @@ package com.cloud.service; import java.util.Map; -import javax.persistence.*; +import javax.persistence.Column; +import javax.persistence.DiscriminatorValue; +import javax.persistence.Entity; +import javax.persistence.PrimaryKeyJoinColumn; +import javax.persistence.Table; +import javax.persistence.Transient; import com.cloud.offering.ServiceOffering; import com.cloud.storage.DiskOfferingVO; @@ -93,9 +98,9 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering this.rateMbps = rateMbps; this.multicastRateMbps = multicastRateMbps; this.offerHA = offerHA; - this.limitCpuUse = false; - this.volatileVm = false; - this.default_use = defaultUse; + limitCpuUse = false; + volatileVm = false; + default_use = defaultUse; this.vm_type = vm_type == null ? null : vm_type.toString().toLowerCase(); } @@ -131,16 +136,16 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering public ServiceOfferingVO(ServiceOfferingVO offering) { super(offering.getId(), offering.getName(), offering.getDisplayText(), false, offering.getTags(), offering.isRecreatable(), offering.getUseLocalStorage(), offering.getSystemUse(), true, offering.getDomainId()); - this.cpu = offering.getCpu(); - this.ramSize = offering.getRamSize(); - this.speed = offering.getSpeed(); - this.rateMbps = offering.getRateMbps(); - this.multicastRateMbps = offering.getMulticastRateMbps(); - this.offerHA = offering.getOfferHA(); - this.limitCpuUse = offering.getLimitCpuUse(); - this.volatileVm = offering.getVolatileVm(); - this.hostTag = offering.getHostTag(); - this.vm_type = offering.getSystemVmType(); + cpu = offering.getCpu(); + ramSize = offering.getRamSize(); + speed = offering.getSpeed(); + rateMbps = offering.getRateMbps(); + multicastRateMbps = offering.getMulticastRateMbps(); + offerHA = offering.getOfferHA(); + limitCpuUse = offering.getLimitCpuUse(); + volatileVm = offering.getVolatileVm(); + hostTag = offering.getHostTag(); + vm_type = offering.getSystemVmType(); } @Override @@ -226,19 +231,23 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering this.hostTag = hostTag; } - public String getHostTag() { + @Override + public String getHostTag() { return hostTag; } - public String getSystemVmType(){ + @Override + public String getSystemVmType(){ return vm_type; } - public void setSortKey(int key) { + @Override + public void setSortKey(int key) { sortKey = key; } - public int getSortKey() { + @Override + public int getSortKey() { return sortKey; } @@ -272,11 +281,12 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering this.details = details; } + @Override public boolean isDynamic() { return cpu == null || speed == null || ramSize == null || isDynamic; } public void setDynamicFlag(boolean isdynamic) { - this.isDynamic = isdynamic; + isDynamic = isdynamic; } } diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java index 1e4e1712f6f..9210c40e9cf 100644 --- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java @@ -331,7 +331,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic // TODO static final ConfigKey VmJobEnabled = new ConfigKey("Advanced", - Boolean.class, "vm.job.enabled", "true", + Boolean.class, "vm.job.enabled", "false", "True to enable new VM sync model. false to use the old way", false); static final ConfigKey VmJobCheckInterval = new ConfigKey("Advanced", Long.class, "vm.job.check.interval", "3000", diff --git a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java index c9f712fee62..5bf248dd87e 100644 --- a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java +++ b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java @@ -131,7 +131,7 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana // TODO static final ConfigKey VmJobEnabled = new ConfigKey("Advanced", - Boolean.class, "vm.job.enabled", "true", + Boolean.class, "vm.job.enabled", "false", "True to enable new VM sync model. false to use the old way", false); static final ConfigKey VmJobCheckInterval = new ConfigKey("Advanced", Long.class, "vm.job.check.interval", "3000", diff --git a/utils/src/com/cloud/utils/exception/CloudRuntimeException.java b/utils/src/com/cloud/utils/exception/CloudRuntimeException.java index afc402e2a4f..914aafa1c2a 100755 --- a/utils/src/com/cloud/utils/exception/CloudRuntimeException.java +++ b/utils/src/com/cloud/utils/exception/CloudRuntimeException.java @@ -16,6 +16,9 @@ // under the License. package com.cloud.utils.exception; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; import java.util.ArrayList; import java.util.List; @@ -30,13 +33,12 @@ public class CloudRuntimeException extends RuntimeException implements ErrorCont private static final long serialVersionUID = SerialVersionUID.CloudRuntimeException; // This holds a list of uuids and their descriptive names. - protected ArrayList idList = new ArrayList(); + transient protected ArrayList idList = new ArrayList(); - protected ArrayList, String>> uuidList = new ArrayList, String>>(); + transient protected ArrayList, String>> uuidList = new ArrayList, String>>(); protected int csErrorCode; - public CloudRuntimeException(String message) { super(message); setCSErrorCode(CSExceptionErrorCode.getCSErrCode(this.getClass().getName())); @@ -49,13 +51,14 @@ public class CloudRuntimeException extends RuntimeException implements ErrorCont protected CloudRuntimeException() { super(); + setCSErrorCode(CSExceptionErrorCode.getCSErrCode(this.getClass().getName())); } public void addProxyObject(ExceptionProxyObject obj){ idList.add(obj); } - + public void addProxyObject(String uuid) { idList.add(new ExceptionProxyObject(uuid, null)); } @@ -91,4 +94,45 @@ public class CloudRuntimeException extends RuntimeException implements ErrorCont public List, String>> getEntitiesInError() { return uuidList; } + + private void writeObject(ObjectOutputStream out) throws IOException { + out.defaultWriteObject(); + + int idListSize = idList.size(); + out.writeInt(idListSize); + for (ExceptionProxyObject proxy : idList) { + out.writeObject(proxy); + } + + int uuidListSize = uuidList.size(); + out.writeInt(uuidListSize); + for (Pair, String> entry : uuidList) { + out.writeObject(entry.first().getCanonicalName()); + out.writeObject(entry.second()); + } + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + in.defaultReadObject(); + + int idListSize = in.readInt(); + if (idList == null) + idList = new ArrayList(); + if (uuidList == null) + uuidList = new ArrayList, String>>(); + + for (int i = 0; i < idListSize; i++) { + ExceptionProxyObject proxy = (ExceptionProxyObject)in.readObject(); + + idList.add(proxy); + } + + int uuidListSize = in.readInt(); + for (int i = 0; i < uuidListSize; i++) { + String clzName = (String)in.readObject(); + String val = (String)in.readObject(); + + uuidList.add(new Pair, String>(Class.forName(clzName), val)); + } + } } diff --git a/utils/src/com/cloud/utils/exception/ExceptionProxyObject.java b/utils/src/com/cloud/utils/exception/ExceptionProxyObject.java index 01cbd632c14..8cb7b94a3c9 100644 --- a/utils/src/com/cloud/utils/exception/ExceptionProxyObject.java +++ b/utils/src/com/cloud/utils/exception/ExceptionProxyObject.java @@ -16,18 +16,22 @@ // under the License. package com.cloud.utils.exception; +import java.io.Serializable; + + +public class ExceptionProxyObject implements Serializable { + private static final long serialVersionUID = -7514266713085362352L; -public class ExceptionProxyObject { private String uuid; private String description; - + public ExceptionProxyObject(){ - + } - + public ExceptionProxyObject(String uuid, String desc){ this.uuid = uuid; - this.description = desc; + description = desc; } public String getUuid() { @@ -45,6 +49,6 @@ public class ExceptionProxyObject { public void setDescription(String description) { this.description = description; } - - + + }