/* * 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.mongodb; import static org.junit.Assert.*; import java.sql.Date; import java.util.LinkedHashSet; import java.util.Properties; import org.bson.types.Binary; import org.bson.types.ObjectId; import org.junit.Test; import org.mockito.Mockito; import org.teiid.metadata.MetadataFactory; import org.teiid.mongodb.MongoDBConnection; import org.teiid.query.metadata.DDLStringVisitor; import org.teiid.query.metadata.SystemMetadata; import org.teiid.translator.TranslatorException; import com.mongodb.BasicDBList; import com.mongodb.BasicDBObject; import com.mongodb.DB; import com.mongodb.DBCollection; import com.mongodb.DBCursor; import com.mongodb.DBRef; @SuppressWarnings("nls") public class TestMongoDBMetadataProcessor { @Test public void testMetadata() throws TranslatorException { MongoDBMetadataProcessor mp = new MongoDBMetadataProcessor(); MetadataFactory mf = new MetadataFactory("vdb", 1, "mongodb", SystemMetadata.getInstance().getRuntimeTypeMap(), new Properties(), null); MongoDBConnection conn = Mockito.mock(MongoDBConnection.class); DBCollection tableDBCollection = Mockito.mock(DBCollection.class); DBCollection embeddedDBCollection = Mockito.mock(DBCollection.class); DBCollection emptyDBCollection = Mockito.mock(DBCollection.class); DBCollection emptyFirstDBCollection = Mockito.mock(DBCollection.class); LinkedHashSet<String> tables = new LinkedHashSet<String>(); tables.add("table"); tables.add("embedded"); tables.add("empty"); tables.add("emptyFirst"); DB db = Mockito.mock(DB.class); BasicDBList array = new BasicDBList(); array.add("one"); array.add("two"); BasicDBObject row = new BasicDBObject(); row.append("_id", new Integer(1)); row.append("col2", new Double(2.0)); row.append("col3", new Long(3L)); row.append("col5", Boolean.TRUE); row.append("col6", new Date(0L)); row.append("col6", new DBRef(db, "ns", "one")); row.append("col7", array); row.append("col8", new Binary("binary".getBytes())); BasicDBObject child = new BasicDBObject(); child.append("col1", "one"); child.append("col2", "two"); row.append("child", child); BasicDBObject emptyFirstRow = new BasicDBObject(); emptyFirstRow.append("_id", new ObjectId("5835a598944716c40d2f26ae")); emptyFirstRow.append("col2", new Double(2.0)); emptyFirstRow.append("col3", new Long(3L)); BasicDBObject embedded = new BasicDBObject(); embedded.append("col1", "one"); embedded.append("col2", "two"); row.append("embedded", embedded); Mockito.stub(db.getCollectionNames()).toReturn(tables); Mockito.stub(db.getCollection(Mockito.eq("table"))).toReturn(tableDBCollection); Mockito.stub(db.getCollection(Mockito.eq("embedded"))).toReturn(embeddedDBCollection); Mockito.stub(db.getCollection(Mockito.eq("empty"))).toReturn(emptyDBCollection); Mockito.stub(db.getCollection(Mockito.eq("emptyFirst"))).toReturn(emptyFirstDBCollection); DBCursor tableCursor = Mockito.mock(DBCursor.class); Mockito.when(tableCursor.hasNext()).thenReturn(true).thenReturn(false); Mockito.when(tableCursor.next()).thenReturn(row); Mockito.when(tableDBCollection.find()).thenReturn(tableCursor); DBCursor embeddedCursor = Mockito.mock(DBCursor.class); Mockito.when(embeddedCursor.hasNext()).thenReturn(true).thenReturn(false); Mockito.when(embeddedCursor.next()).thenReturn(child); Mockito.when(embeddedDBCollection.find()).thenReturn(embeddedCursor); DBCursor emptyFirstCursor = Mockito.mock(DBCursor.class); Mockito.when(emptyFirstCursor.hasNext()).thenReturn(true).thenReturn(true).thenReturn(false); Mockito.when(emptyFirstCursor.next()).thenReturn(null).thenReturn(emptyFirstRow); Mockito.when(emptyFirstDBCollection.find()).thenReturn(emptyFirstCursor); DBCursor emptyCursor = Mockito.mock(DBCursor.class); Mockito.when(emptyCursor.hasNext()).thenReturn(true).thenReturn(false); Mockito.when(emptyCursor.next()).thenReturn(null); Mockito.when(emptyDBCollection.find()).thenReturn(emptyCursor); Mockito.stub(conn.getDatabase()).toReturn(db); mp.process(mf, conn); String metadataDDL = DDLStringVisitor.getDDLString(mf.getSchema(), null, null); String expected = "SET NAMESPACE 'http://www.teiid.org/translator/mongodb/2013' AS teiid_mongo;\n\n" + "CREATE FOREIGN TABLE \"table\" (\n" + "\t\"_id\" integer,\n" + "\tcol2 double,\n" + "\tcol3 long,\n" + "\tcol5 boolean,\n" + "\tcol6 string,\n" + "\tcol7 object[] OPTIONS (SEARCHABLE 'Unsearchable'),\n"+ "\tcol8 varbinary OPTIONS (NATIVE_TYPE 'org.bson.types.Binary'),\n"+ "\tCONSTRAINT PK0 PRIMARY KEY(\"_id\"),\n" + "\tCONSTRAINT FK_col6 FOREIGN KEY(col6) REFERENCES ns \n" + ") OPTIONS (UPDATABLE TRUE);\n" + "\n" + "CREATE FOREIGN TABLE child (\n" + "\tcol1 string,\n" + "\tcol2 string,\n" + "\t\"_id\" integer OPTIONS (UPDATABLE FALSE),\n"+ "\tCONSTRAINT PK0 PRIMARY KEY(\"_id\"),\n"+ "\tFOREIGN KEY(\"_id\") REFERENCES \"table\" \n" + ") OPTIONS (UPDATABLE TRUE, \"teiid_mongo:MERGE\" 'table');\n" + "\n" + "CREATE FOREIGN TABLE embedded (\n" + "\tcol1 string,\n" + "\tcol2 string,\n" + "\t\"_id\" integer OPTIONS (UPDATABLE FALSE),\n" + "\tCONSTRAINT PK0 PRIMARY KEY(\"_id\"),\n" + "\tFOREIGN KEY(\"_id\") REFERENCES \"table\" \n" + ") OPTIONS (UPDATABLE TRUE, \"teiid_mongo:EMBEDDABLE\" 'true');\n" + "\n" + "CREATE FOREIGN TABLE emptyFirst (\n" + "\t\"_id\" string AUTO_INCREMENT OPTIONS (NATIVE_TYPE 'org.bson.types.ObjectId'),\n" + "\tcol2 double,\n" + "\tcol3 long,\n" + "\tCONSTRAINT PK0 PRIMARY KEY(\"_id\")\n" + ") OPTIONS (UPDATABLE TRUE);"; assertEquals(expected, metadataDDL); } @Test public void testExclusion() throws TranslatorException { MongoDBMetadataProcessor mp = new MongoDBMetadataProcessor(); mp.setExcludeTables("e.*"); MetadataFactory mf = new MetadataFactory("vdb", 1, "mongodb", SystemMetadata.getInstance().getRuntimeTypeMap(), new Properties(), null); MongoDBConnection conn = Mockito.mock(MongoDBConnection.class); DBCollection tableDBCollection = Mockito.mock(DBCollection.class); DBCollection embeddedDBCollection = Mockito.mock(DBCollection.class); DBCollection emptyDBCollection = Mockito.mock(DBCollection.class); DBCollection emptyFirstDBCollection = Mockito.mock(DBCollection.class); LinkedHashSet<String> tables = new LinkedHashSet<String>(); tables.add("table"); tables.add("embedded"); tables.add("empty"); tables.add("emptyFirst"); DB db = Mockito.mock(DB.class); BasicDBList array = new BasicDBList(); array.add("one"); array.add("two"); BasicDBObject row = new BasicDBObject(); row.append("_id", new Integer(1)); row.append("col2", new Double(2.0)); row.append("col3", new Long(3L)); row.append("col5", Boolean.TRUE); row.append("col6", new Date(0L)); row.append("col6", new DBRef(db, "ns", "one")); row.append("col7", array); row.append("col8", new Binary("binary".getBytes())); BasicDBObject child = new BasicDBObject(); child.append("col1", "one"); child.append("col2", "two"); row.append("child", child); BasicDBObject emptyFirstRow = new BasicDBObject(); emptyFirstRow.append("_id", new ObjectId("5835a598944716c40d2f26ae")); emptyFirstRow.append("col2", new Double(2.0)); emptyFirstRow.append("col3", new Long(3L)); BasicDBObject embedded = new BasicDBObject(); embedded.append("col1", "one"); embedded.append("col2", "two"); row.append("embedded", embedded); Mockito.stub(db.getCollectionNames()).toReturn(tables); Mockito.stub(db.getCollection(Mockito.eq("table"))).toReturn(tableDBCollection); Mockito.stub(db.getCollection(Mockito.eq("embedded"))).toReturn(embeddedDBCollection); Mockito.stub(db.getCollection(Mockito.eq("empty"))).toReturn(emptyDBCollection); Mockito.stub(db.getCollection(Mockito.eq("emptyFirst"))).toReturn(emptyFirstDBCollection); DBCursor tableCursor = Mockito.mock(DBCursor.class); Mockito.when(tableCursor.hasNext()).thenReturn(true).thenReturn(false); Mockito.when(tableCursor.next()).thenReturn(row); Mockito.when(tableDBCollection.find()).thenReturn(tableCursor); DBCursor embeddedCursor = Mockito.mock(DBCursor.class); Mockito.when(embeddedCursor.hasNext()).thenReturn(true).thenReturn(false); Mockito.when(embeddedCursor.next()).thenReturn(child); Mockito.when(embeddedDBCollection.find()).thenReturn(embeddedCursor); DBCursor emptyFirstCursor = Mockito.mock(DBCursor.class); Mockito.when(emptyFirstCursor.hasNext()).thenReturn(true).thenReturn(true).thenReturn(false); Mockito.when(emptyFirstCursor.next()).thenReturn(null).thenReturn(emptyFirstRow); Mockito.when(emptyFirstDBCollection.find()).thenReturn(emptyFirstCursor); DBCursor emptyCursor = Mockito.mock(DBCursor.class); Mockito.when(emptyCursor.hasNext()).thenReturn(true).thenReturn(false); Mockito.when(emptyCursor.next()).thenReturn(null); Mockito.when(emptyDBCollection.find()).thenReturn(emptyCursor); Mockito.stub(conn.getDatabase()).toReturn(db); mp.process(mf, conn); String metadataDDL = DDLStringVisitor.getDDLString(mf.getSchema(), null, null); String expected = "SET NAMESPACE 'http://www.teiid.org/translator/mongodb/2013' AS teiid_mongo;\n\n" + "CREATE FOREIGN TABLE \"table\" (\n" + "\t\"_id\" integer,\n" + "\tcol2 double,\n" + "\tcol3 long,\n" + "\tcol5 boolean,\n" + "\tcol6 string,\n" + "\tcol7 object[] OPTIONS (SEARCHABLE 'Unsearchable'),\n"+ "\tcol8 varbinary OPTIONS (NATIVE_TYPE 'org.bson.types.Binary'),\n"+ "\tCONSTRAINT PK0 PRIMARY KEY(\"_id\"),\n" + "\tCONSTRAINT FK_col6 FOREIGN KEY(col6) REFERENCES ns \n" + ") OPTIONS (UPDATABLE TRUE);\n" + "\n" + "CREATE FOREIGN TABLE child (\n" + "\tcol1 string,\n" + "\tcol2 string,\n" + "\t\"_id\" integer OPTIONS (UPDATABLE FALSE),\n"+ "\tCONSTRAINT PK0 PRIMARY KEY(\"_id\"),\n"+ "\tFOREIGN KEY(\"_id\") REFERENCES \"table\" \n" + ") OPTIONS (UPDATABLE TRUE, \"teiid_mongo:MERGE\" 'table');\n" + "\n" + "CREATE FOREIGN TABLE embedded (\n" + "\tcol1 string,\n" + "\tcol2 string,\n" + "\t\"_id\" integer OPTIONS (UPDATABLE FALSE),\n" + "\tCONSTRAINT PK0 PRIMARY KEY(\"_id\"),\n" + "\tFOREIGN KEY(\"_id\") REFERENCES \"table\" \n" + ") OPTIONS (UPDATABLE TRUE, \"teiid_mongo:MERGE\" 'table');"; assertEquals(expected, metadataDDL); } }