From 12f52bdd224b67106fc50c36ec7ddff73b6151a2 Mon Sep 17 00:00:00 2001 From: serge-rider Date: Sun, 14 Mar 2021 09:58:40 +0300 Subject: [PATCH] CB-750 Complex value transfer API --- .../io/cloudbeaver/server/CBApplication.java | 2 +- .../service/WebServiceServletBase.java | 46 ++++++++++ .../service/sql/WebSQLResultServlet.java | 66 ++++++++++++++ .../cloudbeaver/service/sql/WebSQLUtils.java | 65 ++++++++++---- .../service/sql/WebServiceBindingSQL.java | 13 ++- .../admin/impl/WebAdminLogsServlet.java | 73 +++++++-------- .../transfer/impl/WebDataTransferServlet.java | 90 ++++++++----------- .../transfer/impl/WebDataTransferUtils.java | 4 +- 8 files changed, 241 insertions(+), 118 deletions(-) create mode 100644 server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/WebServiceServletBase.java create mode 100644 server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLResultServlet.java diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBApplication.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBApplication.java index 8e910da128..2deca20080 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBApplication.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBApplication.java @@ -224,7 +224,7 @@ public class CBApplication extends BaseApplicationImpl { log.debug("\tContent root: " + new File(contentRoot).getAbsolutePath()); log.debug("\tDrivers storage: " + new File(driversLocation).getAbsolutePath()); //log.debug("\tDrivers root: " + driversLocation); - log.debug("\tProduct details: " + application.getInfoDetails()); + //log.debug("\tProduct details: " + application.getInfoDetails()); log.debug("\tBase port: " + serverPort); log.debug("\tBase URI: " + servicesURI); if (develMode) { diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/WebServiceServletBase.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/WebServiceServletBase.java new file mode 100644 index 0000000000..58f68f9f4a --- /dev/null +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/WebServiceServletBase.java @@ -0,0 +1,46 @@ +package io.cloudbeaver.service; + +import io.cloudbeaver.model.session.WebSession; +import io.cloudbeaver.server.CBApplication; +import io.cloudbeaver.server.CBPlatform; +import org.jkiss.dbeaver.DBException; +import org.jkiss.dbeaver.Log; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public abstract class WebServiceServletBase extends HttpServlet { + + private static final Log log = Log.getLog(WebServiceServletBase.class); + + private final CBApplication application; + + public WebServiceServletBase(CBApplication application) { + this.application = application; + } + + public CBApplication getApplication() { + return application; + } + + @Override + protected final void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + WebSession webSession = CBPlatform.getInstance().getSessionManager().findWebSession(request); + if (webSession == null) { + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Web session not found"); + return; + } + try { + processServiceRequest(webSession, request, response); + } catch (Exception e) { + log.error(e); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Error processing request: " + e.getMessage()); + } + } + + protected abstract void processServiceRequest(WebSession session, HttpServletRequest request, HttpServletResponse response) throws DBException, IOException; + +} \ No newline at end of file diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLResultServlet.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLResultServlet.java new file mode 100644 index 0000000000..7919365c08 --- /dev/null +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLResultServlet.java @@ -0,0 +1,66 @@ +package io.cloudbeaver.service.sql; + +import io.cloudbeaver.DBWebException; +import io.cloudbeaver.model.session.WebSession; +import io.cloudbeaver.server.CBApplication; +import io.cloudbeaver.service.WebServiceServletBase; +import org.jkiss.dbeaver.DBException; +import org.jkiss.dbeaver.Log; +import org.jkiss.utils.CommonUtils; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class WebSQLResultServlet extends WebServiceServletBase { + + private static final Log log = Log.getLog(WebSQLResultServlet.class); + + // context-id/result-id/row-number/attribute-name + private static final Pattern URL_PATTERN = Pattern.compile("/?([\\w]+)/([0-9]+)/([0-9]+)/([0-9]+)/(.+)[/\\?]?"); + + private final DBWServiceSQL sqlService; + + public WebSQLResultServlet(CBApplication application, DBWServiceSQL sqlService) { + super(application); + this.sqlService = sqlService; + } + + @Override + protected void processServiceRequest(WebSession session, HttpServletRequest request, HttpServletResponse response) throws DBException, IOException { + + String valuePath = request.getPathInfo(); + if (CommonUtils.isEmpty(valuePath)) { + throw new DBWebException("Result value ID not specified"); + } + Matcher urlMatcher = URL_PATTERN.matcher(valuePath); + if (!urlMatcher.matches()) { + throw new DBWebException("Invalid URI format"); + } + + String connectionId = urlMatcher.group(1); + String contextId = urlMatcher.group(2); + String resultsId = urlMatcher.group(3); + String rowNum = urlMatcher.group(4); + String attrName = urlMatcher.group(5); + + //sqlService. +/* + response.setHeader("Content-Type", processor.getContentType()); + response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\""); + response.setHeader("Content-Length", String.valueOf(dataFile.length())); + + try (InputStream is = new FileInputStream(dataFile)) { + IOUtils.copyStream(is, response.getOutputStream()); + } + + // TODO: cleanup export files ASAP? + if (false) { + dtConfig.removeTask(taskInfo); + } +*/ + } + +} \ No newline at end of file diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLUtils.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLUtils.java index 9ed47f73be..e78e2e7d23 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLUtils.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLUtils.java @@ -18,6 +18,7 @@ package io.cloudbeaver.service.sql; import io.cloudbeaver.model.session.WebSession; import io.cloudbeaver.server.CBConstants; +import org.jkiss.code.NotNull; import org.jkiss.dbeaver.Log; import org.jkiss.dbeaver.model.data.*; import org.jkiss.dbeaver.model.exec.DBCException; @@ -25,14 +26,12 @@ import org.jkiss.dbeaver.model.gis.DBGeometry; import org.jkiss.dbeaver.model.struct.DBSAttributeBase; import org.jkiss.dbeaver.model.struct.DBSTypedObject; import org.jkiss.dbeaver.utils.ContentUtils; +import org.jkiss.dbeaver.utils.GeneralUtils; import org.jkiss.utils.CommonUtils; import java.io.ByteArrayOutputStream; import java.nio.charset.StandardCharsets; -import java.util.Collections; -import java.util.Date; -import java.util.LinkedHashMap; -import java.util.Map; +import java.util.*; /** * Web SQL utils. @@ -41,6 +40,8 @@ public class WebSQLUtils { private static final Log log = Log.getLog(WebSQLUtils.class); + public static final int BINARY_PREVIEW_LENGTH = 255; + public static Object makeWebCellValue(WebSession session, DBSTypedObject type, Object cellValue, WebDataFormat dataFormat) throws DBCException { if (cellValue instanceof Date) { return CBConstants.ISO_DATE_FORMAT.format(cellValue); @@ -51,11 +52,7 @@ public class WebSQLUtils { return null; } else if (dbValue instanceof DBDDocument) { - if (dataFormat != WebDataFormat.document) { - return serializeDocumentValue((DBDDocument) dbValue); - } else { - return serializeDocumentValue(session, (DBDDocument) dbValue); - } + return serializeDocumentValue(session, (DBDDocument) dbValue); } else if (dbValue instanceof DBDComplexValue) { return serializeComplexValue(session, (DBDComplexValue)dbValue, dataFormat); } else if (dbValue instanceof DBGeometry) { @@ -75,18 +72,31 @@ public class WebSQLUtils { for (int i = 0; i < size; i++) { items[i] = makeWebCellValue(session, collection.getComponentType(), collection.getItem(i), dataFormat); } - return items; + + Map map = createMapOfType("collection"); + map.put("value", items); + return map; } else if (value instanceof DBDComposite) { DBDComposite composite = (DBDComposite)value; - Map map = new LinkedHashMap<>(); + Map struct = new LinkedHashMap<>(); for (DBSAttributeBase attr : composite.getAttributes()) { - map.put(attr.getName(), makeWebCellValue(session, attr, composite.getAttributeValue(attr), dataFormat)); + struct.put(attr.getName(), makeWebCellValue(session, attr, composite.getAttributeValue(attr), dataFormat)); } + + Map map = createMapOfType("map"); + map.put("value", struct); return map; } return value.toString(); } + @NotNull + private static Map createMapOfType(String type) { + Map map = new LinkedHashMap<>(); + map.put("$type", type); + return map; + } + private static Map serializeDocumentValue(WebSession session, DBDDocument document) throws DBCException { String documentData; try { @@ -97,7 +107,7 @@ public class WebSQLUtils { throw new DBCException("Error serializing document", e); } - Map map = new LinkedHashMap<>(); + Map map = createMapOfType("document"); map.put("id", CommonUtils.toString(document.getDocumentId())); map.put("contentType", document.getDocumentContentType()); map.put("properties", Collections.emptyMap()); @@ -106,15 +116,34 @@ public class WebSQLUtils { } private static Object serializeContentValue(WebSession session, DBDContent value) throws DBCException { - return ContentUtils.getContentStringValue(session.getProgressMonitor(), value); - } - private static Object serializeDocumentValue(DBDDocument value) { - return value; + Map map = createMapOfType("content"); + if (ContentUtils.isTextContent(value)) { + String stringValue = ContentUtils.getContentStringValue(session.getProgressMonitor(), value); + map.put("text", stringValue); + } else { + map.put("binary", true); + byte[] binaryValue = ContentUtils.getContentBinaryValue(session.getProgressMonitor(), value); + if (binaryValue != null) { + if (binaryValue.length > BINARY_PREVIEW_LENGTH) { + binaryValue = Arrays.copyOf(binaryValue, BINARY_PREVIEW_LENGTH); + } + map.put("text", GeneralUtils.convertToString(binaryValue, 0, binaryValue.length)); + } else { + map.put("text", null); + } + } + map.put("contentType", value.getContentType()); + map.put("contentLength", value.getContentLength()); + return map; } private static Object serializeGeometryValue(DBGeometry value) { - return value.toString(); + Map map = createMapOfType("geometry"); + map.put("srid", value.getSRID()); + map.put("text", value.toString()); + map.put("properties", value.getProperties()); + return map; } } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebServiceBindingSQL.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebServiceBindingSQL.java index 87d4b7d2d6..6246ecf37a 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebServiceBindingSQL.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebServiceBindingSQL.java @@ -20,9 +20,13 @@ import graphql.schema.DataFetchingEnvironment; import io.cloudbeaver.DBWebException; import io.cloudbeaver.model.WebConnectionInfo; import io.cloudbeaver.model.session.WebSession; +import io.cloudbeaver.server.CBApplication; import io.cloudbeaver.service.DBWBindingContext; +import io.cloudbeaver.service.DBWServiceBindingServlet; import io.cloudbeaver.service.WebServiceBindingBase; import io.cloudbeaver.service.sql.impl.WebServiceSQL; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; import org.jkiss.dbeaver.DBException; import org.jkiss.utils.CommonUtils; @@ -34,7 +38,7 @@ import java.util.stream.Collectors; /** * Web service implementation */ -public class WebServiceBindingSQL extends WebServiceBindingBase { +public class WebServiceBindingSQL extends WebServiceBindingBase implements DBWServiceBindingServlet { public WebServiceBindingSQL() { super(DBWServiceSQL.class, new WebServiceSQL(), "schema/service.sql.graphqls"); @@ -133,6 +137,13 @@ public class WebServiceBindingSQL extends WebServiceBindingBase { return context; } + @Override + public void addServlets(CBApplication application, ServletContextHandler servletContextHandler) { + servletContextHandler.addServlet( + new ServletHolder("sqlResultValueViewer", new WebSQLResultServlet(application, getServiceImpl())), + application.getServicesURI() + "sql-result-value/*"); + } + private static class WebSQLConfiguration { private final Map processors = new HashMap<>(); diff --git a/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/impl/WebAdminLogsServlet.java b/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/impl/WebAdminLogsServlet.java index e2bc27b89c..afc10e854d 100644 --- a/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/impl/WebAdminLogsServlet.java +++ b/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/impl/WebAdminLogsServlet.java @@ -4,15 +4,14 @@ import io.cloudbeaver.DBWConstants; import io.cloudbeaver.DBWebException; import io.cloudbeaver.model.session.WebSession; import io.cloudbeaver.server.CBApplication; -import io.cloudbeaver.server.CBPlatform; +import io.cloudbeaver.service.WebServiceServletBase; +import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.Log; import org.jkiss.dbeaver.model.DBConstants; import org.jkiss.dbeaver.utils.GeneralUtils; import org.jkiss.dbeaver.utils.MimeTypes; import org.jkiss.utils.IOUtils; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; @@ -20,55 +19,43 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; -public class WebAdminLogsServlet extends HttpServlet { +public class WebAdminLogsServlet extends WebServiceServletBase { private static final Log log = Log.getLog(WebAdminLogsServlet.class); - private final CBApplication application; - public WebAdminLogsServlet(CBApplication application) { - this.application = application; + super(application); } @Override - protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - try { - WebSession webSession = CBPlatform.getInstance().getSessionManager().findWebSession(request); - if (webSession == null) { - throw new DBWebException("No active session"); - } - if (!webSession.hasPermission(DBWConstants.PERMISSION_ADMIN)) { - response.sendError(HttpServletResponse.SC_FORBIDDEN, "Logs accessible for admins only"); - return; - } - - String logId = request.getPathInfo(); - String logFileName = ".log"; - if ("debug".equals(logId)) { - logFileName = DBConstants.DEBUG_LOG_FILE_NAME; - } - if (logFileName.contains("/") || logFileName.contains("\\")) { - throw new DBWebException("Bad log file name"); - } - File logFile = new File(GeneralUtils.getMetadataFolder(), logFileName); - if (!logFile.exists()) { - throw new DBWebException("Log file '" + logFileName + "' not found"); - } - - response.setHeader("Content-Type", MimeTypes.TEXT_PLAIN); - if (logFileName.equals(".log")) { - logFileName = "server.log"; - } - response.setHeader("Content-Disposition", "attachment; filename=\"" + logFileName + "\""); - - try (InputStream is = new FileInputStream(logFile)) { - IOUtils.copyStream(is, response.getOutputStream()); - } - } catch (Exception e) { - log.error(e); - response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Error reading log: " + e.getMessage()); + protected void processServiceRequest(WebSession session, HttpServletRequest request, HttpServletResponse response) throws DBException, IOException { + if (!session.hasPermission(DBWConstants.PERMISSION_ADMIN)) { + response.sendError(HttpServletResponse.SC_FORBIDDEN, "Logs accessible for admins only"); return; } + + String logId = request.getPathInfo(); + String logFileName = ".log"; + if ("debug".equals(logId)) { + logFileName = DBConstants.DEBUG_LOG_FILE_NAME; + } + if (logFileName.contains("/") || logFileName.contains("\\")) { + throw new DBWebException("Bad log file name"); + } + File logFile = new File(GeneralUtils.getMetadataFolder(), logFileName); + if (!logFile.exists()) { + throw new DBWebException("Log file '" + logFileName + "' not found"); + } + + response.setHeader("Content-Type", MimeTypes.TEXT_PLAIN); + if (logFileName.equals(".log")) { + logFileName = "server.log"; + } + response.setHeader("Content-Disposition", "attachment; filename=\"" + logFileName + "\""); + + try (InputStream is = new FileInputStream(logFile)) { + IOUtils.copyStream(is, response.getOutputStream()); + } } } \ No newline at end of file diff --git a/server/bundles/io.cloudbeaver.service.data.transfer/src/io/cloudbeaver/service/data/transfer/impl/WebDataTransferServlet.java b/server/bundles/io.cloudbeaver.service.data.transfer/src/io/cloudbeaver/service/data/transfer/impl/WebDataTransferServlet.java index ba9d730409..f787740570 100644 --- a/server/bundles/io.cloudbeaver.service.data.transfer/src/io/cloudbeaver/service/data/transfer/impl/WebDataTransferServlet.java +++ b/server/bundles/io.cloudbeaver.service.data.transfer/src/io/cloudbeaver/service/data/transfer/impl/WebDataTransferServlet.java @@ -1,18 +1,17 @@ package io.cloudbeaver.service.data.transfer.impl; import io.cloudbeaver.DBWebException; -import io.cloudbeaver.server.CBPlatform; -import io.cloudbeaver.server.CBApplication; import io.cloudbeaver.model.session.WebSession; +import io.cloudbeaver.server.CBApplication; +import io.cloudbeaver.service.WebServiceServletBase; import io.cloudbeaver.service.data.transfer.DBWServiceDataTransfer; +import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.Log; import org.jkiss.dbeaver.tools.transfer.registry.DataTransferProcessorDescriptor; import org.jkiss.dbeaver.tools.transfer.registry.DataTransferRegistry; import org.jkiss.utils.CommonUtils; import org.jkiss.utils.IOUtils; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; @@ -20,69 +19,56 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; -public class WebDataTransferServlet extends HttpServlet { +public class WebDataTransferServlet extends WebServiceServletBase { private static final Log log = Log.getLog(WebDataTransferServlet.class); - private final CBApplication application; private final DBWServiceDataTransfer dtManager; public WebDataTransferServlet(CBApplication application, DBWServiceDataTransfer dtManager) { - this.application = application; + super(application); this.dtManager = dtManager; } @Override - protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - try { - String dataFileId = request.getPathInfo(); - if (CommonUtils.isEmpty(dataFileId)) { - throw new DBWebException("Data ID not specified"); - } - while (dataFileId.startsWith("/")) { - dataFileId = dataFileId.substring(1); - } + protected void processServiceRequest(WebSession session, HttpServletRequest request, HttpServletResponse response) throws DBException, IOException { + String dataFileId = request.getPathInfo(); + if (CommonUtils.isEmpty(dataFileId)) { + throw new DBWebException("Data ID not specified"); + } + while (dataFileId.startsWith("/")) { + dataFileId = dataFileId.substring(1); + } - WebSession webSession = CBPlatform.getInstance().getSessionManager().findWebSession(request); - if (webSession == null) { - throw new DBWebException("No active session"); - } - WebDataTransferSessionConfig dtConfig = WebDataTransferUtils.getSessionDataTransferConfig(webSession); - WebDataTransferTaskConfig taskInfo = dtConfig.getTask(dataFileId); - if (taskInfo == null) { - throw new DBWebException("Session task '" + dataFileId + "' not found"); - } - DataTransferProcessorDescriptor processor = DataTransferRegistry.getInstance().getProcessor(taskInfo.getParameters().getProcessorId()); - if (processor == null) { - throw new DBWebException("Wrong data processor '" + taskInfo.getParameters().getProcessorId() + "'"); - } - String fileName = taskInfo.getExportFileName(); - if (!CommonUtils.isEmpty(fileName)) { - fileName += "." + WebDataTransferUtils.getProcessorFileExtension(processor); - } else { - fileName = taskInfo.getDataFileId(); - } + WebDataTransferSessionConfig dtConfig = WebDataTransferUtils.getSessionDataTransferConfig(session); + WebDataTransferTaskConfig taskInfo = dtConfig.getTask(dataFileId); + if (taskInfo == null) { + throw new DBWebException("Session task '" + dataFileId + "' not found"); + } + DataTransferProcessorDescriptor processor = DataTransferRegistry.getInstance().getProcessor(taskInfo.getParameters().getProcessorId()); + if (processor == null) { + throw new DBWebException("Wrong data processor '" + taskInfo.getParameters().getProcessorId() + "'"); + } + String fileName = taskInfo.getExportFileName(); + if (!CommonUtils.isEmpty(fileName)) { + fileName += "." + WebDataTransferUtils.getProcessorFileExtension(processor); + } else { + fileName = taskInfo.getDataFileId(); + } - File dataFile = taskInfo.getDataFile(); + File dataFile = taskInfo.getDataFile(); - response.setHeader("Content-Type", processor.getContentType()); - response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\""); - response.setHeader("Content-Length", String.valueOf(dataFile.length())); + response.setHeader("Content-Type", processor.getContentType()); + response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\""); + response.setHeader("Content-Length", String.valueOf(dataFile.length())); - try (InputStream is = new FileInputStream(dataFile)) { - IOUtils.copyStream(is, response.getOutputStream()); - } + try (InputStream is = new FileInputStream(dataFile)) { + IOUtils.copyStream(is, response.getOutputStream()); + } - // TODO: cleanup export files ASAP? - if (false) { - dtConfig.removeTask(taskInfo); - } - - //response.ok(HttpServletResponse.SC_BAD_REQUEST, "Not implemented"); - } catch (Exception e) { - log.error(e); - response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Error reading data: " + e.getMessage()); - return; + // TODO: cleanup export files ASAP? + if (false) { + dtConfig.removeTask(taskInfo); } } diff --git a/server/bundles/io.cloudbeaver.service.data.transfer/src/io/cloudbeaver/service/data/transfer/impl/WebDataTransferUtils.java b/server/bundles/io.cloudbeaver.service.data.transfer/src/io/cloudbeaver/service/data/transfer/impl/WebDataTransferUtils.java index 79c88ef71f..40641112cf 100644 --- a/server/bundles/io.cloudbeaver.service.data.transfer/src/io/cloudbeaver/service/data/transfer/impl/WebDataTransferUtils.java +++ b/server/bundles/io.cloudbeaver.service.data.transfer/src/io/cloudbeaver/service/data/transfer/impl/WebDataTransferUtils.java @@ -6,9 +6,7 @@ import org.jkiss.dbeaver.model.preferences.DBPPropertyDescriptor; import org.jkiss.dbeaver.tools.transfer.registry.DataTransferProcessorDescriptor; import org.jkiss.utils.CommonUtils; -import javax.servlet.http.HttpServlet; - -public class WebDataTransferUtils extends HttpServlet { +class WebDataTransferUtils { private static final Log log = Log.getLog(WebDataTransferUtils.class);