/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2002-2011, Open Source Geospatial Foundation (OSGeo)
*
* 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;
* version 2.1 of the License.
*
* 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.
*/
package org.geoserver.jdbcconfig.internal;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import org.easymock.Capture;
import org.easymock.IAnswer;
import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.DataStoreInfo;
import org.geoserver.catalog.Info;
import org.geoserver.catalog.WorkspaceInfo;
import org.geoserver.catalog.impl.DataStoreInfoImpl;
import org.geoserver.catalog.impl.WorkspaceInfoImpl;
import org.geoserver.config.ConfigurationListener;
import org.geoserver.config.GeoServer;
import org.geoserver.config.ServiceInfo;
import org.geoserver.jdbcconfig.JDBCConfigTestSupport;
import org.geoserver.wms.WMSInfo;
import org.geoserver.wms.WMSInfoImpl;
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import static org.easymock.EasyMock.*;
/**
* @author groldan
*
*/
@RunWith(Parameterized.class)
public class ConfigDatabaseTest {
private JDBCConfigTestSupport testSupport;
private ConfigDatabase database;
private GeoServer geoServer;
public ConfigDatabaseTest(JDBCConfigTestSupport.DBConfig dbConfig) {
testSupport = new JDBCConfigTestSupport(dbConfig);
}
@Parameterized.Parameters(name = "{0}")
public static Iterable<Object[]> data() {
return JDBCConfigTestSupport.parameterizedDBConfigs();
}
@Before
public void setUp() throws Exception {
testSupport.setUp();
database = testSupport.getDatabase();
// Mock the GeoServer instance to accept a listener, and to provide that listener back when asked
geoServer = createMock(GeoServer.class);
final Capture<ConfigurationListener> cap = new Capture<ConfigurationListener>();
geoServer.addListener(capture(cap)); expectLastCall().asStub();
expect(geoServer.getListeners()).andStubAnswer(new IAnswer<Collection<ConfigurationListener>>(){
@Override
public Collection<ConfigurationListener> answer() throws Throwable {
return cap.getValues();
}});
replay(geoServer);
database.setGeoServer(geoServer);
}
@After
public void tearDown() throws Exception {
verify(geoServer);
database.dispose();
testSupport.tearDown();
}
@Test
public void testAdd() throws Exception {
WorkspaceInfoImpl ws = new WorkspaceInfoImpl();
try {
database.add(ws);
fail("Expected NPE on null id");
} catch (NullPointerException e) {
assertEquals("Object has no id", e.getMessage());
}
ws.setId("wsid");
ws.setName("ws1");
WorkspaceInfo addedWs = database.add(ws);
assertNotNull(addedWs);
assertTrue(addedWs instanceof Proxy);
assertEquals(ws, addedWs);
DataStoreInfo addedDs = addDataStore(ws);
assertNotNull(addedDs);
}
private DataStoreInfo addDataStore(WorkspaceInfo ws) {
Catalog catalog = database.getCatalog();
DataStoreInfoImpl ds = new DataStoreInfoImpl(catalog);
ds.setWorkspace(ws);
ds.setId("ds1");
ds.getConnectionParameters().put("param1", "value1");
ds.getConnectionParameters().put("param2", "value2");
ds.setName("data store one");
ds.setDescription("data store description one");
ds.setEnabled(true);
ds.setType("Foo");
DataStoreInfo addedDs = database.add(ds);
return addedDs;
}
@Test
public void testModifyWorkspace() throws Exception {
WorkspaceInfo ws = addWorkspace();
ws.setName("newName");
testSaved(ws);
}
private WorkspaceInfo addWorkspace() {
WorkspaceInfo ws = new WorkspaceInfoImpl();
((WorkspaceInfoImpl) ws).setId("wsid");
ws.setName("ws1");
ws = database.add(ws);
return ws;
}
/**
* @param info
*/
private void testSaved(Info info) {
Info saved = database.save(info);
assertNotSame(info, saved);
if (info instanceof DataStoreInfo) {
assertEquals(((DataStoreInfo) info).getWorkspace(),
((DataStoreInfo) saved).getWorkspace());
}
assertEquals(info, saved);
}
@Test
public void testModifyService(){
// Create a service to modify
WMSInfo service = new WMSInfoImpl();
((WMSInfoImpl) service).setId("WMS-TEST");
service.setName("WMS");
service.setMaintainer("Foo");
service = database.add(service);
assertEquals(service.getMaintainer(), "Foo");
service.setMaintainer("Bar");
testSaved(service);
}
@Test
public void testCacheCatalog() throws Exception {
// Simulates the situation where multiple GeoServer instances are sharing a database.
WorkspaceInfo ws = addWorkspace();
ws.setName("name1");
testSaved(ws);
// Change the stored configuration
// KS: sorry, this is an utter kludge
Connection conn = testSupport.getDataSource().getConnection();
try {
Statement stmt = conn.createStatement();
assertEquals(1, stmt.executeUpdate("UPDATE object_property SET value='name2' WHERE property_type=(SELECT oid FROM property_type WHERE type_id = (SELECT oid FROM type WHERE typename='org.geoserver.catalog.WorkspaceInfo') AND name='name') AND id = '"+ws.getId()+"'"));
assertEquals(1, stmt.executeUpdate("UPDATE object SET blob=(SELECT replace(blob, '<name>name1</name>', '<name>name2</name>') FROM object WHERE id = '"+ws.getId()+"')"));
} finally {
conn.close();
}
// Should be cached
WorkspaceInfo ws2 = database.getById(ws.getId(), WorkspaceInfo.class);
assertEquals("name1", ws2.getName());
// Notify of update
testSupport.getCatalog().firePostModified(ws2, Arrays.asList("name"), Arrays.asList("name1"), Arrays.asList("name2"));
// Should show the new value
WorkspaceInfo ws3 = database.getById(ws.getId(), WorkspaceInfo.class);
assertEquals("name2", ws3.getName());
}
@Test
public void testCacheConfig() throws Exception {
// Simulates the situation where multiple GeoServer instances are sharing a database.
ServiceInfo service = new WMSInfoImpl();
((WMSInfoImpl) service).setId("WMS-TEST");
service.setName("WMS");
service.setMaintainer("Foo");
service = database.add(service);
assertEquals(service.getMaintainer(), "Foo");
// Change the stored configuration
// KS: sorry, this is an utter kludge
Connection conn = testSupport.getDataSource().getConnection();
try {
Statement stmt = conn.createStatement();
//assertEquals(1, stmt.executeUpdate("UPDATE object_property SET value='Bar' WHERE property_type=(SELECT oid FROM property_type WHERE type_id = (SELECT oid FROM type WHERE typename='org.geoserver.wms.ServiceInfo') AND name='maintainer') AND id = '"+service.getId()+"';"));
assertEquals(1, stmt.executeUpdate("UPDATE object SET blob=(SELECT replace(blob, '<maintainer>Foo</maintainer>', '<maintainer>Bar</maintainer>') FROM object WHERE id = '"+service.getId()+"')"));
} finally {
conn.close();
}
// Should be cached
service = database.getById(service.getId(), ServiceInfo.class);
assertEquals("Foo", service.getMaintainer());
// Notify of update
for(ConfigurationListener l : database.getGeoServer().getListeners()){
l.handlePostServiceChange(service);
}
// Should show the new value
service = database.getById(service.getId(), ServiceInfo.class);
assertEquals("Bar", service.getMaintainer());
}
public void testGetServiceWithGeoServerRef() {
WMSInfo service = new WMSInfoImpl();
((WMSInfoImpl) service).setId("WMS-TEST");
service.setName("WMS");
service.setMaintainer("Foo");
service = database.add(service);
database.clear(service);
service = database.getAll(WMSInfo.class).iterator().next();
assertNotNull(service.getGeoServer());
}
}