Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
/presto-thrift-spec @prestodb/committers
/presto-thrift-testing-server @prestodb/committers
/presto-thrift-testing-udf-server @prestodb/committers
/presto-thrift-connector-toolkit @prestodb/committers
/presto-tpcds @prestodb/committers
/presto-tpch @prestodb/committers
/presto-verifier @prestodb/committers
Expand Down
7 changes: 7 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@
<module>presto-druid</module>
<module>presto-common</module>
<module>presto-thrift-testing-udf-server</module>
<module>presto-thrift-connector-toolkit</module>
<module>presto-thrift-spec</module>
<module>presto-testng-services</module>
<module>presto-node-ttl-fetchers</module>
Expand Down Expand Up @@ -1140,6 +1141,12 @@
<type>test-jar</type>
</dependency>

<dependency>
<groupId>com.facebook.presto</groupId>
<artifactId>presto-thrift-connector-toolkit</artifactId>
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>com.facebook.presto</groupId>
<artifactId>presto-thrift-testing-server</artifactId>
Expand Down
63 changes: 63 additions & 0 deletions presto-thrift-connector-toolkit/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.facebook.presto</groupId>
<artifactId>presto-root</artifactId>
<version>0.297-SNAPSHOT</version>
</parent>

<artifactId>presto-thrift-connector-toolkit</artifactId>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we'll be sharing these among modules, could we add some basic unit tests that aren't tied to any particular module?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added tests

<name>presto-thrift-connector-toolkit</name>
<packaging>jar</packaging>

<properties>
<air.main.basedir>${project.parent.basedir}</air.main.basedir>
<air.check.skip-modernizer>true</air.check.skip-modernizer>
</properties>

<dependencies>
<dependency>
<groupId>com.facebook.airlift.drift</groupId>
<artifactId>drift-codec</artifactId>
</dependency>

<dependency>
<groupId>com.facebook.airlift.drift</groupId>
<artifactId>drift-protocol</artifactId>
</dependency>

<dependency>
<groupId>com.facebook.presto</groupId>
<artifactId>presto-spi</artifactId>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>com.facebook.airlift.drift</groupId>
<artifactId>drift-api</artifactId>
<version>${dep.drift.version}</version>
<scope>provided</scope>
</dependency>

<!-- Test dependencies -->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.facebook.presto</groupId>
<artifactId>presto-testng-services</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -11,50 +11,59 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.facebook.presto.tpcds.thrift;
package com.facebook.presto.thrift.codec;

import com.facebook.drift.codec.ThriftCodec;
import com.facebook.drift.codec.ThriftCodecManager;
import com.facebook.drift.protocol.TProtocolException;
import com.facebook.presto.spi.ConnectorCodec;
import com.facebook.presto.spi.PrestoException;
import com.facebook.presto.spi.connector.ConnectorTransactionHandle;
import com.facebook.presto.tpcds.TpcdsTransactionHandle;

import java.lang.reflect.Type;

import static com.facebook.presto.spi.StandardErrorCode.INVALID_ARGUMENTS;
import static com.facebook.presto.tpcds.thrift.ThriftCodecUtils.fromThrift;
import static com.facebook.presto.tpcds.thrift.ThriftCodecUtils.toThrift;
import static com.facebook.presto.thrift.codec.ThriftCodecUtils.fromThrift;
import static com.facebook.presto.thrift.codec.ThriftCodecUtils.toThrift;
import static java.util.Objects.requireNonNull;

