package org.ovirt.engine.api.restapi.resource;
import static org.ovirt.engine.api.restapi.resource.BackendGraphicsConsoleHelper.asGraphicsType;
import java.nio.charset.StandardCharsets;
import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
import org.ovirt.engine.api.model.Action;
import org.ovirt.engine.api.model.GraphicsConsole;
import org.ovirt.engine.api.model.GraphicsType;
import org.ovirt.engine.api.model.ProxyTicket;
import org.ovirt.engine.api.resource.ActionResource;
import org.ovirt.engine.api.resource.ApiMediaType;
import org.ovirt.engine.api.resource.VmGraphicsConsoleResource;
import org.ovirt.engine.api.restapi.logging.Messages;
import org.ovirt.engine.api.restapi.types.VmMapper;
import org.ovirt.engine.api.restapi.utils.HexUtils;
import org.ovirt.engine.core.common.console.ConsoleOptions;
import org.ovirt.engine.core.common.errors.EngineMessage;
import org.ovirt.engine.core.common.queries.ConfigureConsoleOptionsParams;
import org.ovirt.engine.core.common.queries.ConsoleOptionsParams;
import org.ovirt.engine.core.common.queries.GetSignedWebsocketProxyTicketParams;
import org.ovirt.engine.core.common.queries.VdcQueryReturnValue;
import org.ovirt.engine.core.common.queries.VdcQueryType;
import org.ovirt.engine.core.compat.Guid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class BackendVmGraphicsConsoleResource
extends AbstractBackendActionableResource<GraphicsConsole, org.ovirt.engine.core.common.businessentities.GraphicsType>
implements VmGraphicsConsoleResource {
private static final Logger log = LoggerFactory.getLogger(BackendVmGraphicsConsoleResource.class);
private BackendVmGraphicsConsolesResource parent;
private Guid guid;
private String consoleId;
public BackendVmGraphicsConsoleResource(BackendVmGraphicsConsolesResource parent, Guid vmGuid, String consoleId) {
super(consoleId, GraphicsConsole.class, org.ovirt.engine.core.common.businessentities.GraphicsType.class);
this.parent = parent;
this.guid = vmGuid;
this.consoleId = consoleId;
}
private VdcQueryReturnValue generateDescriptorResponse() throws Exception {
org.ovirt.engine.core.common.businessentities.GraphicsType graphicsType =
BackendGraphicsConsoleHelper.asGraphicsType(consoleId);
ConsoleOptions consoleOptions = new ConsoleOptions(graphicsType);
consoleOptions.setVmId(guid);
VdcQueryReturnValue configuredOptionsReturnValue = runQuery(
VdcQueryType.ConfigureConsoleOptions,
new ConfigureConsoleOptionsParams(consoleOptions, true)
);
if (!configuredOptionsReturnValue.getSucceeded()) {
throw new Exception(configuredOptionsReturnValue.getExceptionString());
}
return runQuery(
VdcQueryType.GetConsoleDescriptorFile,
new ConsoleOptionsParams(configuredOptionsReturnValue.getReturnValue())
);
}
/**
* A method handling GET requests with media type x-virt-viewer.
* Returns a console representation usable by virt-viewer client (e.g. a .vv file)
*
* @return a console representation for virt-viewer (e.g. a .vv file)
*/
@GET
@Produces(ApiMediaType.APPLICATION_X_VIRT_VIEWER)
public Response generateDescriptor() {
try {
VdcQueryReturnValue consoleDescriptorReturnValue = generateDescriptorResponse();
Response.ResponseBuilder builder;
if (consoleDescriptorReturnValue.getSucceeded() && consoleDescriptorReturnValue.getReturnValue() != null) {
builder = Response.ok(((String) consoleDescriptorReturnValue.getReturnValue())
.getBytes(StandardCharsets.UTF_8), ApiMediaType.APPLICATION_X_VIRT_VIEWER);
} else {
builder = Response.noContent();
}
return builder.build();
} catch (Exception ex) {
return handleConfigureConsoleError(ex.getMessage());
}
}
@Override
public Response remoteViewerConnectionFile(Action action) {
try {
VdcQueryReturnValue consoleDescriptorReturnValue = generateDescriptorResponse();
Response.ResponseBuilder builder;
if (consoleDescriptorReturnValue.getSucceeded() && consoleDescriptorReturnValue.getReturnValue() != null) {
action.setRemoteViewerConnectionFile(consoleDescriptorReturnValue.getReturnValue());
builder = Response.ok().entity(action);
} else {
builder = Response.noContent();
}
return builder.build();
} catch (Exception ex) {
return handleConfigureConsoleError(ex.getMessage());
}
}
private Response handleConfigureConsoleError(String exceptionMessage) {
log.error(localize(Messages.BACKEND_FAILED_TEMPLATE, exceptionMessage));
if (EngineMessage.USER_CANNOT_FORCE_RECONNECT_TO_VM.name().equals(exceptionMessage)) {
return Response.status(Response.Status.FORBIDDEN).build();
}
return Response.serverError().build();
}
@Override
public Response ticket(Action action) {
return BackendGraphicsConsoleHelper.setTicket(this, action, guid, asGraphicsType(consoleId));
}
@Override
public Response proxyTicket(Action action) {
final String plainConsoleId = HexUtils.hex2string(consoleId);
final GraphicsType graphicsTypeModel = GraphicsType.fromValue(plainConsoleId);
final org.ovirt.engine.core.common.businessentities.GraphicsType graphicsTypeEntity =
VmMapper.map(graphicsTypeModel, null);
final String ticketValue = getTicket(graphicsTypeEntity);
if (!action.isSetProxyTicket()) {
action.setProxyTicket(new ProxyTicket());
}
action.getProxyTicket().setValue(ticketValue);
return Response.ok().entity(action).build();
}
private String getTicket(org.ovirt.engine.core.common.businessentities.GraphicsType graphicsTypeEntity) {
final GetSignedWebsocketProxyTicketParams params =
new GetSignedWebsocketProxyTicketParams(guid, graphicsTypeEntity);
final VdcQueryReturnValue ticketQueryReturnValue =
runQuery(VdcQueryType.GetSignedWebsocketProxyTicket, params);
if (!ticketQueryReturnValue.getSucceeded()) {
try {
backendFailure(ticketQueryReturnValue.getExceptionString());
} catch (BackendFailureException ex) {
handleError(ex, false);
}
}
return ticketQueryReturnValue.getReturnValue();
}
@Override
public ActionResource getActionResource(String action, String oid) {
return inject(new BackendActionResource(action, oid));
}
@Override
public GraphicsConsole get() {
return BackendGraphicsConsoleHelper.get(parent::list, consoleId);
}
@Override
public Response remove() {
return BackendGraphicsConsoleHelper.remove(this, guid, consoleId);
}
@Override
protected Guid asGuidOr404(String id) {
return null;
}
}