001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.geronimo.console.internaldb; 019 020 import java.sql.Connection; 021 import java.sql.DriverManager; 022 import java.sql.SQLException; 023 import java.util.Set; 024 025 import javax.sql.DataSource; 026 027 import org.apache.commons.logging.Log; 028 import org.apache.commons.logging.LogFactory; 029 import org.apache.geronimo.console.util.KernelManagementHelper; 030 import org.apache.geronimo.console.util.ManagementHelper; 031 import org.apache.geronimo.derby.DerbySystemGBean; 032 import org.apache.geronimo.gbean.AbstractName; 033 import org.apache.geronimo.gbean.AbstractNameQuery; 034 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory; 035 import org.apache.geronimo.kernel.Kernel; 036 import org.apache.geronimo.kernel.KernelRegistry; 037 import org.apache.geronimo.management.JCAManagedConnectionFactory; 038 import org.apache.geronimo.management.geronimo.ResourceAdapterModule; 039 040 /** 041 * A static class to handle retreiving connections. This class is built to 042 * handle lookups to the SystemDatabase as a special case. If a connection is 043 * requested for the SystemDatabase this class gets a DataSource from an admin 044 * object registered in the geronimo kernel otherwise the DataSource is looked 045 * up via JNDI. 046 * 047 * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $ 048 */ 049 public class DerbyConnectionUtil { 050 051 private final static Log log = LogFactory.getLog(DerbyConnectionUtil.class); 052 053 public static final String CREATE_DB_PROP = ";create=true"; 054 055 public static final String SHUTDOWN_DB_PROP = ";shutdown=true"; 056 057 private static final int RDBMS_DERBY = 1; 058 059 private static final int RDBMS_MSSQL = 2; 060 061 private static final String SYSTEM_DB = "SYSTEMDATABASE"; 062 063 private static final String DERBY_DRIVER = "org.apache.derby.jdbc.EmbeddedDriver"; 064 065 private static final String PROTOCOL = "jdbc:derby:"; 066 067 private static final String EMPTY_PROPS = ""; 068 069 private static AbstractName SYSTEM_DATASOURCE_NAME = null; 070 071 static { 072 try { 073 log.debug("Looking up system datasource name..."); 074 075 // cache the name for the system data source 076 AbstractNameQuery query = new AbstractNameQuery(JCAManagedConnectionFactory.class.getName()); 077 Set<AbstractName> names = KernelRegistry.getSingleKernel().listGBeans(query); 078 for (AbstractName name : names) { 079 String nameProperty = name.getNameProperty("name"); 080 if ("SystemDatasource".equals(nameProperty)) { 081 SYSTEM_DATASOURCE_NAME = name; 082 log.debug("Using system datasource name: " + SYSTEM_DATASOURCE_NAME); 083 } 084 } 085 086 if (SYSTEM_DATASOURCE_NAME == null) { 087 log.warn("Failed to lookup system datasource name"); 088 } 089 } 090 catch (Throwable t) { 091 // 092 // HACK: Log any errors which occur when this is loading... 093 // the system is not logging the full detail, which it should 094 // but for now lets show the details here 095 // 096 log.error("Failed to initialize", t); 097 throw new Error(t); 098 } 099 } 100 101 private static String derbyHome = null; 102 103 /** 104 * Get the Derby home directory path. 105 */ 106 public static String getDerbyHome() { 107 if (derbyHome == null) { 108 try { 109 derbyHome = (String)KernelRegistry.getSingleKernel().getAttribute(DerbySystemGBean.class, "derbyHome"); 110 } 111 catch (Exception e) { 112 throw new RuntimeException("Failed to query derbyHome", e); 113 } 114 } 115 return derbyHome; 116 } 117 118 /** 119 * Get database connection. 120 * 121 * @param dbName 122 * @return 123 * @throws SQLException 124 */ 125 private static Connection getConnection(String dbName, String properties, 126 String protocol, String driver) throws SQLException { 127 try { 128 Class.forName(driver).newInstance(); 129 } catch (Exception e) { 130 log.error("Problem loading driver class", e); 131 } 132 // If we are looking for the SystemDatabase get it from the kernel 133 // because it is not binded to our JNDI Context. 134 if (SYSTEM_DB.equalsIgnoreCase(dbName)) { 135 return getSystemDBConnection(); 136 } else { 137 return DriverManager.getConnection(protocol + dbName + properties); 138 } 139 } 140 141 /** 142 * Get a connection to derby. 143 * 144 * @param dbName 145 * the name of the database to connect to. 146 * @param properties 147 * the properties to pass to the connection string. 148 * @return connection 149 */ 150 public static Connection getDerbyConnection(String dbName, String properties) 151 throws SQLException { 152 return getConnection(dbName, properties, PROTOCOL, DERBY_DRIVER); 153 } 154 155 public static Connection getDerbyConnection(String dbName) 156 throws SQLException { 157 return getDerbyConnection(dbName, EMPTY_PROPS); 158 } 159 160 /** 161 * Get a connection to the SystemDatabase. 162 * 163 * @return 164 * @throws SQLException 165 */ 166 public static Connection getSystemDBConnection() throws SQLException { 167 DataSource ds = null; 168 try { 169 ds = getDataSource(SYSTEM_DB); 170 return ds.getConnection(); 171 } catch (Exception e) { 172 throw new SQLException(e.getMessage()); 173 } 174 } 175 176 /** 177 * Get the datasource if dbName is == SYSTEM_DB, otherwise returns null. 178 * 179 * @param dbName 180 * @return datasource 181 */ 182 public static DataSource getDataSource(String dbName) { 183 try { 184 if (SYSTEM_DATASOURCE_NAME!=null && SYSTEM_DB.equalsIgnoreCase(dbName)) { 185 return (DataSource) KernelRegistry.getSingleKernel().invoke( 186 SYSTEM_DATASOURCE_NAME, "$getResource"); 187 } 188 } catch (Exception e) { 189 log.error("Problem getting datasource " + dbName, e); 190 } 191 192 Kernel kernel = KernelRegistry.getSingleKernel(); 193 ManagementHelper helper = new KernelManagementHelper(kernel); 194 ResourceAdapterModule[] modules = helper.getOutboundRAModules(helper.getDomains()[0].getServerInstances()[0], "javax.sql.DataSource"); 195 for (ResourceAdapterModule module : modules) { 196 org.apache.geronimo.management.geronimo.JCAManagedConnectionFactory[] databases = helper.getOutboundFactories(module, "javax.sql.DataSource"); 197 for (org.apache.geronimo.management.geronimo.JCAManagedConnectionFactory db : databases) { 198 try { 199 Object databaseName = db.getConfigProperty("DatabaseName"); 200 if(dbName.equalsIgnoreCase((String) databaseName)) { 201 AbstractName tempDbName = helper.getNameFor(db); 202 return (DataSource) KernelRegistry.getSingleKernel().invoke( 203 tempDbName, "$getResource"); 204 } 205 } catch (Exception ignored) { 206 } 207 } 208 } 209 210 return null; 211 } 212 213 }