Saggi Mizrahi has uploaded a new change for review. Change subject: [WIP] Integrate jsonrpc ......................................................................
[WIP] Integrate jsonrpc Change-Id: Ia4ea4c0d2d896835eea30799fc983837728d18c1 Signed-off-by: Saggi Mizrahi <[email protected]> --- M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VDS.java A backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VdsProtocolType.java M backend/manager/modules/vdsbroker/pom.xml M backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VdsManager.java M backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VdsUpdateRunTimeInfo.java A backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/json/DefaultVdsmClientPool.java A backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/json/JsonVdsServerWrapper.java A backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/json/ResponseUnpacker.java M backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/xmlrpc/VdsServerWrapper.java M frontend/webadmin/modules/gwt-common/src/main/resources/org/ovirt/engine/core/Common.gwt.xml M pom.xml 11 files changed, 412 insertions(+), 90 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/20/20620/1 diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VDS.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VDS.java index 952478e..c6361d1 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VDS.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VDS.java @@ -309,6 +309,11 @@ return this.mVdsStatic.getHostName(); } + public VdsProtocolType getProtocolType() { + // FIXME: Add a field to VdsStatic + return VdsProtocolType.JsonRPC; + } + public void setHostName(String value) { this.mVdsStatic.setHostName(value); } @@ -1282,4 +1287,15 @@ public String getSupportedEmulatedMachines() { return mVdsDynamic.getSupportedEmulatedMachines(); } + + /* FIXME: This method returns a String instead of a URI object because GWT can't + compile that class. The fact that GWT even accesses this class is way + beyond me and should be rectified ASAP. + */ + public String getUri() { + /* FIXME: I wanted to use formatting but GWT decided the function doesn't exist. + * I guess I don't share GWT's plane of existence + */ + return "tcp://" + getHostName() + ":" + Integer.toString(getPort()); + } } diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VdsProtocolType.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VdsProtocolType.java new file mode 100644 index 0000000..f1d0c4a --- /dev/null +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VdsProtocolType.java @@ -0,0 +1,9 @@ +package org.ovirt.engine.core.common.businessentities; + +/** + * Owner: Saggi Mizrahi + */ +public enum VdsProtocolType { + XMLRPC, + JsonRPC +} diff --git a/backend/manager/modules/vdsbroker/pom.xml b/backend/manager/modules/vdsbroker/pom.xml index e5ea9a3..5a1c4fe 100644 --- a/backend/manager/modules/vdsbroker/pom.xml +++ b/backend/manager/modules/vdsbroker/pom.xml @@ -87,6 +87,12 @@ <version>${snakeyaml.version}</version> </dependency> + <dependency> + <groupId>org.ovirt.vdsm</groupId> + <artifactId>vdsm-api</artifactId> + <version>${vdsmapi.version}</version> + </dependency> + <!-- <dependency> <groupId>org.jboss.jbossas</groupId> diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VdsManager.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VdsManager.java index c721ff7..6b50a81 100644 --- a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VdsManager.java +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VdsManager.java @@ -1,5 +1,6 @@ package org.ovirt.engine.core.vdsbroker; +import java.net.URI; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; @@ -44,40 +45,89 @@ import org.ovirt.engine.core.utils.timer.SchedulerUtilQuartzImpl; import org.ovirt.engine.core.vdsbroker.irsbroker.IRSErrorException; import org.ovirt.engine.core.vdsbroker.irsbroker.IrsBrokerCommand; +import org.ovirt.engine.core.vdsbroker.json.DefaultVdsmClientPool; import org.ovirt.engine.core.vdsbroker.vdsbroker.CollectVdsNetworkDataVDSCommand; import org.ovirt.engine.core.vdsbroker.vdsbroker.GetCapabilitiesVDSCommand; import org.ovirt.engine.core.vdsbroker.vdsbroker.IVdsServer; import org.ovirt.engine.core.vdsbroker.vdsbroker.VDSNetworkException; import org.ovirt.engine.core.vdsbroker.vdsbroker.VDSRecoveringException; import org.ovirt.engine.core.vdsbroker.vdsbroker.VdsServerConnector; +import org.ovirt.engine.core.vdsbroker.vdsbroker.json.JsonVdsServerWrapper; import org.ovirt.engine.core.vdsbroker.vdsbroker.xmlrpc.VdsServerWrapper; import org.ovirt.engine.core.vdsbroker.xmlrpc.XmlRpcUtils; +import org.ovirt.vdsm.VDSMClient; public class VdsManager { - private VDS _vds; + private static Log log = LogFactory.getLog(VdsManager.class); + private static final int VDS_REFRESH_RATE = Config.<Integer> GetValue(ConfigValues.VdsRefreshRate) * 1000; + private static Map<Guid, String> recoveringJobIdMap = new ConcurrentHashMap<Guid, String>(); + private static final int VDS_DURING_FAILURE_TIMEOUT_IN_MINUTES = Config + .<Integer> GetValue(ConfigValues.TimeToReduceFailedRunOnVdsInMinutes); + + private VDS vds; + private long lastUpdate; private long updateStartTime; - private static Log log = LogFactory.getLog(VdsManager.class); - - public boolean getRefreshStatistics() { - return (_refreshIteration == _numberRefreshesBeforeSave); - } - - private static final int VDS_REFRESH_RATE = Config.<Integer> GetValue(ConfigValues.VdsRefreshRate) * 1000; - private String onTimerJobId; - private final int _numberRefreshesBeforeSave = Config.<Integer> GetValue(ConfigValues.NumberVmRefreshesBeforeSave); - private int _refreshIteration = 1; + private final int numberRefreshesBeforeSave = Config.<Integer> GetValue(ConfigValues.NumberVmRefreshesBeforeSave); + private int refreshIteration = 1; - private final Object _lockObj = new Object(); - private static Map<Guid, String> recoveringJobIdMap = new ConcurrentHashMap<Guid, String>(); + private IVdsServer vdsProxy; + + private String duringFailureJobId; + private boolean privateInitialized; + + + private final Object lockObj = new Object(); private boolean isSetNonOperationalExecuted; private MonitoringStrategy monitoringStrategy; private EngineLock monitoringLock; + private final AtomicInteger mFailedToRunVmAttempts; + private final AtomicInteger mUnrespondedAttempts; + private final AtomicBoolean sshSoftFencingExecuted; + + private final Guid _vdsId; + + public VdsManager(VDS vds) { + log.info("Entered VdsManager constructor"); + this.vds = vds; + _vdsId = vds.getId(); + monitoringStrategy = MonitoringStrategyFactory.getMonitoringStrategyForVds(vds); + mUnrespondedAttempts = new AtomicInteger(); + mFailedToRunVmAttempts = new AtomicInteger(); + sshSoftFencingExecuted = new AtomicBoolean(false); + monitoringLock = new EngineLock(Collections.singletonMap(_vdsId.toString(), + new Pair<String, String>(LockingGroup.VDS_INIT.name(), "")), null); + + if (this.vds.getStatus() == VDSStatus.PreparingForMaintenance) { + this.vds.setPreviousStatus(this.vds.getStatus()); + } else { + this.vds.setPreviousStatus(VDSStatus.Up); + } + // if ssl is on and no certificate file + if (Config.<Boolean> GetValue(ConfigValues.UseSecureConnectionWithServers) + && !EngineEncryptionUtils.haveKey()) { + if (this.vds.getStatus() != VDSStatus.Maintenance && this.vds.getStatus() != VDSStatus.InstallFailed) { + setStatus(VDSStatus.NonResponsive, this.vds); + UpdateDynamicData(this.vds.getDynamicData()); + } + log.error("Could not find VDC Certificate file."); + AuditLogableBase logable = new AuditLogableBase(_vdsId); + AuditLogDirector.log(logable, AuditLogType.CERTIFICATE_FILE_NOT_FOUND); + } + InitVdsBroker(); + this.vds = null; + + } + public Object getLockObj() { - return _lockObj; + return lockObj; + } + + public boolean getRefreshStatistics() { + return (refreshIteration == numberRefreshesBeforeSave); } public static void cancelRecoveryJob(Guid vdsId) { @@ -92,15 +142,6 @@ } } - private final AtomicInteger mFailedToRunVmAttempts; - private final AtomicInteger mUnrespondedAttempts; - private final AtomicBoolean sshSoftFencingExecuted; - - private static final int VDS_DURING_FAILURE_TIMEOUT_IN_MINUTES = Config - .<Integer> GetValue(ConfigValues.TimeToReduceFailedRunOnVdsInMinutes); - private String duringFailureJobId; - private boolean privateInitialized; - public boolean getInitialized() { return privateInitialized; } @@ -109,10 +150,8 @@ privateInitialized = value; } - private IVdsServer _vdsProxy; - public IVdsServer getVdsProxy() { - return _vdsProxy; + return vdsProxy; } public Guid getVdsId() { @@ -170,14 +209,14 @@ TimeUnit.MINUTES); sched.pauseJob(duringFailureJobId); // start with refresh statistics - _refreshIteration = _numberRefreshesBeforeSave - 1; + refreshIteration = numberRefreshesBeforeSave - 1; onTimerJobId = sched.scheduleAFixedDelayJob(this, "OnTimer", new Class[0], new Object[0], VDS_REFRESH_RATE, VDS_REFRESH_RATE, TimeUnit.MILLISECONDS); } private void InitVdsBroker() { - log.infoFormat("Initialize vdsBroker ({0},{1})", _vds.getHostName(), _vds.getPort()); + log.infoFormat("Initialize vdsBroker ({0},{1})", vds.getHostName(), vds.getPort()); // Get the values of the timeouts: int clientTimeOut = Config.<Integer> GetValue(ConfigValues.vdsTimeout) * 1000; @@ -185,14 +224,23 @@ int clientRetries = Config.<Integer>GetValue(ConfigValues.vdsRetries); Pair<VdsServerConnector, HttpClient> returnValue = - XmlRpcUtils.getConnection(_vds.getHostName(), - _vds.getPort(), + XmlRpcUtils.getConnection(vds.getHostName(), + vds.getPort(), clientTimeOut, connectionTimeOut, clientRetries, VdsServerConnector.class, Config.<Boolean> GetValue(ConfigValues.EncryptHostCommunication)); - _vdsProxy = new VdsServerWrapper(returnValue.getFirst(), returnValue.getSecond()); + switch (vds.getProtocolType()) { + case XMLRPC: + vdsProxy = new VdsServerWrapper(returnValue.getFirst(), returnValue.getSecond()); + break; + case JsonRPC: + // FIXME: The new Server Wrapper gets both clients since it's still incomplete. Don't forget to remove. + URI uri = URI.create(vds.getUri()); + VDSMClient apiClient = DefaultVdsmClientPool.getInstance().createClient(uri); + vdsProxy = new JsonVdsServerWrapper(apiClient, returnValue.getFirst(), returnValue.getSecond()); + } } public void UpdateVmDynamic(VmDynamic vmDynamic) { @@ -212,30 +260,30 @@ VDS tmpVds; synchronized (getLockObj()) { tmpVds = _vds = DbFacade.getInstance().getVdsDao().get(getVdsId()); - if (_vds == null) { + if (vds == null) { log.errorFormat("VdsManager::refreshVdsRunTimeInfo - OnTimer is NULL for {0}", getVdsId()); return; } try { - if (_refreshIteration == _numberRefreshesBeforeSave) { - _refreshIteration = 1; + if (refreshIteration == numberRefreshesBeforeSave) { + refreshIteration = 1; } else { - _refreshIteration++; + refreshIteration++; } if (isMonitoringNeeded()) { setStartTime(); - _vdsUpdater = new VdsUpdateRunTimeInfo(VdsManager.this, _vds, monitoringStrategy); + _vdsUpdater = new VdsUpdateRunTimeInfo(VdsManager.this, vds, monitoringStrategy); _vdsUpdater.Refresh(); mUnrespondedAttempts.set(0); sshSoftFencingExecuted.set(false); setLastUpdate(); } - if (!getInitialized() && _vds.getStatus() != VDSStatus.NonResponsive - && _vds.getStatus() != VDSStatus.PendingApproval) { - log.infoFormat("Initializing Host: {0}", _vds.getName()); - ResourceManager.getInstance().HandleVdsFinishedInit(_vds.getId()); + if (!getInitialized() && vds.getStatus() != VDSStatus.NonResponsive + && vds.getStatus() != VDSStatus.PendingApproval) { + log.infoFormat("Initializing Host: {0}", vds.getName()); + ResourceManager.getInstance().HandleVdsFinishedInit(vds.getId()); setInitialized(true); } } catch (VDSNetworkException e) { @@ -259,7 +307,7 @@ } } - _vds = null; + vds = null; _vdsUpdater = null; } catch (IRSErrorException ex) { logAfterRefreshFailureMessage(ex); @@ -289,8 +337,8 @@ private void logFailureMessage(RuntimeException ex) { log.warnFormat( "Failed to refresh VDS , vds = {0} : {1}, error = '{2}', continuing.", - _vds.getId(), - _vds.getName(), + vds.getId(), + vds.getName(), ex); } @@ -305,31 +353,31 @@ } public boolean isMonitoringNeeded() { - return (monitoringStrategy.isMonitoringNeeded(_vds) && - _vds.getStatus() != VDSStatus.Installing && - _vds.getStatus() != VDSStatus.InstallFailed && - _vds.getStatus() != VDSStatus.Reboot && - _vds.getStatus() != VDSStatus.Maintenance && - _vds.getStatus() != VDSStatus.PendingApproval && _vds.getStatus() != VDSStatus.Down); + return (monitoringStrategy.isMonitoringNeeded(vds) && + vds.getStatus() != VDSStatus.Installing && + vds.getStatus() != VDSStatus.InstallFailed && + vds.getStatus() != VDSStatus.Reboot && + vds.getStatus() != VDSStatus.Maintenance && + vds.getStatus() != VDSStatus.PendingApproval && vds.getStatus() != VDSStatus.Down); } private void HandleVdsRecoveringException(VDSRecoveringException ex) { - if (_vds.getStatus() != VDSStatus.Initializing && _vds.getStatus() != VDSStatus.NonOperational) { - setStatus(VDSStatus.Initializing, _vds); - DbFacade.getInstance().getVdsDynamicDao().updateStatus(_vds.getId(), VDSStatus.Initializing); - AuditLogableBase logable = new AuditLogableBase(_vds.getId()); + if (vds.getStatus() != VDSStatus.Initializing && vds.getStatus() != VDSStatus.NonOperational) { + setStatus(VDSStatus.Initializing, vds); + DbFacade.getInstance().getVdsDynamicDao().updateStatus(vds.getId(), VDSStatus.Initializing); + AuditLogableBase logable = new AuditLogableBase(vds.getId()); logable.addCustomValue("ErrorMessage", ex.getMessage()); logable.updateCallStackFromThrowable(ex); AuditLogDirector.log(logable, AuditLogType.VDS_INITIALIZING); log.warnFormat( "Failed to refresh VDS , vds = {0} : {1}, error = {2}, continuing.", - _vds.getId(), - _vds.getName(), + vds.getId(), + vds.getName(), ex.getMessage()); final int VDS_RECOVERY_TIMEOUT_IN_MINUTES = Config.<Integer> GetValue(ConfigValues.VdsRecoveryTimeoutInMintues); String jobId = SchedulerUtilQuartzImpl.getInstance().scheduleAOneTimeJob(this, "onTimerHandleVdsRecovering", new Class[0], new Object[0], VDS_RECOVERY_TIMEOUT_IN_MINUTES, TimeUnit.MINUTES); - recoveringJobIdMap.put(_vds.getId(), jobId); + recoveringJobIdMap.put(vds.getId(), jobId); } } @@ -421,20 +469,20 @@ } if (vds.getPreviousStatus() != vds.getStatus()) { vds.setPreviousStatus(vds.getStatus()); - if (_vds != null) { - _vds.setPreviousStatus(vds.getStatus()); + if (this.vds != null) { + this.vds.setPreviousStatus(vds.getStatus()); } } // update to new status vds.setStatus(status); - if (_vds != null) { - _vds.setStatus(status); + if (this.vds != null) { + this.vds.setStatus(status); } switch (status) { case NonOperational: - if (_vds != null) { - _vds.setNonOperationalReason(vds.getNonOperationalReason()); + if (this.vds != null) { + this.vds.setNonOperationalReason(vds.getNonOperationalReason()); } if(vds.getVmCount() > 0) { break; @@ -442,21 +490,21 @@ case NonResponsive: case Down: case Maintenance: - vds.setCpuSys(Double.valueOf(0)); - vds.setCpuUser(Double.valueOf(0)); - vds.setCpuIdle(Double.valueOf(0)); - vds.setCpuLoad(Double.valueOf(0)); + vds.setCpuSys((double) 0); + vds.setCpuUser((double) 0); + vds.setCpuIdle((double) 0); + vds.setCpuLoad((double) 0); vds.setUsageCpuPercent(0); vds.setUsageMemPercent(0); vds.setUsageNetworkPercent(0); - if (_vds != null) { - _vds.setCpuSys(Double.valueOf(0)); - _vds.setCpuUser(Double.valueOf(0)); - _vds.setCpuIdle(Double.valueOf(0)); - _vds.setCpuLoad(Double.valueOf(0)); - _vds.setUsageCpuPercent(0); - _vds.setUsageMemPercent(0); - _vds.setUsageNetworkPercent(0); + if (this.vds != null) { + this.vds.setCpuSys((double) 0); + this.vds.setCpuUser((double) 0); + this.vds.setCpuIdle((double) 0); + this.vds.setCpuLoad((double) 0); + this.vds.setUsageCpuPercent(0); + this.vds.setUsageMemPercent(0); + this.vds.setUsageNetworkPercent(0); } default: break; @@ -465,7 +513,7 @@ } /** - * This function called when vds have failed vm attempts one in predefined time. Its increments failure attemts to + * This function is called when vds have failed vm attempts one in predefined time. Its increments failure attempts to * one * * @param obj @@ -476,7 +524,7 @@ synchronized (getLockObj()) { VDS vds = DbFacade.getInstance().getVdsDao().get(getVdsId()); /** - * Disable timer if vds returns from suspitious mode + * Disable timer if vds returns from suspicious mode */ if (mFailedToRunVmAttempts.decrementAndGet() == 0) { SchedulerUtilQuartzImpl.getInstance().pauseJob(duringFailureJobId); @@ -513,10 +561,10 @@ /** */ - public void SuccededToRunVm(Guid vmId) { + public void SucceededToRunVm(Guid vmId) { mUnrespondedAttempts.set(0); sshSoftFencingExecuted.set(false); - ResourceManager.getInstance().SuccededToRunVm(vmId, _vds.getId()); + ResourceManager.getInstance().SuccededToRunVm(vmId, vds.getId()); } public VDSStatus refreshCapabilities(AtomicBoolean processHardwareCapsNeeded, VDS vds) { @@ -657,7 +705,7 @@ public void dispose() { log.info("vdsManager::disposing"); SchedulerUtilQuartzImpl.getInstance().deleteJob(onTimerJobId); - XmlRpcUtils.shutDownConnection(((VdsServerWrapper) _vdsProxy).getHttpClient()); + XmlRpcUtils.shutDownConnection(((VdsServerWrapper) vdsProxy).getHttpClient()); } /** @@ -667,21 +715,21 @@ * The exception to log. */ private void logNetworkException(VDSNetworkException e) { - switch (_vds.getStatus()) { + switch (vds.getStatus()) { case Down: break; case NonResponsive: log.debugFormat( "Failed to refresh VDS , vds = {0} : {1}, VDS Network Error, continuing.\n{2}", - _vds.getId(), - _vds.getName(), + vds.getId(), + vds.getName(), e.getMessage()); break; default: log.warnFormat( "Failed to refresh VDS , vds = {0} : {1}, VDS Network Error, continuing.\n{2}", - _vds.getId(), - _vds.getName(), + vds.getId(), + vds.getName(), e.getMessage()); } } diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VdsUpdateRunTimeInfo.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VdsUpdateRunTimeInfo.java index 8a1496a..905e4fb 100644 --- a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VdsUpdateRunTimeInfo.java +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VdsUpdateRunTimeInfo.java @@ -420,7 +420,7 @@ } for (Guid vm_guid : _succededToRunVms) { - _vdsManager.SuccededToRunVm(vm_guid); + _vdsManager.SucceededToRunVm(vm_guid); } // run all vms that crushed that marked with auto startup for (Guid vm_guid : _autoVmsToRun) { diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/json/DefaultVdsmClientPool.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/json/DefaultVdsmClientPool.java new file mode 100644 index 0000000..045afcc --- /dev/null +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/json/DefaultVdsmClientPool.java @@ -0,0 +1,75 @@ +package org.ovirt.engine.core.vdsbroker.json; + +import org.ovirt.vdsm.VDSMClientPool; +import org.ovirt.vdsm.reactors.NioReactor; +import org.ovirt.vdsm.reactors.Reactor; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +/** + * Owner: Saggi Mizrahi + * + * This initializes a global VDSMClientPool to be used by the whole process + */ +public class DefaultVdsmClientPool { + private static Lock instanceLock = new ReentrantLock(); + private static VDSMClientPool instance; + public static VDSMClientPool getInstance() { + // http://en.wikipedia.org/wiki/Double-checked_locking#Usage_in_Java + if (instance == null) { + instanceLock.lock(); + try { + if (instance == null) { + + instance = createInstance(); + } + + } finally { + instanceLock.unlock(); + } + } + return instance; + } + + private static VDSMClientPool createInstance() { + Map<String,Reactor> reactorMap = createReactorMap(); + final VDSMClientPool pool = new VDSMClientPool(reactorMap); + Thread t = new Thread(new Runnable() { + @Override + public void run() { + pool.serve(); + } + }); + t.start(); + return pool; + } + + private static Map<String, Reactor> createReactorMap() { + Map<String, Reactor> reactorMap = new HashMap<>(); + final NioReactor nioRactor; + try { + nioRactor = new NioReactor(); + } catch (IOException e) { + // Shouldn't ever happen + throw new RuntimeException(e); + } + setUpReactor(nioRactor); + reactorMap.put("tcp", nioRactor); + return reactorMap; + } + + private static void setUpReactor(final Reactor reactor) { + Thread t = new Thread(new Runnable() { + @Override + public void run() { + reactor.serve(); + } + }); + t.start(); + } + +} diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/json/JsonVdsServerWrapper.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/json/JsonVdsServerWrapper.java new file mode 100644 index 0000000..2844f6f --- /dev/null +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/json/JsonVdsServerWrapper.java @@ -0,0 +1,41 @@ +package org.ovirt.engine.core.vdsbroker.vdsbroker.json; + +import org.apache.commons.httpclient.HttpClient; +import org.ovirt.engine.core.vdsbroker.vdsbroker.VDSInfoReturnForXmlRpc; +import org.ovirt.engine.core.vdsbroker.vdsbroker.VdsServerConnector; +import org.ovirt.engine.core.vdsbroker.vdsbroker.xmlrpc.VdsServerWrapper; +import org.ovirt.engine.core.vdsbroker.xmlrpc.XmlRpcRunTimeException; +import org.ovirt.vdsm.VDSMClient; +import org.ovirt.vdsm.VDSMResponse; +import org.ovirt.vdsm.VdsmCapabilities; + +import java.util.Map; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +public class JsonVdsServerWrapper extends VdsServerWrapper { + + private final VDSMClient _client; + private final ResponseUnpacker unpacker = new ResponseUnpacker(); + + public JsonVdsServerWrapper(VDSMClient client, VdsServerConnector innerImplementation, HttpClient httpClient) { + super(innerImplementation, httpClient); + _client = client; + } + + private <T> T waitForResponse(Future<T> future) { + // TODO: TIMEOUT + try { + return future.get(3, TimeUnit.MINUTES); + } catch (Exception e) { + throw new XmlRpcRunTimeException("Wrapped JSON-RPC Error", e); + } + } + + @Override + public VDSInfoReturnForXmlRpc getCapabilities() { + Future<VDSMResponse<VdsmCapabilities>> call = _client.Host_getCapabilities(_client.newID()); + Map<String, Object> unpackedResponse = unpacker.unpackResponse(waitForResponse(call), "info"); + return new VDSInfoReturnForXmlRpc(unpackedResponse); + } +} diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/json/ResponseUnpacker.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/json/ResponseUnpacker.java new file mode 100644 index 0000000..931f829 --- /dev/null +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/json/ResponseUnpacker.java @@ -0,0 +1,126 @@ +package org.ovirt.engine.core.vdsbroker.vdsbroker.json; + +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.annotate.JsonProperty; +import org.codehaus.jackson.node.ObjectNode; +import org.ovirt.vdsm.VDSMEnum; +import org.ovirt.vdsm.VDSMObject; +import org.ovirt.vdsm.VDSMResponse; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + * Owner: Saggi Mizrahi + * + * Unpacks Vdsm responses to a raw Map<Object, Object>. This is to be able to use the new API infra as a drop in + * replacement until we find the resources to convert all the commands + * + * The class is meant to be completely stateless and reentrent so one instance can be used for all of our unpacking + * needs + * + * @param response The response as returned from the VDSM API + * @param resultKey Unlike the JsonRPC where the result key is always "result" in the XML-RPC it is always different + */ +public class ResponseUnpacker { + public ResponseUnpacker() {} + + public Map<String, Object> unpackResponse(VDSMResponse<?> response, String resultKey) { + Map<String, Object> unpackedResult = new HashMap<>(); + unpackStatus(unpackedResult, response); + if (response.isSuccess()) { + unpackedResult.put(resultKey, unpackObject(response.result())); + } + + return unpackedResult; + } + + private void unpackStatus(Map<String, Object> result, VDSMResponse<?> response) { + HashMap<String,Object> status = new HashMap<>(); + if (response.isSuccess()) { + status.put("code", 0); + status.put("message", "Success"); + } else { + status.put("code", response.error().code()); + status.put("message", response.error().message()); + } + result.put("status", status); + } + + private Object unpackObject(Object obj) { + Class cls = obj.getClass(); + if (VDSMObject.class.isAssignableFrom(cls)) { + return unpackVdsmObject((VDSMObject) obj); + } else if (List.class.isAssignableFrom(cls)) { + return unpackList((List<Object>) obj); + } else if (Map.class.isAssignableFrom(cls)) { + return unpackMap((Map<String, Object>) obj); + } else if (Enum.class.isAssignableFrom(cls)) { + return unpackEnum((Enum<?>) obj); + } else { + // All we have left are basic types + return obj; + } + } + + private String unpackEnum(Enum<?> obj) { + return ((VDSMEnum)obj).toString(); + } + + private Map<String, Object> unpackMap(Map<String, Object> map) { + Map<String, Object> result = new HashMap<>(); + for(Map.Entry<String, Object> item : map.entrySet()) { + result.put(item.getKey(), unpackObject(item.getValue())); + } + return result; + } + + private List<Object> unpackList(List<Object> lst) { + List<Object> result = new ArrayList<>(lst.size()); + for(Object item : lst) { + result.add(unpackObject(item)); + } + return result; + } + + private Map<String, Object> unpackVdsmObject(VDSMObject obj) { + Map<String, Object> result = new HashMap<>(); + + Class cls = obj.getClass(); + for (Method method : cls.getMethods()) { + + if (method.getParameterTypes().length != 0) { + continue; + } + + JsonProperty jp = + method.getAnnotation(JsonProperty.class); + if (jp == null) { + continue; + } + + final Object value; + try { + value = unpackObject(method.invoke(obj)); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } + result.put(jp.value(), value); + } + + //TODO + final ObjectNode node = obj.getExtraFields(); + Iterator<Map.Entry<String, JsonNode>> fieldIter = node.getFields(); + while (fieldIter.hasNext()) { + final Map.Entry<String, JsonNode> field = fieldIter.next(); + result.put(field.getKey(), field.getValue()); + } + + return result; + } +} diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/xmlrpc/VdsServerWrapper.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/xmlrpc/VdsServerWrapper.java index d7c06e1..72c4a5d 100644 --- a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/xmlrpc/VdsServerWrapper.java +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/xmlrpc/VdsServerWrapper.java @@ -1027,14 +1027,12 @@ } @Override - public StatusOnlyReturnForXmlRpc glusterVolumeRebalanceStart(String volumeName, Boolean fixLayoutOnly, Boolean force) { - Map<String, Object> xmlRpcResponse; + public StatusOnlyReturnForXmlRpc glusterVolumeRebalanceStop(String volumeName) { try { - xmlRpcResponse = vdsServer.glusterVolumeRebalanceStart(volumeName, fixLayoutOnly, force); + return new StatusOnlyReturnForXmlRpc(vdsServer.glusterVolumeRebalanceStop(volumeName)); } catch (UndeclaredThrowableException ute) { throw new XmlRpcRunTimeException(ute); } - return new StatusOnlyReturnForXmlRpc(xmlRpcResponse); } @Override diff --git a/frontend/webadmin/modules/gwt-common/src/main/resources/org/ovirt/engine/core/Common.gwt.xml b/frontend/webadmin/modules/gwt-common/src/main/resources/org/ovirt/engine/core/Common.gwt.xml index 99619f8..96a48f5 100644 --- a/frontend/webadmin/modules/gwt-common/src/main/resources/org/ovirt/engine/core/Common.gwt.xml +++ b/frontend/webadmin/modules/gwt-common/src/main/resources/org/ovirt/engine/core/Common.gwt.xml @@ -46,7 +46,9 @@ <include name="common/businessentities/OpenstackNetworkPluginType.java" /> <include name="common/businessentities/DiskAlignment.java" /> <include name="common/businessentities/OpenStackImageProviderProperties.java" /> - <include name="common/businessentities/VmBalloonInfo.java" /> + <include name="common/businessentities/OpenStackImageProviderProperties.java" /> + <include name="common/businessentities/VmBalloonInfo.java" /> + <include name="common/businessentities/VdsProtocolType.java" /> <!-- Network business entities --> <include name="common/businessentities/network/VdsNetworkInterface.java" /> diff --git a/pom.xml b/pom.xml index ae75e69..b30925f 100644 --- a/pom.xml +++ b/pom.xml @@ -88,6 +88,7 @@ <infinispan.version>5.2.5.Final</infinispan.version> <snakeyaml.version>1.8</snakeyaml.version> <ws-commons-util.version>1.0.2</ws-commons-util.version> + <vdsmapi.version>1.0.0</vdsmapi.version> <!-- OpenStack --> <openstack-client.version>3.0.1</openstack-client.version> -- To view, visit http://gerrit.ovirt.org/20620 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ia4ea4c0d2d896835eea30799fc983837728d18c1 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Saggi Mizrahi <[email protected]> _______________________________________________ Engine-patches mailing list [email protected] http://lists.ovirt.org/mailman/listinfo/engine-patches
