001/**
002 * Logback: the reliable, generic, fast and flexible logging framework.
003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
004 *
005 * This program and the accompanying materials are dual-licensed under
006 * either the terms of the Eclipse Public License v1.0 as published by
007 * the Eclipse Foundation
008 *
009 *   or (per the licensee's choosing)
010 *
011 * under the terms of the GNU Lesser General Public License version 2.1
012 * as published by the Free Software Foundation.
013 */
014package ch.qos.logback.access.db;
015
016import static org.junit.Assert.assertEquals;
017import static org.junit.Assert.assertFalse;
018import static org.junit.Assert.assertNotNull;
019import static org.junit.Assert.fail;
020
021import java.sql.ResultSet;
022import java.sql.SQLException;
023import java.sql.Statement;
024
025import ch.qos.logback.access.spi.IAccessEvent;
026import org.junit.After;
027import org.junit.AfterClass;
028import org.junit.Before;
029import org.junit.BeforeClass;
030import org.junit.Test;
031
032import ch.qos.logback.access.dummy.DummyRequest;
033import ch.qos.logback.access.dummy.DummyResponse;
034import ch.qos.logback.access.dummy.DummyServerAdapter;
035import ch.qos.logback.access.spi.AccessContext;
036import ch.qos.logback.access.spi.AccessEvent;
037import ch.qos.logback.core.db.DriverManagerConnectionSource;
038import ch.qos.logback.core.util.StatusPrinter;
039
040public class DBAppenderHSQLTest {
041    static DBAppenderHSQLTestFixture DB_APPENDER_HSQL_TEST_FIXTURE;
042
043    AccessContext context;
044    DBAppender appender;
045    DriverManagerConnectionSource connectionSource;
046
047    int existingEventTableRowCount;
048    Statement stmt;
049
050    @BeforeClass
051    static public void fixtureSetUp() throws SQLException {
052        DB_APPENDER_HSQL_TEST_FIXTURE = new DBAppenderHSQLTestFixture();
053        DB_APPENDER_HSQL_TEST_FIXTURE.setUp();
054    }
055
056    @AfterClass
057    static public void fixtureTearDown() throws SQLException {
058        DB_APPENDER_HSQL_TEST_FIXTURE.tearDown();
059    }
060
061    @Before
062    public void setUp() throws SQLException {
063        context = new AccessContext();
064        context.setName("default");
065        appender = new DBAppender();
066        appender.setName("DB");
067        appender.setContext(context);
068        connectionSource = new DriverManagerConnectionSource();
069        connectionSource.setContext(context);
070        connectionSource.setDriverClass(DBAppenderHSQLTestFixture.DRIVER_CLASS);
071        connectionSource.setUrl(DB_APPENDER_HSQL_TEST_FIXTURE.url);
072        connectionSource.setUser(DB_APPENDER_HSQL_TEST_FIXTURE.user);
073        connectionSource.setPassword(DB_APPENDER_HSQL_TEST_FIXTURE.password);
074        connectionSource.start();
075        appender.setConnectionSource(connectionSource);
076
077        stmt = connectionSource.getConnection().createStatement();
078        existingEventTableRowCount = existingEventTableRowCount(stmt);
079    }
080
081    @After
082    public void tearDown() throws SQLException {
083        context = null;
084        appender = null;
085        connectionSource = null;
086        stmt.close();
087    }
088
089    int existingEventTableRowCount(Statement stmt) throws SQLException {
090        ResultSet rs = stmt.executeQuery("SELECT count(*) FROM access_event");
091        int result = -1;
092        if (rs.next()) {
093            result = rs.getInt(1);
094        }
095        rs.close();
096        return result;
097    }
098
099    private void setInsertHeadersAndStart(boolean insert) {
100        appender.setInsertHeaders(insert);
101        appender.start();
102    }
103
104    @Test
105    public void testAppendAccessEvent() throws SQLException {
106        setInsertHeadersAndStart(false);
107
108        IAccessEvent event = createAccessEvent();
109        appender.append(event);
110
111        Statement stmt = connectionSource.getConnection().createStatement();
112        ResultSet rs = null;
113        rs = stmt.executeQuery("SELECT * FROM access_event where EVENT_ID = " + existingEventTableRowCount);
114        if (rs.next()) {
115            assertEquals(event.getTimeStamp(), rs.getLong(1));
116            assertEquals(event.getRequestURI(), rs.getString(2));
117            assertEquals(event.getRequestURL(), rs.getString(3));
118            assertEquals(event.getRemoteHost(), rs.getString(4));
119            assertEquals(event.getRemoteUser(), rs.getString(5));
120            assertEquals(event.getRemoteAddr(), rs.getString(6));
121            assertEquals(event.getProtocol(), rs.getString(7));
122            assertEquals(event.getMethod(), rs.getString(8));
123            assertEquals(event.getServerName(), rs.getString(9));
124            assertEquals(event.getRequestContent(), rs.getString(10));
125        } else {
126            fail("No row was inserted in the database");
127        }
128        rs.close();
129        stmt.close();
130    }
131
132    @Test
133    public void testCheckNoHeadersAreInserted() throws Exception {
134        setInsertHeadersAndStart(false);
135
136        IAccessEvent event = createAccessEvent();
137        appender.append(event);
138        StatusPrinter.print(context.getStatusManager());
139
140        // Check that no headers were inserted
141        Statement stmt = connectionSource.getConnection().createStatement();
142        ResultSet rs = null;
143        rs = stmt.executeQuery("SELECT * FROM access_event_header where EVENT_ID = " + existingEventTableRowCount);
144
145        assertFalse(rs.next());
146        rs.close();
147        stmt.close();
148    }
149
150    @Test
151    public void testAppendHeaders() throws SQLException {
152        setInsertHeadersAndStart(true);
153
154        IAccessEvent event = createAccessEvent();
155        appender.append(event);
156
157        Statement stmt = connectionSource.getConnection().createStatement();
158        ResultSet rs = null;
159        rs = stmt.executeQuery("SELECT * FROM access_event_header");
160        String key;
161        String value;
162        if (!rs.next()) {
163            fail("There should be results to this query");
164        } else {
165            key = rs.getString(2);
166            value = rs.getString(3);
167            assertNotNull(key);
168            assertNotNull(value);
169            assertEquals(event.getRequestHeader(key), value);
170            rs.next();
171            key = rs.getString(2);
172            value = rs.getString(3);
173            assertNotNull(key);
174            assertNotNull(value);
175            assertEquals(event.getRequestHeader(key), value);
176        }
177        if (rs.next()) {
178            fail("There should be no more rows available");
179        }
180
181        rs.close();
182        stmt.close();
183    }
184
185    @Test
186    public void testAppendMultipleEvents() throws SQLException {
187        setInsertHeadersAndStart(false);
188        String uri = "testAppendMultipleEvents";
189        for (int i = 0; i < 10; i++) {
190            IAccessEvent event = createAccessEvent(uri);
191            appender.append(event);
192        }
193
194        StatusPrinter.print(context);
195
196        Statement stmt = connectionSource.getConnection().createStatement();
197        ResultSet rs = null;
198        rs = stmt.executeQuery("SELECT * FROM access_event where requestURI='" + uri + "'");
199        int count = 0;
200        while (rs.next()) {
201            count++;
202        }
203        assertEquals(10, count);
204
205        rs.close();
206        stmt.close();
207    }
208
209    private IAccessEvent createAccessEvent() {
210        return createAccessEvent("");
211    }
212
213    private IAccessEvent createAccessEvent(String uri) {
214        DummyRequest request = new DummyRequest();
215        request.setRequestUri(uri);
216        DummyResponse response = new DummyResponse();
217        DummyServerAdapter adapter = new DummyServerAdapter(request, response);
218
219        return new AccessEvent(request, response, adapter);
220    }
221}