通过自定义servlet通过Avatica公开基于Calcite的数据库

时间:2017-10-17 14:16:12

标签: java jdbc jira apache-calcite

我使用方解石帮助构建了自定义架构。现在我想通过servlet公开它并用Avatica连接它。我正在使用servlet,因为我的容器是JIRA。以下是来自servlet的一些相关代码

public class JDBCServlet extends HttpServlet {

private final Service service;
private final ProtobufHandler pbHandler;
private final ProtobufTranslation protobufTranslation;
private final MetricsSystem metrics;

final ThreadLocal<UnsynchronizedBuffer> threadLocalBuffer;

public JDBCServlet(LocalDBProvider provider) {
    this.service = provider.service();
    this.metrics = provider.metrics();
    this.protobufTranslation = new ProtobufTranslationImpl();
    this.pbHandler = new ProtobufHandler(service, protobufTranslation, metrics);
    this.threadLocalBuffer = new ThreadLocal<UnsynchronizedBuffer>() {
        @Override
        public UnsynchronizedBuffer initialValue() {
            return new UnsynchronizedBuffer();
        }
    };
}

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    System.out.println("DO GET DO GET");
    doPost(req, resp);
}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    System.out.println("DO POST DO POST");
    response.setContentType("application/octet-stream;charset=utf-8");
    response.setStatus(HttpServletResponse.SC_OK);
    final byte[] requestBytes;
    // Avoid a new buffer creation for every HTTP request
    final UnsynchronizedBuffer buffer = threadLocalBuffer.get();
    try (ServletInputStream inputStream = request.getInputStream()) {
        requestBytes = AvaticaUtils.readFullyToBytes(inputStream, buffer);
    } finally {
        buffer.reset();
    }

    Handler.HandlerResponse<byte[]> handlerResponse;
    try {
        handlerResponse = pbHandler.apply(requestBytes);
    } catch (Exception e) {
        handlerResponse = pbHandler.convertToErrorResponse(e);
    }
    response.setStatus(handlerResponse.getStatusCode());
    response.getOutputStream().write(handlerResponse.getResponse());
    response.getOutputStream().close();
}
}

代码基于AvaticaProtobufHandler,没有Jetty相关的东西。

使用LocalService和CalciteConnection使用我的自定义架构构建服务:

new LocalService(DRIVER.createMeta((AvaticaConnection) bootstrap.getConnection()));

使用url连接squirrel(带avatica jars :)时:    JDBC:avatica:远程:URL = http://127.0.0.1:2990/jira/plugins/servlet/smartqljdbctest;serialization=PROTOBUF

一些HTTP POST请求与驱动程序握手,但整个事情在Meta.toProto()方法上失败:

    } else {
      // Can a "row" be a primitive? A struct? Only an Array?
      throw new RuntimeException("Only arrays are supported");
    }

我认为我已经错误地引导了servlet,但不知道为什么?

1 个答案:

答案 0 :(得分:0)

在搞乱了Calcite后,我设法使用Evatica Server示例中的JDBCMeta来处理这个问题。

根据我之前的解决方案,我认为由基于CalciteConnection的驱动程序生成的Meta与avatica LocalService实现不兼容。