001/*
002 * ModeShape (http://www.modeshape.org)
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *       http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.modeshape.jdbc;
017
018import static org.junit.Assert.assertFalse;
019import static org.junit.Assert.assertNotNull;
020import static org.junit.Assert.assertTrue;
021import java.sql.Connection;
022import java.sql.DatabaseMetaData;
023import java.sql.DriverManager;
024import java.sql.ResultSet;
025import java.sql.SQLException;
026import java.sql.Statement;
027import java.util.Properties;
028import org.junit.After;
029import org.junit.Before;
030import org.junit.Test;
031import org.modeshape.common.FixFor;
032
033/**
034 * Integration test with the http protocol of the {@link JcrDriver}. Please note that this class only performs a series of
035 * "smoke tests" against a running remote repository and is nowhere near complete from a point of view of testing a
036 * {@link java.sql.Driver} implementation.
037 * 
038 * @author Horia Chiorean
039 */
040public class JcrHttpDriverIntegrationTest {
041
042    private Properties driverProperties = new Properties();
043    private JcrDriver driver = new JcrDriver(null);
044
045    @Before
046    public void before() throws Exception {
047        DriverManager.registerDriver(driver);
048
049        driverProperties.setProperty(JcrDriver.USERNAME_PROPERTY_NAME, getUserName());
050        driverProperties.setProperty(JcrDriver.PASSWORD_PROPERTY_NAME, getPassword());
051    }
052
053    @After
054    public void after() throws Exception {
055        DriverManager.deregisterDriver(driver);
056    }
057
058    @Test
059    public void shouldCreateConnectionToRemoteServer() throws SQLException {
060        Connection connection = connectToRemoteRepository();
061        assertTrue(connection instanceof JcrConnection);
062        assertTrue(connection.unwrap(JcrConnection.class) != null);
063        assertFalse(connection.isClosed());
064    }
065
066    @Test( expected = SQLException.class )
067    public void shouldNotConnectWithInvalidRepositoryName() throws Exception {
068        DriverManager.getConnection(getContextPathUrl() + "/dummy", driverProperties);
069    }
070
071    @Test
072    @FixFor( "MODE-2125" )
073    public void shouldRetrieveMetaData() throws SQLException {
074        Connection connection = connectToRemoteRepository();
075        DatabaseMetaData metadata = connection.getMetaData();
076        assertNotNull(metadata);
077
078        // reads tables and columns
079        readTables(metadata);
080    }
081
082    @SuppressWarnings( "unused" )
083    private void readTables( DatabaseMetaData metadata ) throws SQLException {
084        ResultSet tables = metadata.getTables(null, null, null, null);
085        try {
086            while (tables.next()) {
087                String tableCatalog = tables.getString(1);
088                String tableSchema = tables.getString(2);
089                String tableName = tables.getString(3);
090                String tableType = tables.getString(4);
091                String remarks = tables.getString(5);
092                String typeCat = tables.getString(6);
093                String typeSchema = tables.getString(7);
094                String typeName = tables.getString(8);
095                String selfRefColumnName = tables.getString(9);
096                String refGeneration = tables.getString(10);
097
098                readColumns(metadata, tableCatalog, tableSchema, tableName);
099            }
100        } finally {
101            tables.close();
102        }
103    }
104
105    @SuppressWarnings( "unused" )
106    private void readColumns( DatabaseMetaData metadata,
107                              String catalog,
108                              String schema,
109                              String table ) throws SQLException {
110        ResultSet columns = metadata.getColumns(catalog, schema, table, null);
111        try {
112            while (columns.next()) {
113                String tableCatalog = columns.getString(1);
114                String tableSchema = columns.getString(2);
115                String tableName = columns.getString(3);
116                String columnName = columns.getString(4);
117                int type = columns.getInt(5);
118                String typeName = columns.getString(6);
119                int columnSize = columns.getInt(7);
120                int bufferLength = columns.getInt(8);
121                int decimalDigits = columns.getInt(9);
122                int radix = columns.getInt(10);
123                int nullable = columns.getInt(11);
124                String remarks = columns.getString(12);
125                String columnDef = columns.getString(13);
126                int sqlDataType = columns.getInt(14);
127                int sqlDataTimeSub = columns.getInt(15);
128                int charOctetLength = columns.getInt(16);
129                int ordinalPost = columns.getInt(17);
130                String isNullable = columns.getString(18);
131                String scopeCat = columns.getString(19);
132                String scopeSchema = columns.getString(20);
133                String scopeTable = columns.getString(21);
134                short scopeDataType = columns.getShort(22);
135                // String isAutoIncrement = columns.getString(23);
136                // String isGenerated = columns.getString(24);
137            }
138        } finally {
139            columns.close();
140        }
141    }
142
143    @Test
144    @FixFor( "MODE-872" )
145    public void shouldReturnResultsFromSimpleQuery() throws Exception {
146        Connection connection = connectToRemoteRepository();
147        String query = "SELECT [jcr:primaryType], [jcr:mixinTypes], [jcr:path], [jcr:name], [mode:localName], [mode:depth] FROM [nt:base] WHERE [jcr:path] LIKE '/%' AND [jcr:path] NOT LIKE '/%/%'ORDER BY [jcr:path]";
148        String[] expectedResults = new String[] {
149            "jcr:primaryType[STRING]    jcr:mixinTypes[STRING]    jcr:path[STRING]    jcr:name[STRING]    mode:localName[STRING]    mode:depth[LONG]",
150            "mode:root    null    /    null    null    0",
151            "mode:system    null    /jcr:system    jcr:system    system    1"};
152        ConnectionResultsComparator.executeTest(connection, query, expectedResults, 3);
153    }
154
155    @Test
156    @FixFor( "MODE-872" )
157    public void shouldReturnEmptyResultSetWhenNoResultsFoundForQuery() throws Exception {
158        Connection connection = connectToRemoteRepository();
159        String query = "SELECT [jcr:primaryType], [jcr:mixinTypes], [jcr:path], [jcr:name], [mode:localName], [mode:depth] FROM [mix:versionable] ORDER BY [jcr:path]";
160
161        Statement statement = null;
162        ResultSet rs = null;
163        try {
164            statement = connection.createStatement();
165            rs = statement.executeQuery(query);
166
167            assertNotNull(rs);
168            assertFalse(rs.next());
169        } finally {
170            if (rs != null) {
171                rs.close();
172            }
173            if (statement != null) {
174                statement.close();
175            }
176        }
177    }
178
179    protected String getContextPathUrl() {
180        // must match Cargo's configuration
181        return "localhost:8090/modeshape";
182    }
183
184    protected String getRepositoryName() {
185        // must match the configuration from modeshape-web-jcr-rest-war
186        return "repo";
187    }
188
189    protected String getWorkspaceName() {
190        // must match the configuration from modeshape-web-jcr-rest-war
191        return "default";
192    }
193
194    protected String getUserName() {
195        // must match Cargo's configuration
196        return "dnauser";
197    }
198
199    protected String getPassword() {
200        // must match Cargo's configuration
201        return "password";
202    }
203
204    private String getRepositoryUrl() {
205        return JcrDriver.HTTP_URL_PREFIX + getContextPathUrl() + "/" + getRepositoryName() + "/" + getWorkspaceName();
206    }
207
208    private Connection connectToRemoteRepository() throws SQLException {
209        Connection connection = DriverManager.getConnection(getRepositoryUrl(), driverProperties);
210        assertNotNull(connection);
211        return connection;
212    }
213}