public class TpcdsTransactionHandleCodec
implements ConnectorCodec<ConnectorTransactionHandle>
public class GenericThriftCodec<T>
implements ConnectorCodec<T>
{
private final ThriftCodec<TpcdsTransactionHandle> thriftCodec;
private final ThriftCodec<T> thriftCodec;

public TpcdsTransactionHandleCodec(ThriftCodecManager thriftCodecManager)
public GenericThriftCodec(ThriftCodecManager codecManager, Type javaType)
{
this.thriftCodec = requireNonNull(thriftCodecManager, "thriftCodecManager is null").getCodec(TpcdsTransactionHandle.class);
requireNonNull(codecManager, "codecManager is null");
requireNonNull(javaType, "javaType is null");

if (!(javaType instanceof Class<?>)) {
throw new IllegalArgumentException("Expected a Class type for javaType, but got: " + javaType.getTypeName());
}

Class<?> clazz = (Class<?>) javaType;

this.thriftCodec = (ThriftCodec<T>) codecManager.getCodec(clazz);
}

@Override
public byte[] serialize(ConnectorTransactionHandle handle)
public byte[] serialize(T value)
{
try {
return toThrift((TpcdsTransactionHandle) handle, thriftCodec);
return toThrift(value, thriftCodec);
}
catch (TProtocolException e) {
throw new PrestoException(INVALID_ARGUMENTS, "Can not serialize tpcds transaction handle", e);
throw new PrestoException(INVALID_ARGUMENTS, "Unable to serialize object of type " + value.getClass().getSimpleName(), e);
}
}

@Override
public ConnectorTransactionHandle deserialize(byte[] bytes)
public T deserialize(byte[] bytes)
{
try {
return fromThrift(bytes, thriftCodec);
}
catch (TProtocolException e) {
throw new PrestoException(INVALID_ARGUMENTS, "Can not deserialize tpcds transaction handle", e);
throw new PrestoException(INVALID_ARGUMENTS, "Unable to deserialize bytes to object of expected type", e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.facebook.presto.thrift.codec;

import com.facebook.drift.codec.ThriftCodecManager;
import com.facebook.presto.spi.ConnectorCodec;
import com.facebook.presto.spi.ConnectorDeleteTableHandle;
import com.facebook.presto.spi.ConnectorInsertTableHandle;
import com.facebook.presto.spi.ConnectorOutputTableHandle;
import com.facebook.presto.spi.ConnectorSplit;
import com.facebook.presto.spi.ConnectorTableHandle;
import com.facebook.presto.spi.ConnectorTableLayoutHandle;
import com.facebook.presto.spi.connector.ConnectorCodecProvider;
import com.facebook.presto.spi.connector.ConnectorTransactionHandle;

import java.lang.reflect.Type;
import java.util.Optional;

import static java.util.Objects.requireNonNull;

public class ThriftCodecProvider
implements ConnectorCodecProvider
{
private final ThriftCodecManager thriftCodecManager;
private final Optional<ConnectorCodec<ConnectorSplit>> connectorSplitCodec;
private final Optional<ConnectorCodec<ConnectorTransactionHandle>> connectorTransactionHandleCodec;
private final Optional<ConnectorCodec<ConnectorTableLayoutHandle>> connectorTableLayoutHandleCodec;
private final Optional<ConnectorCodec<ConnectorTableHandle>> connectorTableHandleCodec;
private final Optional<ConnectorCodec<ConnectorOutputTableHandle>> connectorOutputTableHandleCodec;
private final Optional<ConnectorCodec<ConnectorInsertTableHandle>> connectorInsertTableHandleCodec;
private final Optional<ConnectorCodec<ConnectorDeleteTableHandle>> connectorDeleteTableHandleCodec;

private ThriftCodecProvider(Builder builder)
{
this.thriftCodecManager = requireNonNull(builder.thriftCodecManager, "thriftCodecManager is null");
this.connectorSplitCodec = builder.connectorSplitType.map(type -> new GenericThriftCodec<>(thriftCodecManager, type));
this.connectorTransactionHandleCodec = builder.connectorTransactionHandle.map(type -> new GenericThriftCodec<>(thriftCodecManager, type));
this.connectorTableLayoutHandleCodec = builder.connectorTableLayoutHandle.map(type -> new GenericThriftCodec<>(thriftCodecManager, type));
this.connectorTableHandleCodec = builder.connectorTableHandle.map(type -> new GenericThriftCodec<>(thriftCodecManager, type));
this.connectorOutputTableHandleCodec = builder.connectorOutputTableHandle.map(type -> new GenericThriftCodec<>(thriftCodecManager, type));
this.connectorInsertTableHandleCodec = builder.connectorInsertTableHandle.map(type -> new GenericThriftCodec<>(thriftCodecManager, type));
this.connectorDeleteTableHandleCodec = builder.connectorDeleteTableHandle.map(type -> new GenericThriftCodec<>(thriftCodecManager, type));
}

@Override
public Optional<ConnectorCodec<ConnectorSplit>> getConnectorSplitCodec()
{
return connectorSplitCodec;
}

@Override
public Optional<ConnectorCodec<ConnectorTransactionHandle>> getConnectorTransactionHandleCodec()
{
return connectorTransactionHandleCodec;
}

@Override
public Optional<ConnectorCodec<ConnectorTableLayoutHandle>> getConnectorTableLayoutHandleCodec()
{
return connectorTableLayoutHandleCodec;
}

@Override
public Optional<ConnectorCodec<ConnectorTableHandle>> getConnectorTableHandleCodec()
{
return connectorTableHandleCodec;
}

@Override
public Optional<ConnectorCodec<ConnectorOutputTableHandle>> getConnectorOutputTableHandleCodec()
{
return connectorOutputTableHandleCodec;
}

@Override
public Optional<ConnectorCodec<ConnectorInsertTableHandle>> getConnectorInsertTableHandleCodec()
{
return connectorInsertTableHandleCodec;
}

@Override
public Optional<ConnectorCodec<ConnectorDeleteTableHandle>> getConnectorDeleteTableHandleCodec()
{
return connectorDeleteTableHandleCodec;
}

public ThriftCodecManager getThriftCodecManager()
{
return thriftCodecManager;
}

public static class Builder
{
private ThriftCodecManager thriftCodecManager;
private Optional<Type> connectorSplitType = Optional.empty();
private Optional<Type> connectorTransactionHandle = Optional.empty();
private Optional<Type> connectorTableLayoutHandle = Optional.empty();
private Optional<Type> connectorTableHandle = Optional.empty();
private Optional<Type> connectorOutputTableHandle = Optional.empty();
private Optional<Type> connectorInsertTableHandle = Optional.empty();
private Optional<Type> connectorDeleteTableHandle = Optional.empty();

public Builder setThriftCodecManager(ThriftCodecManager thriftCodecManager)
{
this.thriftCodecManager = thriftCodecManager;
return this;
}

public Builder setConnectorSplitType(Class<? extends ConnectorSplit> type)
{
this.connectorSplitType = Optional.ofNullable(type);
return this;
}

public Builder setConnectorTransactionHandle(Class<? extends ConnectorTransactionHandle> type)
{
this.connectorTransactionHandle = Optional.ofNullable(type);
return this;
}

public Builder setConnectorTableLayoutHandle(Class<? extends ConnectorTableLayoutHandle> type)
{
this.connectorTableLayoutHandle = Optional.ofNullable(type);
return this;
}

public Builder setConnectorTableHandle(Class<? extends ConnectorTableHandle> type)
{
this.connectorTableHandle = Optional.ofNullable(type);
return this;
}

public Builder setConnectorOutputTableHandle(Class<? extends ConnectorOutputTableHandle> type)
{
this.connectorOutputTableHandle = Optional.ofNullable(type);
return this;
}

public Builder setConnectorInsertTableHandle(Class<? extends ConnectorInsertTableHandle> type)
{
this.connectorInsertTableHandle = Optional.ofNullable(type);
return this;
}

public Builder setConnectorDeleteTableHandle(Class<? extends ConnectorDeleteTableHandle> type)
{
this.connectorDeleteTableHandle = Optional.ofNullable(type);
return this;
}

public ThriftCodecProvider build()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider validating that thriftCodecManager is set before building - it's required but could be null if the caller forgets to call setThriftCodecManager().

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a check

{
requireNonNull(thriftCodecManager, "ThriftCodecManager not set");
return new ThriftCodecProvider(this);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.facebook.presto.tpcds.thrift;
package com.facebook.presto.thrift.codec;

import com.facebook.drift.codec.ThriftCodec;
import com.facebook.drift.protocol.TBinaryProtocol;
Expand Down
Loading
Loading