/*
* 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.arquillian;
import static org.junit.Assert.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.nio.charset.Charset;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import javax.ws.rs.core.Response;
import org.apache.cxf.jaxrs.client.WebClient;
import org.jboss.arquillian.junit.Arquillian;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.teiid.adminapi.Admin;
import org.teiid.adminapi.AdminException;
import org.teiid.adminapi.jboss.AdminFactory;
import org.teiid.core.util.Base64;
import org.teiid.core.util.ObjectConverterUtil;
import org.teiid.core.util.ReaderInputStream;
import org.teiid.core.util.UnitTestUtil;
import org.teiid.jdbc.AbstractMMQueryTestCase;
import org.teiid.jdbc.TeiidDriver;
@RunWith(Arquillian.class)
@SuppressWarnings("nls")
public class IntegrationTestOData4 extends AbstractMMQueryTestCase {
private Admin admin;
@Before
public void setup() throws Exception {
admin = AdminFactory.getInstance().createAdmin("localhost", AdminUtil.MANAGEMENT_PORT, "admin", "admin".toCharArray());
}
@After
public void teardown() throws AdminException {
AdminUtil.cleanUp(admin);
admin.close();
}
@Test
public void testOdata() throws Exception {
String vdb = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" +
"<vdb name=\"Loopy\" version=\"1\">\n" +
" <model name=\"MarketData\">\n" +
" <source name=\"text-connector2\" translator-name=\"loopback\" />\n" +
" <metadata type=\"DDL\"><![CDATA[\n" +
" CREATE FOREIGN TABLE G1 (e1 string, e2 integer PRIMARY KEY);\n" +
" CREATE FOREIGN TABLE G2 (e1 string, e2 integer PRIMARY KEY) OPTIONS (UPDATABLE 'true');\n" +
" ]]> </metadata>\n" +
" </model>\n" +
"</vdb>";
admin.deploy("loopy-vdb.xml", new ReaderInputStream(new StringReader(vdb), Charset.forName("UTF-8")));
assertTrue(AdminUtil.waitForVDBLoad(admin, "Loopy", 1, 3));
WebClient client = WebClient.create("http://localhost:8080/odata4/loopy.1/MarketData/$metadata");
client.header("Authorization", "Basic " + Base64.encodeBytes(("user:user").getBytes())); //$NON-NLS-1$ //$NON-NLS-2$
Response response = client.invoke("GET", null);
int statusCode = response.getStatus();
assertEquals(200, statusCode);
Connection conn = TeiidDriver.getInstance().connect("jdbc:teiid:loopy@mm://localhost:31000;user=user;password=user", null);
PreparedStatement ps = conn.prepareCall("select t.* from xmltable('/*:Edmx/*:DataServices/*:Schema[@Alias=\"MarketData\"]' passing xmlparse(document cast(? as clob))) as t");
ps.setAsciiStream(1, (InputStream)response.getEntity());
ResultSet rs = ps.executeQuery();
rs.next();
assertEquals(ObjectConverterUtil.convertFileToString(UnitTestUtil.getTestDataFile("loopy-metadata4-results.txt")), rs.getString(1));
conn.close();
//try an invalid url
client = WebClient.create("http://localhost:8080/odata4/x/y$metadata");
client.header("Authorization", "Basic " + Base64.encodeBytes(("user:user").getBytes())); //$NON-NLS-1$ //$NON-NLS-2$
response = client.invoke("GET", null);
assertEquals(404, response.getStatus());
admin.undeploy("loopy-vdb.xml");
}
@Test
public void testReadOdataMetadata() throws Exception {
String vdb = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" +
"<vdb name=\"Loopy\" version=\"1\">\n" +
" <model name=\"MarketData\">\n" +
" <source name=\"text-connector2\" translator-name=\"loopback\" />\n" +
" <metadata type=\"DDL\"><![CDATA[\n" +
" CREATE FOREIGN TABLE G1 (e1 string[], e2 integer PRIMARY KEY);\n" +
" CREATE FOREIGN TABLE G2 (e1 string, e2 integer PRIMARY KEY) OPTIONS (UPDATABLE 'true');\n" +
" ]]> </metadata>\n" +
" </model>\n" +
"</vdb>";
admin.deploy("loopy-vdb.xml", new ReaderInputStream(new StringReader(vdb), Charset.forName("UTF-8")));
assertTrue(AdminUtil.waitForVDBLoad(admin, "Loopy", 1, 3));
String vdb2 = "<?xml version='1.0' encoding='UTF-8'?>\n" +
"<vdb name=\"TestOData\" version=\"1\">\n" +
" <model name=\"TestOData\" type=\"PHYSICAL\" visible=\"true\">\n" +
" <property name=\"importer.entityContainer\" value=\"MarketData\"/>\n"+
" <property name=\"importer.schemaNamespace\" value=\"MarketData\"/>\n"+
" <source name=\"TestOData\" translator-name=\"odata4\" connection-jndi-name=\"java:/TestOData4\"/>\n" +
" </model>\n" +
"</vdb>";
Properties p = new Properties();
p.setProperty("class-name", "org.teiid.resource.adapter.ws.WSManagedConnectionFactory");
p.setProperty("EndPoint", "http://localhost:8080/odata4/Loopy.1/MarketData");
p.setProperty("SecurityType", "HTTPBasic");
p.setProperty("AuthUserName", "user");
p.setProperty("AuthPassword", "user");
admin.createDataSource("TestOData4", "webservice", p);
admin.deploy("test-vdb.xml", new ReaderInputStream(new StringReader(vdb2), Charset.forName("UTF-8")));
assertTrue(AdminUtil.waitForVDBLoad(admin, "TestOData", 1, 30000));
this.internalConnection = TeiidDriver.getInstance().connect("jdbc:teiid:TestOData@mm://localhost:31000;user=user;password=user", null);
execute("SELECT Name FROM Sys.Tables Where name='G1'"); //$NON-NLS-1$
assertResultsSetEquals("Name[string]\nG1");
execute("SELECT * from G1"); //$NON-NLS-1$
assertResultsSetEquals("e1[string[]] e2[integer]\n[ABCDEFGHIJ] 0");
admin.undeploy("loopy-vdb.xml");
admin.undeploy("test-vdb.xml");
}
// TEIID-3914 - test the olingo-patch work
@Test public void testCompositeKeyTimestamp() throws Exception {
String vdb = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" +
"<vdb name=\"Loopy\" version=\"1\">\n" +
" <model name=\"m\">\n" +
" <source name=\"x1\" translator-name=\"loopback\" />\n" +
" <metadata type=\"DDL\"><![CDATA[\n" +
" CREATE FOREIGN TABLE x (a string, b timestamp, c integer, primary key (a, b)) options (updatable true);\n" +
" ]]> </metadata>\n" +
" </model>\n" +
"</vdb>";
admin.deploy("loopy-vdb.xml", new ReaderInputStream(new StringReader(vdb), Charset.forName("UTF-8")));
assertTrue(AdminUtil.waitForVDBLoad(admin, "Loopy", 1, 3));
WebClient client = WebClient.create("http://localhost:8080/odata4/Loopy/m/x(a='a',b=2011-09-11T00:00:00Z)");
client.header("Authorization", "Basic " + Base64.encodeBytes(("user:user").getBytes())); //$NON-NLS-1$ //$NON-NLS-2$
Response response = client.invoke("GET", null);
assertEquals(200, response.getStatus());
client = WebClient.create("http://localhost:8080/odata4/Loopy/m/x");
client.header("Authorization", "Basic " + Base64.encodeBytes(("user:user").getBytes())); //$NON-NLS-1$ //$NON-NLS-2$
client.header("Content-Type", "application/json");
response = client.post("{\"a\":\"b\", \"b\":\"2000-02-02T22:22:22Z\"}");
assertEquals(304, response.getStatus());
admin.undeploy("loopy-vdb.xml");
}
@Test
public void testOdataMetadataError() throws Exception {
String vdb = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" +
"<vdb name=\"Loopy\" version=\"1\">\n" +
" <model name=\"MarketData\">\n" +
" <source name=\"text-connector2\" translator-name=\"loopback\" />\n" +
" <metadata type=\"DDL\"><![CDATA[\n" +
" CREATE FOREIGN TABLE G1 (e1 string, e2 integer PRIMARY KEY);\n" +
" CREATE FOREIGN TABLE G1 (e1 string, e2 integer PRIMARY KEY) OPTIONS (UPDATABLE 'true');\n" +
" ]]> </metadata>\n" +
" </model>\n" +
"</vdb>";
admin.deploy("loopy-vdb.xml", new ReaderInputStream(new StringReader(vdb), Charset.forName("UTF-8")));
assertTrue(AdminUtil.waitForVDBLoad(admin, "Loopy", 1, 3));
WebClient client = WebClient.create("http://localhost:8080/odata4/loopy.1/MarketData/$metadata");
client.header("Authorization", "Basic " + Base64.encodeBytes(("user:user").getBytes())); //$NON-NLS-1$ //$NON-NLS-2$
Response response = client.invoke("GET", null);
int statusCode = response.getStatus();
assertEquals(404, statusCode);
}
@Test
public void testCORS() throws Exception {
String vdb = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" +
"<vdb name=\"Loopy\" version=\"1\">\n" +
" <model name=\"MarketData\">\n" +
" <source name=\"text-connector2\" translator-name=\"loopback\" />\n" +
" <metadata type=\"DDL\"><![CDATA[\n" +
" CREATE FOREIGN TABLE G1 (e1 string, e2 integer PRIMARY KEY);\n" +
" CREATE FOREIGN TABLE G1 (e1 string, e2 integer PRIMARY KEY) OPTIONS (UPDATABLE 'true');\n" +
" ]]> </metadata>\n" +
" </model>\n" +
"</vdb>";
admin.deploy("loopy-vdb.xml", new ReaderInputStream(new StringReader(vdb), Charset.forName("UTF-8")));
assertTrue(AdminUtil.waitForVDBLoad(admin, "Loopy", 1, 3));
WebClient client = WebClient.create("http://localhost:8080/odata4/loopy.1/MarketData/$metadata");
Response response = client.invoke("OPTIONS", null);
int statusCode = response.getStatus();
assertEquals(400, statusCode);
/* setting of Origin header is blocked HttpUrlConnection
client = WebClient.create("http://localhost:8080/odata4/loopy.1/MarketData/$metadata");
client.header("Origin", "foo.bar"); //$NON-NLS-1$ //$NON-NLS-2$
response = client.invoke("OPTIONS", null);
assertEquals(204, response.getStatus());
assertEquals("GET,POST,PUT,PATCH,DELETE", response.getHeaderString("Access-Control-Allow-Methods"));
assertEquals("foo.bar", response.getHeaderString("Access-Control-Allow-Origin"));
assertEquals("true", response.getHeaderString("Access-Control-Allow-Credentials"));
assertEquals("Content-Type,Accept,Origin,Authorization", response.getHeaderString("Access-Control-Allow-Headers"));
*/
}
@Test
public void testStaticServlet() throws Exception {
WebClient client = WebClient.create("http://localhost:8080/odata4/static/org.apache.olingo.v1.xml");
client.header("Authorization", "Basic " + Base64.encodeBytes(("user:user").getBytes())); //$NON-NLS-1$ //$NON-NLS-2$
Response response = client.invoke("GET", null);
int statusCode = response.getStatus();
assertEquals(200, statusCode);
client = WebClient.create("http://localhost:8080/odata4/static/pom.xml");
client.header("Authorization", "Basic " + Base64.encodeBytes(("user:user").getBytes())); //$NON-NLS-1$ //$NON-NLS-2$
response = client.invoke("GET", null);
statusCode = response.getStatus();
assertEquals(404, statusCode);
client = WebClient.create("http://localhost:8080/odata4/static/META-INF/keycloak.json");
client.header("Authorization", "Basic " + Base64.encodeBytes(("user:user").getBytes())); //$NON-NLS-1$ //$NON-NLS-2$
response = client.invoke("GET", null);
statusCode = response.getStatus();
assertEquals(404, statusCode);
}
@Test
public void testGetDataInGzip() throws AdminException, IOException{
String vdb = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" +
"<vdb name=\"loopy\" version=\"1\">\n" +
" <model name=\"gzip\">\n" +
" <source name=\"loopback_src\" translator-name=\"loopback\" />\n" +
" <metadata type=\"DDL\"><![CDATA[\n" +
" CREATE FOREIGN TABLE t (e integer PRIMARY KEY) OPTIONS (UPDATABLE 'true');\n" +
" ]]> </metadata>\n" +
" </model>\n" +
"</vdb>";
admin.deploy("loopy-vdb.xml", new ByteArrayInputStream(vdb.getBytes()));
assertTrue(AdminUtil.waitForVDBLoad(admin, "Loopy", 1, 3));
WebClient client = WebClient.create("http://localhost:8080/odata4/loopy/gzip/t");
client.header("Authorization", "Basic " + Base64.encodeBytes(("user:user").getBytes()));
client.header("Accept", "application/json");
Response response = client.invoke("GET", null);
assertEquals("The request should succeed.", 200, response.getStatus());
assertNull("Content-Encoding response header is not expected.", response.getHeaderString("Content-Encoding"));
InputStream is = (InputStream)response.getEntity();
byte[] buff = new byte[1000];
assertEquals("Expected entity.", "{\"@odata.context\":\"$metadata#t\",\"value\":[{\"e\":0}]}", new String(buff, 0, is.read(buff)));
client.header("Accept-Encoding", "gzip");
response = client.invoke("GET", null);
is = (InputStream)response.getEntity();
is = new GZIPInputStream(is);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int read;
while((read = is.read(buff)) != -1){
bos.write(buff, 0, read);
}
assertEquals("The request should succeed.", 200, response.getStatus());
assertNotNull("Content-Encoding response header is expected.", response.getHeaderString("Content-Encoding"));
assertEquals("Content-Encoding response header.", "gzip", response.getHeaderString("Content-Encoding").toLowerCase());
assertEquals("Expected entity.", "{\"@odata.context\":\"$metadata#t\",\"value\":[{\"e\":0}]}", new String(bos.toByteArray()));
}
@Test
public void testPutDataInGzip() throws AdminException, IOException{
String vdb = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" +
"<vdb name=\"loopy\" version=\"1\">\n" +
" <model name=\"gzip\">\n" +
" <source name=\"loopback_src\" translator-name=\"loopback\" />\n" +
" <metadata type=\"DDL\"><![CDATA[\n" +
" CREATE FOREIGN TABLE t (e integer PRIMARY KEY) OPTIONS (UPDATABLE 'true');\n" +
" ]]> </metadata>\n" +
" </model>\n" +
"</vdb>";
admin.deploy("loopy-vdb.xml", new ByteArrayInputStream(vdb.getBytes()));
assertTrue(AdminUtil.waitForVDBLoad(admin, "Loopy", 1, 3));
String data = "{\"e\":1}";
ByteArrayOutputStream bos = new ByteArrayOutputStream();
GZIPOutputStream gos = new GZIPOutputStream(bos);
gos.write(data.getBytes());
gos.finish();
gos.close();
byte[] gzipData = bos.toByteArray();
WebClient client = WebClient.create("http://localhost:8080/odata4/loopy/gzip/t(1)");
client.header("Authorization", "Basic " + Base64.encodeBytes(("user:user").getBytes()));
client.header("Content-Type", "application/json");
Response response = client.put(data);
assertEquals("The request should succeed." + response.readEntity(String.class), 304, response.getStatus());
response = client.put(new ByteArrayInputStream(gzipData));
assertEquals("The request should not succeed. Data is in GZIP format but header not specified.", 400, response.getStatus());
client.header("Content-Encoding", "gzip");
response = client.put(data);
assertEquals("The request should not succeed. Data is not in GZIP format.", 400, response.getStatus());
response = client.put(new ByteArrayInputStream(gzipData));
assertEquals("The request should succeed.", 304, response.getStatus());
}
}