View Javadoc

1   /*
2    * Copyright 2001-2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.juddi.registry;
17  
18  import java.io.IOException;
19  import java.io.InputStream;
20  import java.sql.Connection;
21  import java.sql.ResultSet;
22  import java.sql.SQLException;
23  import java.sql.Statement;
24  import java.util.Properties;
25  
26  import org.apache.commons.logging.Log;
27  import org.apache.commons.logging.LogFactory;
28  import org.apache.juddi.AbstractRegistry;
29  import org.apache.juddi.datatype.RegistryObject;
30  import org.apache.juddi.datatype.request.AuthInfo;
31  import org.apache.juddi.datatype.response.AuthToken;
32  import org.apache.juddi.error.RegistryException;
33  import org.apache.juddi.error.UnsupportedException;
34  import org.apache.juddi.function.FunctionMaker;
35  import org.apache.juddi.function.IFunction;
36  import org.apache.juddi.util.Config;
37  import org.apache.juddi.util.Loader;
38  import org.apache.juddi.util.jdbc.ConnectionManager;
39  
40  /***
41   * @author Steve Viens (sviens@apache.org)
42   * @author Kurt Stam (kurt@osconsulting.org)
43   */
44  public class RegistryEngine extends AbstractRegistry
45  {
46    // Registry Property File Name
47    private static final String PROPFILE_NAME = "juddi.properties";
48    
49    // Registry Property Names
50    //
51    public static final String PROPNAME_OPERATOR_NAME = "juddi.operatorName";
52    
53    public static final String PROPNAME_I18N_LANGUAGE_CODE = "juddi.i18n.languageCode";
54    public static final String PROPNAME_I18N_COUNTRY_CODE = "juddi.i18n.countryCode";
55    
56    public static final String PROPNAME_DISCOVERY_URL = "juddi.discoveryURL";
57    public static final String PROPNAME_ADMIN_EMAIL_ADDRESS = "juddi.adminEmailAddress"; // unused
58    public static final String PROPNAME_DATASOURCE_NAME = "juddi.dataSource";
59    public static final String PROPNAME_IS_USE_DATASOURCE = "juddi.isUseDataSource";
60    public static final String PROPNAME_JDBC_DRIVER = "juddi.jdbcDriver";
61    public static final String PROPNAME_JDBC_URL = "juddi.jdbcUrl";
62    public static final String PROPNAME_JDBC_USERNAME = "juddi.jdbcUsername";
63    public static final String PROPNAME_JDBC_PASSWORD = "juddi.jdbcPassword";
64    public static final String PROPNAME_IS_CREATE_DATABASE = "juddi.isCreateDatabase";
65    public static final String PROPNAME_DB_EXISTS_SQL = "juddi.databaseExistsSql";
66    public static final String PROPNAME_SQL_FILES = "juddi.sqlFiles";
67    public static final String PROPNAME_TABLE_PREFIX = "juddi.tablePrefix";
68    
69    public static final String PROPNAME_JAVA_NAMING_FACTORY_INITIAL = "java.naming.factory.initial";
70    public static final String PROPNAME_JAVA_NAMING_PROVIDER_URL = "java.naming.provider.url";
71    public static final String PROPNAME_JAVA_NAMING_FACTORY_URL_PKGS = "java.naming.factory.url.pkgs";
72    
73    public static final String PROPNAME_AUTH_CLASS_NAME = "juddi.auth";
74    public static final String PROPNAME_DATASTORE_CLASS_NAME = "juddi.dataStore";
75    public static final String PROPNAME_CRYPTOR_CLASS_NAME = "juddi.cryptor";
76    public static final String PROPNAME_UUIDGEN_CLASS_NAME = "juddi.uuidgen";
77    public static final String PROPNAME_VALIDATOR_CLASS_NAME = "juddi.validator";
78    
79    public static final String PROPNAME_MAX_NAME_ELEMENTS = "juddi.maxNameElementsAllowed";
80    public static final String PROPNAME_MAX_NAME_LENGTH = "juddi.maxNameLengthAllowed";
81    
82    public static final String PROPNAME_MAX_BUSINESSES_PER_PUBLISHER = "juddi.maxBusinessesPerPublisher";
83    public static final String PROPNAME_MAX_SERVICES_PER_BUSINESS = "juddi.maxServicesPerBusiness";
84    public static final String PROPNAME_MAX_BINDINGS_PER_SERVICE = "juddi.maxBindingsPerService";
85    public static final String PROPNAME_MAX_TMODELS_PER_PUBLISHER = "juddi.maxTModelsPerPublisher";
86  
87    public static final String PROPNAME_MAX_MESSAGE_SIZE = "juddi.maxMessageSize"; // unused
88    public static final String PROPNAME_MAX_ROWS_LIMIT = "juddi.maxRowsLimit"; // unused
89    
90    // Registry Default Property Values
91    //
92    public static final String DEFAULT_OPERATOR_NAME = "Apache.org";
93    
94    public static final String DEFAULT_I18N_LANGUAGE_CODE = "en";
95    public static final String DEFAULT_I18N_COUNTRY_CODE = "US";
96    
97    public static final String DEFAULT_DISCOVERY_URL = "http://localhost:8080/juddi/uddiget.jsp?";
98    public static final String DEFAULT_ADMIN_EMAIL_ADDRESS = "nobody@apache.org"; // unused
99    public static final String DEFAULT_DATASOURCE_NAME = "java:comp/env/jdbc/juddiDB";
100   public static final Boolean DEFAULT_IS_USE_DATASOURCE = Boolean.TRUE;
101   public static final String DEFAULT_JDBC_DRIVER = "com.mysql.jdbc.Driver";
102   public static final String DEFAULT_JDBC_URL = "jdbc:mysql://localhost/juddi";
103   public static final String DEFAULT_JDBC_USERNAME = "juddi";
104   public static final String DEFAULT_JDBC_PASSWORD = "juddi";
105   public static final Boolean DEFAULT_IS_CREATE_DATABASE = Boolean.FALSE;
106   public static final String DEFAULT_DB_EXISTS_SQL = "select * from BUSINESS_ENTITY";
107   public static final String DEFAULT_SQL_FILES = "sql/derby/create_database.sql,sql/insert_publishers.sql";
108   public static final String DEFAULT_TABLE_PREFIX = "";
109   
110   public static final String DEFAULT_AUTH_CLASS_NAME = "org.apache.juddi.auth.DefaultAuthenticator";
111   public static final String DEFAULT_DATASTORE_CLASS_NAME = "org.apache.juddi.datastore.jdbc.JDBCDataStore";
112   public static final String DEFAULT_CRYPTOR_CLASS_NAME = "org.apache.juddi.cryptor.DefaultCryptor";
113   public static final String DEFAULT_UUIDGEN_CLASS_NAME = "org.apache.juddi.uuidgen.DefaultUUIDGen";
114   public static final String DEFAULT_VALIDATOR_CLASS_NAME = "org.apache.juddi.validator.DefaultValidator";
115   
116   public static final String DEFAULT_JAVA_NAMING_FACTORY_INITIAL = "org.jnp.interfaces.NamingContextFactory";
117   public static final String DEFAULT_JAVA_NAMING_PROVIDER_URL = "jnp://localhost:1099";
118   public static final String DEFAULT_JAVA_NAMING_FACTORY_URL_PKGS = "org.jboss.naming";
119   
120   public static final int    DEFAULT_MAX_NAME_ELEMENTS = 5;
121   public static final int    DEFAULT_MAX_NAME_LENGTH = 255;    
122   public static final int    DEFAULT_MAX_MESSAGE_SIZE = 2097152; // unused
123   public static final int    DEFAULT_MAX_BUSINESSES_PER_PUBLISHER = -1; // unused
124   public static final int    DEFAULT_MAX_SERVICES_PER_BUSINESS = -1; // unused
125   public static final int    DEFAULT_MAX_BINDINGS_PER_SERVICE = -1; // unused
126   public static final int    DEFAULT_MAX_TMODELS_PER_PUBLISHER = -1; // unused
127   public static final int    DEFAULT_MAX_ROWS_LIMIT = 10; // unused
128   
129   // private reference to the jUDDI logger
130   private static Log log = LogFactory.getLog(RegistryEngine.class);
131 
132   // Function maker
133   private FunctionMaker maker = null;
134 
135   // registry status
136   private boolean isAvailable = false;
137 
138   /***
139    * Create a new instance of RegistryEngine.  This constructor
140    * looks in the classpath for a file named 'juddi.properties'
141    * and uses property values in this file to initialize the
142    * new instance. Default values are used if the file does not
143    * exist or if a particular property value is not present.
144    */
145   public RegistryEngine()
146   {
147     super();
148 
149     // Add jUDDI properties from the juddi.properties
150     // file found in the classpath. Duplicate property
151     // values added in init() will be overwritten.
152     try {
153       InputStream stream = Loader.getResourceAsStream(PROPFILE_NAME);
154       if (stream != null)
155       {
156         Properties props = new Properties();
157         props.load(stream);
158         Config.addProperties(props);
159       }
160     }
161     catch (IOException ioex) {
162       log.error("An error occured while loading properties from: "+PROPFILE_NAME,ioex);
163     }
164   }
165 
166   /***
167    * Creates a new instance of RegistryEngine. This constructor
168    * uses the property values passed in the Properties parameter
169    * to initialize the new RegistryProxy instance. Default values 
170    * are used if the file does not exist or if a particular 
171    * property value is not present.
172    */
173   public RegistryEngine(Properties props)
174   {
175     super();
176 
177     if (props != null)
178       Config.addProperties(props);
179   }
180 
181   /***
182    * Initialize required resources.
183    */
184   public void init()
185   {
186     // Turn off registry access
187     isAvailable = false;
188 
189     // Grab a reference to the function
190     // registry (hmm bad name choice).
191     this.maker = new FunctionMaker(this);
192     
193     if (Config.getBooleanProperty(
194             RegistryEngine.PROPNAME_IS_CREATE_DATABASE,RegistryEngine.DEFAULT_IS_CREATE_DATABASE.booleanValue())) {
195         // Initialize database
196         initializeDatabase();
197     }
198 
199     // Turn on registry access
200     isAvailable = true;
201   }
202 
203   /***
204    * Releases any acquired resources. Will stop these
205    * if they are currently running.
206    */
207   public void dispose()
208   {
209     // Turn off registry access
210     isAvailable = false;
211   }
212 
213   /***
214    * Returns 'true' if the registry is available
215    * to handle requests, otherwise returns 'false'.
216    */
217   public boolean isAvailable()
218   {
219     return this.isAvailable;
220   }
221 
222   /***
223    *
224    */
225   public RegistryObject execute(RegistryObject request)
226     throws RegistryException
227   {
228     String className = request.getClass().getName();
229 
230     IFunction function = (IFunction)maker.lookup(className);
231     if (function == null)
232       throw new UnsupportedException(className);
233 
234     RegistryObject response = function.execute(request);
235 
236     return response;
237   }
238   
239   private void initializeDatabase()
240   {
241       String dbExistsSql = Config.getStringProperty(
242               RegistryEngine.PROPNAME_DB_EXISTS_SQL,RegistryEngine.DEFAULT_DB_EXISTS_SQL);
243       String sqlFiles = Config.getStringProperty(
244               RegistryEngine.PROPNAME_SQL_FILES,RegistryEngine.DEFAULT_SQL_FILES);
245       String tablePrefix = Config.getStringProperty(
246               RegistryEngine.PROPNAME_TABLE_PREFIX,RegistryEngine.DEFAULT_TABLE_PREFIX);
247       
248       Connection conn=null;
249       try {
250           conn = ConnectionManager.acquireConnection();
251           boolean create = false;
252 
253           Statement st = conn.createStatement();
254           ResultSet rs = null;
255           try {
256              dbExistsSql = dbExistsSql.trim().replaceAll("//$//{prefix}", tablePrefix);
257              rs = st.executeQuery(dbExistsSql);
258              rs.close();
259           } catch (SQLException e) {
260              create = true;
261           }
262           st.close();
263           if (!create) {
264              log.debug("jUDDI Database is already initialized");
265              return;
266           }
267           log.info("Initializing jUDDI database from listed sql files");
268           String[] list = sqlFiles.split(",");
269           for (int i=0; i<list.length; i++) {
270              executeSql(list[i].trim(), conn, tablePrefix);
271           }
272       } catch (Exception e) {
273           log.error("Could not create jUDDI database " + e.getMessage(), e);
274       } finally {
275     	  if (conn!=null) {
276     		  try {
277     			  if (!conn.isClosed()) conn.close();
278     		  } catch (SQLException e) {}
279     	  }
280       }
281   }
282   
283   public void executeSql(String resource, Connection conn, String tablePrefix) throws Exception 
284   { 
285         InputStream is = Loader.getResourceAsStream(resource);
286         if (is == null) {
287             log.debug("Trying the classloader of the class itself. (workaround for maven2)");
288             Loader loader = new Loader();
289             is = loader.getResourceAsStreamFromClass(resource);
290         }
291         String sql = getString(is);
292         sql = sql.replaceAll("(?m)^--([^\n]+)?$", ""); // Remove all commented lines
293         sql = sql.replaceAll("//$//{prefix}", tablePrefix);
294         is.close();
295         String[] statements = sql.split(";");
296         for (int i=0; i<statements.length;i++) {
297             String statement = statements[i].trim();
298             Statement sqlStatement = null;
299             if (!"".equals(statement)) {
300                 try {
301                     sqlStatement = conn.createStatement();
302                     sqlStatement.executeUpdate(statement);
303                 } catch (Exception e) {
304                     //ignore drop errors
305                     if (!statement.toUpperCase().startsWith("DROP")) {
306                         throw e;
307                     }
308                 } finally {
309                     sqlStatement.close();
310                 }
311             }
312         }
313     }
314   
315   public static String getString(InputStream in) throws IOException {
316       StringBuffer out = new StringBuffer();
317       byte[] b = new byte[4096];
318       for (int n; (n = in.read(b)) != -1;) {
319           out.append(new String(b, 0, n));
320       }
321       return out.toString();
322   }
323 
324 
325   
326 
327   /****************************************************************************/
328   /****************************** TEST DRIVER *********************************/
329   /****************************************************************************/
330 
331 
332   public static void main(String[] args)
333     throws Exception
334   {
335     // Option #1 (grabs properties from juddi.properties file)
336     //RegistryEngine registry = new RegistryEngine();
337     
338     // Option #2 (provides properties in Properties instance)
339     Properties props = new Properties();
340     props.setProperty(RegistryEngine.PROPNAME_OPERATOR_NAME,"jUDDI.org");
341     props.setProperty(RegistryEngine.PROPNAME_MAX_NAME_ELEMENTS,"5");
342     props.setProperty(RegistryEngine.PROPNAME_MAX_NAME_LENGTH,"255");
343     props.setProperty(RegistryEngine.PROPNAME_DISCOVERY_URL,"http://localhost/juddi");
344     props.setProperty(RegistryEngine.PROPNAME_ADMIN_EMAIL_ADDRESS,"admin@juddi.org");    
345     props.setProperty(RegistryEngine.PROPNAME_MAX_MESSAGE_SIZE,"2097152");
346     props.setProperty(RegistryEngine.PROPNAME_AUTH_CLASS_NAME,"org.apache.juddi.auth.DefaultAuthenticator");
347     props.setProperty(RegistryEngine.PROPNAME_CRYPTOR_CLASS_NAME,"org.apache.juddi.cryptor.DefaultCryptor");
348     props.setProperty(RegistryEngine.PROPNAME_UUIDGEN_CLASS_NAME,"org.apache.juddi.uuidgen.DefaultUUIDGen");
349     
350     props.setProperty("juddi.useConnectionPool","true");
351     props.setProperty("juddi.jdbcDriver","com.mysql.jdbc.Driver");
352     props.setProperty("juddi.jdbcURL","jdbc:mysql://localhost/juddi");
353     props.setProperty("juddi.jdbcUser","juddi");
354     props.setProperty("juddi.jdbcPassword","juddi");
355     props.setProperty("juddi.jdbcMaxActive","10");
356     props.setProperty("juddi.jdbcMaxIdle","10");
357     
358     RegistryEngine registry = new RegistryEngine(props);    
359 
360     // initialize the registry
361     registry.init();
362 
363     // write all properties to the console
364     System.out.println(Config.getProperties());
365 
366     AuthToken authToken = registry.getAuthToken("sviens","password");
367     AuthInfo authInfo = authToken.getAuthInfo();
368 
369     System.out.println("AuthToken: "+authInfo.getValue());    
370 
371     // tear down the registry
372     registry.dispose();
373   }
374 }