/*
* JBoss, Home of Professional Open Source.
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership. Some portions may be licensed
* to Red Hat, Inc. under one or more contributor license agreements.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*/
package org.teiid.translator.infinispan.hotrod;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.infinispan.protostream.FileDescriptorSource;
import org.infinispan.protostream.ProtobufUtil;
import org.infinispan.protostream.RawProtoStreamReader;
import org.infinispan.protostream.RawProtoStreamWriter;
import org.infinispan.protostream.SerializationContext;
import org.infinispan.protostream.WrappedMessage;
import org.infinispan.protostream.config.Configuration;
import org.infinispan.protostream.impl.RawProtoStreamReaderImpl;
import org.infinispan.protostream.impl.RawProtoStreamWriterImpl;
import org.junit.Test;
import org.teiid.cdk.api.TranslationUtility;
import org.teiid.core.util.ObjectConverterUtil;
import org.teiid.core.util.UnitTestUtil;
import org.teiid.dqp.internal.datamgr.RuntimeMetadataImpl;
import org.teiid.infinispan.api.InfinispanDocument;
import org.teiid.infinispan.api.TableWireFormat;
import org.teiid.language.Select;
import org.teiid.metadata.MetadataFactory;
import org.teiid.metadata.RuntimeMetadata;
import org.teiid.query.metadata.TransformationMetadata;
import org.teiid.translator.TranslatorException;
import org.teiid.translator.document.Document;
import org.teiid.translator.marshallers.G1;
import org.teiid.translator.marshallers.G1Marshaller;
import org.teiid.translator.marshallers.G2;
import org.teiid.translator.marshallers.G2Marshaller;
import org.teiid.translator.marshallers.G3;
import org.teiid.translator.marshallers.G3Marshaller;
import org.teiid.translator.marshallers.G4;
import org.teiid.translator.marshallers.G4Marshaller;
public class TestTeiidTableMarsheller {
private IckleConversionVisitor helpExecute(String query) throws Exception {
MetadataFactory mf = TestProtobufMetadataProcessor.protoMatadata("tables.proto");
//System.out.println(DDLStringVisitor.getDDLString(mf.getSchema(), null, null));
InfinispanExecutionFactory ef = new InfinispanExecutionFactory();
TransformationMetadata metadata = TestProtobufMetadataProcessor.getTransformationMetadata(mf, ef);
TranslationUtility utility = new TranslationUtility(metadata);
Select cmd = (Select)utility.parseCommand(query);
RuntimeMetadata runtimeMetadata = new RuntimeMetadataImpl(metadata);
IckleConversionVisitor visitor = new IckleConversionVisitor(runtimeMetadata, false);
visitor.visitNode(cmd);
visitor.getQuery();
return visitor;
}
@Test
public void testReadSimple() throws Exception {
IckleConversionVisitor visitor = helpExecute("select * from G1");
TeiidTableMarsheller g1ReadMarshaller = new TeiidTableMarsheller(
ProtobufMetadataProcessor.getMessageName(visitor.getParentTable()),
MarshallerBuilder.getWireMap(visitor.getParentTable(), visitor.getMetadata()));
G1Marshaller g1WriteMarshller = new G1Marshaller() {
@Override
public G1 readFrom(ProtoStreamReader reader) throws IOException {
throw new RuntimeException("Use Teiid marshaller for reading for this test..");
}
};
SerializationContext ctx = ProtobufUtil.newSerializationContext(Configuration.builder().build());
ctx.registerProtoFiles(FileDescriptorSource.fromString("tables.proto",
ObjectConverterUtil.convertFileToString(UnitTestUtil.getTestDataFile("tables.proto"))));
G1 g1 = buildG1();
ctx.registerMarshaller(g1WriteMarshller);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
RawProtoStreamWriter out = RawProtoStreamWriterImpl.newInstance(baos);
WrappedMessage.writeMessage(ctx, out, g1);
out.flush();
baos.flush();
ctx.unregisterMarshaller(g1WriteMarshller);
ctx.registerMarshaller(g1ReadMarshaller);
RawProtoStreamReader in = RawProtoStreamReaderImpl.newInstance(baos.toByteArray());
Document result = WrappedMessage.readMessage(ctx, in);
Map<String, Object> row = result.flatten().get(0);
assertEquals(1, row.get("e1"));
assertEquals("foo", row.get("e2"));
assertEquals(1.234f, row.get("e3"));
assertNull(row.get("e4"));
List<String> e5 = (List<String>)row.get("e5");
assertArrayEquals(new String[] {"hello", "world"}, e5.toArray(new String[e5.size()]));
ctx.unregisterMarshaller(g1ReadMarshaller);
}
@Test
public void testWriteSimple() throws Exception {
IckleConversionVisitor visitor = helpExecute("select * from G1");
TeiidTableMarsheller g1WriteMarshaller = new TeiidTableMarsheller(
ProtobufMetadataProcessor.getMessageName(visitor.getParentTable()),
MarshallerBuilder.getWireMap(visitor.getParentTable(), visitor.getMetadata()));
G1Marshaller g1ReadMarshaller = new G1Marshaller() {
@Override
public void writeTo(ProtoStreamWriter writer, G1 g1) throws IOException {
throw new RuntimeException("Use Teiid marshaller for writing for this test..");
}
};
SerializationContext ctx = ProtobufUtil.newSerializationContext(Configuration.builder().build());
ctx.registerProtoFiles(FileDescriptorSource.fromString("tables.proto",
ObjectConverterUtil.convertFileToString(UnitTestUtil.getTestDataFile("tables.proto"))));
InfinispanDocument g1 = new InfinispanDocument("pm1.G1",
MarshallerBuilder.getWireMap(visitor.getParentTable(), visitor.getMetadata()), null);
g1.addProperty("e1", 1);
g1.addProperty("e2", "foo");
g1.addProperty("e3", 1.234f);
g1.addProperty("e4", null);
g1.addArrayProperty("e5", "hello");
g1.addArrayProperty("e5", "world");
// write to buffer
ctx.registerMarshaller(g1WriteMarshaller);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
RawProtoStreamWriter out = RawProtoStreamWriterImpl.newInstance(baos);
WrappedMessage.writeMessage(ctx, out, g1);
out.flush();
baos.flush();
ctx.unregisterMarshaller(g1WriteMarshaller);
// read from buffer
ctx.registerMarshaller(g1ReadMarshaller);
RawProtoStreamReader in = RawProtoStreamReaderImpl.newInstance(baos.toByteArray());
G1 result = WrappedMessage.readMessage(ctx, in);
ctx.unregisterMarshaller(g1ReadMarshaller);
assertEquals(buildG1(), result);
}
private G1 buildG1() {
G1 g1 = new G1();
g1.setE1(1);
g1.setE2("foo");
g1.setE3(1.234f);
g1.setE4(null);
g1.setE5(new String[] {"hello", "world"});
return g1;
}
// this is for sanity debugging while writing the protocol decoder.
@Test
public void testMarshallWithComplexNative() throws Exception {
SerializationContext ctx = ProtobufUtil.newSerializationContext(Configuration.builder().build());
ctx.registerProtoFiles(FileDescriptorSource.fromString("tables.proto",
ObjectConverterUtil.convertFileToString(UnitTestUtil.getTestDataFile("tables.proto"))));
ctx.registerMarshaller(new G3Marshaller());
ctx.registerMarshaller(new G4Marshaller());
ctx.registerMarshaller(new G2Marshaller());
G2 g2 = buildG2();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
RawProtoStreamWriter out = RawProtoStreamWriterImpl.newInstance(baos);
WrappedMessage.writeMessage(ctx, out, g2);
out.flush();
baos.flush();
RawProtoStreamReader in = RawProtoStreamReaderImpl.newInstance(baos.toByteArray());
G2 result = WrappedMessage.readMessage(ctx, in);
//System.out.println(result);
assertNotNull(result);
assertEquals(g2, result);
}
private G2 buildG2() {
G3 g3 = new G3();
g3.setE1(1);
g3.setE2("bar");
G4 g41 = new G4();
g41.setE1(1);
g41.setE2("hello");
G4 g42 = new G4();
g42.setE1(2);
g42.setE2("world");
G2 g2 = new G2();
g2.setE1(1);
g2.setE2("foo");
g2.setG3(g3);
g2.setG4(Arrays.asList(g41, g42));
g2.setE5("Hello Infinispan".getBytes());
g2.setE6(new Timestamp(1489835322801L));
return g2;
}
private InfinispanDocument buildG2(IckleConversionVisitor visitor) throws TranslatorException {
TreeMap<Integer, TableWireFormat> wireMap = MarshallerBuilder.getWireMap(visitor.getParentTable(),
visitor.getMetadata());
InfinispanDocument g2 = new InfinispanDocument("pm1.G2", wireMap, null);
g2.addProperty("e1", 1);
g2.addProperty("e2", "foo");
InfinispanDocument g3 = new InfinispanDocument("pm1.G3", getWireMap(wireMap, "pm1.G3"), g2);
g3.addProperty("e1", 1);
g3.addProperty("e2", "bar");
g2.addChildDocument("pm1.G3", g3);
InfinispanDocument g41 = new InfinispanDocument("pm1.G4", getWireMap(wireMap, "pm1.G4"), g2);
g41.addProperty("e1", 1);
g41.addProperty("e2", "hello");
g2.addChildDocument("pm1.G4", g41);
InfinispanDocument g42 = new InfinispanDocument("pm1.G4", getWireMap(wireMap, "pm1.G4"), g2);
g42.addProperty("e1", 2);
g42.addProperty("e2", "world");
g2.addChildDocument("pm1.G4", g42);
g2.addProperty("e5", "Hello Infinispan");
g2.addProperty("e6", new Timestamp(1489835322801L));
return g2;
}
private void assertG2(InfinispanDocument result) {
List<Map<String, Object>> rows = result.flatten();
assertEquals(2, rows.size());
Map<String, Object> row = rows.get(0);
assertEquals(1, row.get("e1"));
assertEquals("foo", row.get("e2"));
assertEquals("Hello Infinispan", new String((byte[])row.get("e5")));
assertEquals(1489835322801L, row.get("e6"));
assertEquals(1, row.get("pm1.G2/pm1.G3/e1"));
assertEquals("bar", row.get("pm1.G2/pm1.G3/e2"));
assertEquals(1, row.get("pm1.G2/pm1.G4/e1"));
assertEquals("hello", row.get("pm1.G2/pm1.G4/e2"));
row = rows.get(1);
assertEquals(1, row.get("e1"));
assertEquals("foo", row.get("e2"));
assertEquals(1, row.get("pm1.G2/pm1.G3/e1"));
assertEquals("bar", row.get("pm1.G2/pm1.G3/e2"));
assertEquals(2, row.get("pm1.G2/pm1.G4/e1"));
assertEquals("world", row.get("pm1.G2/pm1.G4/e2"));
}
private TreeMap<Integer, TableWireFormat> getWireMap(TreeMap<Integer, TableWireFormat> wireMap, String name) {
for (TableWireFormat twf : wireMap.values()) {
if (twf.getAttributeName().equals(name)) {
return twf.getNestedWireMap();
}
}
return null;
}
@Test
public void testReadComplex() throws Exception {
IckleConversionVisitor visitor = helpExecute("select * from G2");
TeiidTableMarsheller readMarshaller = new TeiidTableMarsheller(
ProtobufMetadataProcessor.getMessageName(visitor.getParentTable()),
MarshallerBuilder.getWireMap(visitor.getParentTable(), visitor.getMetadata()));
SerializationContext ctx = ProtobufUtil.newSerializationContext(Configuration.builder().build());
ctx.registerProtoFiles(FileDescriptorSource.fromString("tables.proto",
ObjectConverterUtil.convertFileToString(UnitTestUtil.getTestDataFile("tables.proto"))));
ctx.registerMarshaller(new G3Marshaller());
ctx.registerMarshaller(new G4Marshaller());
G2Marshaller writeMarshaller = new G2Marshaller() {
@Override
public G2 readFrom(ProtoStreamReader reader) throws IOException {
throw new RuntimeException("Use Teiid marshaller for reading for this test..");
}
};
G2 g2 = buildG2();
// this is used for writing, if reading is being attempted then fail
ctx.registerMarshaller(writeMarshaller);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
RawProtoStreamWriter out = RawProtoStreamWriterImpl.newInstance(baos);
WrappedMessage.writeMessage(ctx, out, g2);
out.flush();
baos.flush();
ctx.unregisterMarshaller(writeMarshaller);
ctx.registerMarshaller(readMarshaller);
RawProtoStreamReader in = RawProtoStreamReaderImpl.newInstance(baos.toByteArray());
InfinispanDocument result = WrappedMessage.readMessage(ctx, in);
//System.out.println(result.flatten());
assertG2(result);
ctx.unregisterMarshaller(readMarshaller);
}
@Test
public void testWriteComplex() throws Exception {
IckleConversionVisitor visitor = helpExecute("select * from G2");
TeiidTableMarsheller writeMarshaller = new TeiidTableMarsheller(
ProtobufMetadataProcessor.getMessageName(visitor.getParentTable()),
MarshallerBuilder.getWireMap(visitor.getParentTable(), visitor.getMetadata()));
SerializationContext ctx = ProtobufUtil.newSerializationContext(Configuration.builder().build());
ctx.registerProtoFiles(FileDescriptorSource.fromString("tables.proto",
ObjectConverterUtil.convertFileToString(UnitTestUtil.getTestDataFile("tables.proto"))));
ctx.registerMarshaller(new G3Marshaller());
ctx.registerMarshaller(new G4Marshaller());
G2Marshaller readMarshaller = new G2Marshaller() {
@Override
public void writeTo(ProtoStreamWriter writer, G2 g2) throws IOException {
throw new RuntimeException("Use Teiid marshaller for writing for this test..");
}
};
InfinispanDocument g2 = buildG2(visitor);
ctx.registerMarshaller(writeMarshaller);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
RawProtoStreamWriter out = RawProtoStreamWriterImpl.newInstance(baos);
WrappedMessage.writeMessage(ctx, out, g2);
out.flush();
baos.flush();
ctx.unregisterMarshaller(writeMarshaller);
// this is used for writing, if reading is being attempted then fail
ctx.registerMarshaller(readMarshaller);
RawProtoStreamReader in = RawProtoStreamReaderImpl.newInstance(baos.toByteArray());
G2 result = WrappedMessage.readMessage(ctx, in);
ctx.unregisterMarshaller(readMarshaller);
assertEquals(buildG2(), result);
}
}