Frank Kobzik has uploaded a new change for review. Change subject: engine: Phase 4: Query for generating console descriptor ......................................................................
engine: Phase 4: Query for generating console descriptor Move generating console descriptor file (aka '.vv' file) from frontend clients to backend generator. Added query for calling this generator from UI and REST API. Change-Id: I4a0f882f8936fe49d7231eb42d67fe374e28ccb5 Signed-off-by: Frantisek Kobzik <fkob...@redhat.com> Bug-Url: https://bugzilla.redhat.com/1128763 --- A backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetConsoleDescriptorFileQuery.java A backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/GetConsoleDescriptorFileQueryTest.java A backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/console/ConsoleDescriptorGenerator.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java M frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/uicommon/SpiceNativeImpl.java M frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/uicommon/VncNativeImpl.java 6 files changed, 232 insertions(+), 112 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/75/37975/1 diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetConsoleDescriptorFileQuery.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetConsoleDescriptorFileQuery.java new file mode 100644 index 0000000..77a7cea --- /dev/null +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetConsoleDescriptorFileQuery.java @@ -0,0 +1,45 @@ +package org.ovirt.engine.core.bll; + +import org.ovirt.engine.core.common.console.ConsoleDescriptorGenerator; +import org.ovirt.engine.core.common.console.ConsoleOptions; +import org.ovirt.engine.core.common.queries.ConsoleOptionsParams; + +/** + * Generates descriptor file (for now only .vv file for SPICE and VNC is supported) + * for given graphics protocol of given vm. + * + * @param <P> ConsoleOptions instance used for generating descriptor. + */ +public class GetConsoleDescriptorFileQuery<P extends ConsoleOptionsParams> extends QueriesCommandBase<P> { + + public GetConsoleDescriptorFileQuery(P parameters) { + super(parameters); + } + + @Override + protected boolean validateInputs() { + ConsoleOptions options = getParameters().getOptions(); + if (options == null) { + getQueryReturnValue().setExceptionString("Console options must be specified."); + return false; + } + + if (options.getVmId() == null) { + getQueryReturnValue().setExceptionString("VM id must be specified."); + return false; + } + + if (options.getGraphicsType() == null) { + getQueryReturnValue().setExceptionString("Graphics Type or Console Options must must be specified."); + return false; + } + + return true; + } + + @Override + protected void executeQueryCommand() { + getQueryReturnValue().setReturnValue(ConsoleDescriptorGenerator.generateDescriptor(getParameters().getOptions())); + } + +} diff --git a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/GetConsoleDescriptorFileQueryTest.java b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/GetConsoleDescriptorFileQueryTest.java new file mode 100644 index 0000000..b8b3d3e --- /dev/null +++ b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/GetConsoleDescriptorFileQueryTest.java @@ -0,0 +1,44 @@ +package org.ovirt.engine.core.bll; + +import org.junit.Test; +import org.ovirt.engine.core.common.businessentities.GraphicsType; +import org.ovirt.engine.core.common.console.ConsoleOptions; +import org.ovirt.engine.core.common.queries.ConsoleOptionsParams; +import org.ovirt.engine.core.compat.Guid; + + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class GetConsoleDescriptorFileQueryTest { + + @Test + public void shouldFailWhenVmNull() throws Exception { + ConsoleOptions options = new ConsoleOptions(GraphicsType.SPICE); + + ConsoleOptionsParams params = new ConsoleOptionsParams(options); + GetConsoleDescriptorFileQuery query = new GetConsoleDescriptorFileQuery(params); + assertFalse(query.validateInputs()); + } + + @Test + public void shouldFailWhenGraphicsTypeNull() throws Exception { + ConsoleOptions options = new ConsoleOptions(); + options.setVmId(Guid.Empty); + + ConsoleOptionsParams params = new ConsoleOptionsParams(options); + GetConsoleDescriptorFileQuery query = new GetConsoleDescriptorFileQuery(params); + assertFalse(query.validateInputs()); + } + + @Test + public void shouldPass() throws Exception { + ConsoleOptions options = new ConsoleOptions(GraphicsType.SPICE); + options.setVmId(Guid.Empty); + + ConsoleOptionsParams params = new ConsoleOptionsParams(options); + GetConsoleDescriptorFileQuery query = new GetConsoleDescriptorFileQuery(params); + assertTrue(query.validateInputs()); + } + +} diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/console/ConsoleDescriptorGenerator.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/console/ConsoleDescriptorGenerator.java new file mode 100644 index 0000000..3a3f487 --- /dev/null +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/console/ConsoleDescriptorGenerator.java @@ -0,0 +1,108 @@ +package org.ovirt.engine.core.common.console; + +import org.ovirt.engine.core.common.businessentities.GraphicsType; +import org.ovirt.engine.core.compat.StringHelper; + +public class ConsoleDescriptorGenerator { + + public static String generateDescriptor(ConsoleOptions options) { + StringBuilder configBuilder = new StringBuilder("[virt-viewer]"); //$NON-NLS-1$ + configBuilder.append("\ntype=").append(graphicsTypeToString(options.getGraphicsType())) //$NON-NLS-1$ + .append("\nhost=").append(options.getHost()) //$NON-NLS-1$ + .append("\nport=").append(options.getPort()) //$NON-NLS-1$ + .append("\npassword=").append(options.getTicket()) //$NON-NLS-1$ + .append("\n# Password is valid for ") //$NON-NLS-1$ + .append(ConsoleOptions.TICKET_VALIDITY_SECONDS).append(" seconds.") //$NON-NLS-1$ + .append("\ndelete-this-file=1") //$NON-NLS-1$ + .append("\nfullscreen=").append(boolToInt(options.isFullScreen())) //$NON-NLS-1$ + .append("\ntitle=").append(options.getTitle()); //$NON-NLS-1$ + + if (!StringHelper.isNullOrEmpty(options.getToggleFullscreenHotKey())) { + configBuilder.append("\ntoggle-fullscreen=").append(options.getToggleFullscreenHotKey()); //$NON-NLS-1$ + } + + String releaseCursorHotKey = options.getReleaseCursorHotKey(); + if (!StringHelper.isNullOrEmpty(releaseCursorHotKey)) { + configBuilder.append("\nrelease-cursor=").append(releaseCursorHotKey); //$NON-NLS-1$ + } + + if (options.isRemapCtrlAltDelete()) { + configBuilder.append("\nsecure-attention=").append(ConsoleOptions.SECURE_ATTENTION_MAPPING); //$NON-NLS-1$ + } + + if (options.getGraphicsType() == GraphicsType.SPICE) { + configBuilder.append(generateSpicePart(options)); + } + + return configBuilder.toString(); + } + + private static String generateSpicePart(ConsoleOptions options) { + StringBuilder configBuilder = new StringBuilder("[virt-viewer]"); //$NON-NLS-1$ + + configBuilder.append("\ntls-port=").append(options.getSecurePort()) //$NON-NLS-1$ + .append("\nenable-smartcard=").append(boolToInt(options.isSmartcardEnabled())) //$NON-NLS-1$ + .append("\nenable-usb-autoshare=").append(boolToInt(options.isUsbAutoShare())) //$NON-NLS-1$ + .append("\nusb-filter=").append(options.getUsbFilter()); //$NON-NLS-1$ + + if (options.getCipherSuite() != null) { + configBuilder.append("\ntls-ciphers=").append(options.getCipherSuite()); //$NON-NLS-1$ + } + + if (!StringHelper.isNullOrEmpty(options.getHostSubject())) { + configBuilder.append("\nhost-subject=").append(options.getHostSubject()); //$NON-NLS-1$ + } + + if (options.getTrustStore() != null) { + //virt-viewer-file doesn't want newlines in ca + String trustStore= options.getTrustStore().replace("\n", "\\n"); //$NON-NLS-1$ $NON-NLS-2$ + configBuilder.append("\nca=").append(trustStore); //$NON-NLS-1$ + } + + if (options.isWanOptionsEnabled()) { + configBuilder.append("\ncolor-depth=").append(options.colorDepthAsInt()) //$NON-NLS-1$ + .append("\ndisable-effects=").append(options.disableEffectsAsString()); //$NON-NLS-1$ + } + + if (!StringHelper.isNullOrEmpty(options.getSpiceProxy())) { + configBuilder.append("\nproxy=").append(options.getSpiceProxy()); //$NON-NLS-1$ + } + + if (!StringHelper.isNullOrEmpty(options.getSslChanels())) { + configBuilder.append("\nsecure-channels=").append(formatSecureChannels(options.getSslChanels())); //$NON-NLS-1$ + } + + return configBuilder.toString(); + } + + private static int boolToInt(Boolean b) { + return (Boolean.TRUE.equals(b)) + ? 1 + : 0; + } + + private static String graphicsTypeToString(GraphicsType graphicsType) { + if (graphicsType == null) { + return null; + } + + switch (graphicsType) { + case SPICE: + return "spice"; + case VNC: + return "vnc"; + default: + return null; + } + } + + /** + * Reformats the secure channels - the .vv file accepts semicolon-separated values (unlike SPICE browser plugin). + */ + private static String formatSecureChannels(String sslChanels) { + return (sslChanels == null) + ? "" //$NON-NLS-1$ + : sslChanels.replace(',', ';'); + } + +} diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java index d4534a0..f90e175 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java @@ -374,6 +374,7 @@ GetGraphicsDevices(VdcQueryAuthType.User), ConfigureConsoleOptions(VdcQueryAuthType.User), + GetConsoleDescriptorFile(VdcQueryAuthType.User), GetDeviceCustomProperties(VdcQueryAuthType.User), diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/uicommon/SpiceNativeImpl.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/uicommon/SpiceNativeImpl.java index 090e314..8ddc366 100644 --- a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/uicommon/SpiceNativeImpl.java +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/uicommon/SpiceNativeImpl.java @@ -1,98 +1,29 @@ package org.ovirt.engine.ui.common.uicommon; -import org.ovirt.engine.core.common.console.ConsoleOptions; -import org.ovirt.engine.core.compat.StringHelper; +import org.ovirt.engine.core.common.queries.ConsoleOptionsParams; +import org.ovirt.engine.core.common.queries.VdcQueryReturnValue; +import org.ovirt.engine.core.common.queries.VdcQueryType; +import org.ovirt.engine.ui.frontend.AsyncQuery; +import org.ovirt.engine.ui.frontend.Frontend; +import org.ovirt.engine.ui.frontend.INewAsyncCallback; import org.ovirt.engine.ui.uicommonweb.models.vms.ConsoleModel; import org.ovirt.engine.ui.uicommonweb.models.vms.ISpiceNative; public class SpiceNativeImpl extends AbstractSpice implements ISpiceNative { - public SpiceNativeImpl() { - super(); - } - @Override public void invokeClient() { - ConsoleOptions options = getOptions(); - StringBuilder configBuilder = new StringBuilder("[virt-viewer]"); //$NON-NLS-1$ + AsyncQuery callback = new AsyncQuery(this, new INewAsyncCallback() { + @Override + public void onSuccess(Object model, Object returnValue) { // todo avoid code duplication with vnc + ConsoleModel.makeConsoleConfigRequest("console.vv", //$NON-NLS-1$ + "application/x-virt-viewer; charset=UTF-8", //$NON-NLS-1$ + (String) ((VdcQueryReturnValue) returnValue).getReturnValue()); + } + }); - int fullscreen = 0; - if (options.isFullScreen()) { - fullscreen = 1; - } - - int enableSmartcard = 0; - if (options.isSmartcardEnabled()) { - enableSmartcard = 1; - } - - int usbAutoShare = 0; - if (options.isUsbAutoShare()) { - usbAutoShare = 1; - } - - configBuilder.append("\ntype=spice") //$NON-NLS-1$ - .append("\nhost=").append(options.getHost()) //$NON-NLS-1$ - .append("\nport=").append(options.getPort()) //$NON-NLS-1$ - .append("\npassword=").append(options.getTicket())//$NON-NLS-1$ - .append("\n# Password is valid for ").append(ConsoleOptions.TICKET_VALIDITY_SECONDS).append(" seconds.") //$$NON-NLS-1$NON-NLS-2$ - .append("\ntls-port=").append(getOptions().getSecurePort()) //$NON-NLS-1$ - .append("\nfullscreen=").append(fullscreen) //$NON-NLS-1$ - .append("\ntitle=").append(options.getTitle()) //$NON-NLS-1$ - .append("\nenable-smartcard=").append(enableSmartcard) //$NON-NLS-1$ - .append("\nenable-usb-autoshare=").append(usbAutoShare) //$NON-NLS-1$ - .append("\ndelete-this-file=1") //$NON-NLS-1$ - .append("\nusb-filter=").append(options.getUsbFilter()); //$NON-NLS-1$ - - if (options.getCipherSuite() != null) { - configBuilder.append("\ntls-ciphers=").append(options.getCipherSuite()); //$NON-NLS-1$ - } - - if (!StringHelper.isNullOrEmpty(options.getHostSubject())) { - configBuilder.append("\nhost-subject=").append(options.getHostSubject()); //$NON-NLS-1$ - } - - if (options.getTrustStore() != null) { - //virt-viewer-file doesn't want newlines in ca - String trustStore= options.getTrustStore().replace("\n", "\\n"); //$NON-NLS-1$ $NON-NLS-2$ - configBuilder.append("\nca=").append(trustStore); //$NON-NLS-1$ - } - - if (options.isWanOptionsEnabled()) { - configBuilder.append("\ncolor-depth=").append(options.colorDepthAsInt()) //$NON-NLS-1$ - .append("\ndisable-effects=").append(options.disableEffectsAsString()); //$NON-NLS-1$ - } - - if (!StringHelper.isNullOrEmpty(options.getToggleFullscreenHotKey())) { - configBuilder.append("\ntoggle-fullscreen=").append(options.getToggleFullscreenHotKey()); //$NON-NLS-1$ - } - - if (!StringHelper.isNullOrEmpty(options.getReleaseCursorHotKey())) { - configBuilder.append("\nrelease-cursor=").append(options.getReleaseCursorHotKey()); //$NON-NLS-1$ - } - - if (options.isRemapCtrlAltDelete()) { - configBuilder.append("\nsecure-attention=").append(ConsoleOptions.SECURE_ATTENTION_MAPPING); //$NON-NLS-1$ - } - - if (!StringHelper.isNullOrEmpty(options.getSpiceProxy())) { - configBuilder.append("\nproxy=").append(options.getSpiceProxy()); //$NON-NLS-1$ - } - - if (!StringHelper.isNullOrEmpty(options.getSslChanels())) { - configBuilder.append("\nsecure-channels=").append(formatSecureChannels(getOptions().getSslChanels())); //$NON-NLS-1$ - } - - ConsoleModel.makeConsoleConfigRequest("console.vv", "application/x-virt-viewer; charset=UTF-8", configBuilder.toString()); //$NON-NLS-1$ $NON-NLS-2$ + Frontend.getInstance().runQuery( + VdcQueryType.GetConsoleDescriptorFile, + new ConsoleOptionsParams(getOptions()), callback); } - - /** - * Reformats the secure channels - the .vv file accepts semicolon-separated values (unlike SPICE browser plugin). - */ - private static String formatSecureChannels(String sslChanels) { - return (sslChanels == null) - ? "" //$NON-NLS-1$ - : sslChanels.replace(',', ';'); - } - } diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/uicommon/VncNativeImpl.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/uicommon/VncNativeImpl.java index 70e6741..91ad19c 100644 --- a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/uicommon/VncNativeImpl.java +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/uicommon/VncNativeImpl.java @@ -1,7 +1,11 @@ package org.ovirt.engine.ui.common.uicommon; -import org.ovirt.engine.core.common.console.ConsoleOptions; -import org.ovirt.engine.core.compat.StringHelper; +import org.ovirt.engine.core.common.queries.ConsoleOptionsParams; +import org.ovirt.engine.core.common.queries.VdcQueryReturnValue; +import org.ovirt.engine.core.common.queries.VdcQueryType; +import org.ovirt.engine.ui.frontend.AsyncQuery; +import org.ovirt.engine.ui.frontend.Frontend; +import org.ovirt.engine.ui.frontend.INewAsyncCallback; import org.ovirt.engine.ui.uicommonweb.models.vms.ConsoleModel; import org.ovirt.engine.ui.uicommonweb.models.vms.IVnc; @@ -9,31 +13,18 @@ @Override public void invokeClient() { - ConsoleOptions options = getOptions(); - StringBuilder configBuilder = new StringBuilder("[virt-viewer]"); //$NON-NLS-1$ - configBuilder.append("\ntype=vnc") //$NON-NLS-1$ - .append("\nhost=").append(options.getHost()) //$NON-NLS-1$ - .append("\nport=").append(options.getPort()) //$NON-NLS-1$ - .append("\npassword=").append(options.getTicket()) //$NON-NLS-1$ - .append("\n# Password is valid for ") //$NON-NLS-1$ - .append(ConsoleOptions.TICKET_VALIDITY_SECONDS).append(" seconds.") //$NON-NLS-1$ - .append("\ndelete-this-file=1") //$NON-NLS-1$ - .append("\ntitle=").append(options.getTitle()); //$NON-NLS-1$ + AsyncQuery callback = new AsyncQuery(this, new INewAsyncCallback() { + @Override + public void onSuccess(Object model, Object returnValue) { // todo avoid code duplication with spice + ConsoleModel.makeConsoleConfigRequest("console.vv", //$NON-NLS-1$ + "application/x-virt-viewer; charset=UTF-8", //$NON-NLS-1$ + (String) ((VdcQueryReturnValue) returnValue).getReturnValue()); + } + }); - if (!StringHelper.isNullOrEmpty(options.getToggleFullscreenHotKey())) { - configBuilder.append("\ntoggle-fullscreen=").append(options.getToggleFullscreenHotKey()); //$NON-NLS-1$ - } - - String releaseCursorHotKey = options.getReleaseCursorHotKey(); - if (!StringHelper.isNullOrEmpty(releaseCursorHotKey)) { - configBuilder.append("\nrelease-cursor=").append(releaseCursorHotKey); //$NON-NLS-1$ - } - - if (options.isRemapCtrlAltDelete()) { - configBuilder.append("\nsecure-attention=").append(ConsoleOptions.SECURE_ATTENTION_MAPPING); //$NON-NLS-1$ - } - - ConsoleModel.makeConsoleConfigRequest("console.vv", "application/x-virt-viewer; charset=UTF-8", configBuilder.toString()); //$NON-NLS-1$ $NON-NLS-2$ + Frontend.getInstance().runQuery( + VdcQueryType.GetConsoleDescriptorFile, + new ConsoleOptionsParams(getOptions()), callback); } } -- To view, visit http://gerrit.ovirt.org/37975 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I4a0f882f8936fe49d7231eb42d67fe374e28ccb5 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Frank Kobzik <fkob...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches