View Javadoc

1   /***
2    * Redistribution and use of this software and associated documentation
3    * ("Software"), with or without modification, are permitted provided
4    * that the following conditions are met:
5    *
6    * 1. Redistributions of source code must retain copyright
7    *    statements and notices.  Redistributions must also contain a
8    *    copy of this document.
9    *
10   * 2. Redistributions in binary form must reproduce the
11   *    above copyright notice, this list of conditions and the
12   *    following disclaimer in the documentation and/or other
13   *    materials provided with the distribution.
14   *
15   * 3. The name "Exolab" must not be used to endorse or promote
16   *    products derived from this Software without prior written
17   *    permission of Exoffice Technologies.  For written permission,
18   *    please contact info@exolab.org.
19   *
20   * 4. Products derived from this Software may not be called "Exolab"
21   *    nor may "Exolab" appear in their names without prior written
22   *    permission of Exoffice Technologies. Exolab is a registered
23   *    trademark of Exoffice Technologies.
24   *
25   * 5. Due credit should be given to the Exolab Project
26   *    (http://www.exolab.org/).
27   *
28   * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS
29   * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
32   * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39   * OF THE POSSIBILITY OF SUCH DAMAGE.
40   *
41   * Copyright 2005 (C) Exoffice Technologies Inc. All Rights Reserved.
42   *
43   * $Id: Exporter.java,v 1.3 2005/11/12 12:47:37 tanderson Exp $
44   */
45  package org.exolab.jms.tools.migration;
46  
47  import java.sql.Connection;
48  import java.sql.SQLException;
49  import javax.jms.JMSException;
50  
51  import org.apache.commons.logging.Log;
52  import org.apache.commons.logging.LogFactory;
53  import org.apache.derby.jdbc.EmbeddedDataSource;
54  
55  import org.exolab.jms.config.Configuration;
56  import org.exolab.jms.config.ConfigurationReader;
57  import org.exolab.jms.persistence.DatabaseService;
58  import org.exolab.jms.persistence.PersistenceException;
59  import org.exolab.jms.service.ServiceException;
60  import org.exolab.jms.tools.db.Database;
61  import org.exolab.jms.tools.db.RDBMSTool;
62  import org.exolab.jms.tools.migration.master.MasterConsumerStore;
63  import org.exolab.jms.tools.migration.master.MasterDestinationStore;
64  import org.exolab.jms.tools.migration.master.MasterMessageStore;
65  import org.exolab.jms.tools.migration.master.MasterUserStore;
66  import org.exolab.jms.tools.migration.proxy.ConsumerStore;
67  import org.exolab.jms.tools.migration.proxy.DestinationStore;
68  import org.exolab.jms.tools.migration.proxy.MessageStore;
69  import org.exolab.jms.tools.migration.proxy.PropertyStore;
70  import org.exolab.jms.tools.migration.proxy.UserStore;
71  import org.exolab.jms.tools.migration.proxy.VersionInfo;
72  import org.exolab.jms.util.CommandLine;
73  import org.exolab.jms.util.Version;
74  
75  
76  /***
77   * Exports data from a master database into a proxy.
78   *
79   * @author <a href="mailto:tma@netspace.net.au">Tim Anderson</a>
80   * @version $Revision: 1.3 $ $Date: 2005/11/12 12:47:37 $
81   * @see Importer
82   */
83  public class Exporter {
84  
85      /***
86       * The database service.
87       */
88      private final DatabaseService _database;
89  
90      /***
91       * The connection factory for the target database.
92       */
93      private final EmbeddedDataSource _dataSource;
94  
95      /***
96       * The logger.
97       */
98      private final Log _log = LogFactory.getLog(Exporter.class);
99  
100 
101     /***
102      * Construct a new <code>Exporter</code>.
103      *
104      * @param config   the configuration to use
105      * @param database the database name
106      * @param delete   if <code>true</code>, indicates to delete data in the
107      *                 migration database, if it exists
108      */
109     public Exporter(Configuration config, String database, boolean delete)
110             throws PersistenceException {
111         if (config == null) {
112             throw new IllegalArgumentException("Argument 'config' is null");
113         }
114         if (database == null) {
115             throw new IllegalArgumentException("Argument 'database' is null");
116         }
117         _database = new DatabaseService(config);
118         _dataSource = MigrationHelper.getDataSource(database);
119 
120         init(delete);
121     }
122 
123     /***
124      * Export the data from the master database to the migration database.
125      *
126      * @throws JMSException
127      * @throws PersistenceException for any persistence error
128      * @throws ServiceException     for any service error
129      */
130     public void apply() throws JMSException, PersistenceException,
131                                ServiceException {
132         // get a connection to the migration database
133         Connection connection;
134         try {
135             connection = _dataSource.getConnection();
136         } catch (SQLException exception) {
137             throw new PersistenceException(
138                     "Failed to get connection to target database",
139                     exception);
140         }
141 
142         PropertyStore properties = new PropertyStore(connection);
143         VersionInfo info = new VersionInfo(properties);
144         info.setProxySchemaVersion("1.0");
145         info.setOpenJMSVersion(Version.VERSION);
146         info.setCreationTimestamp(System.currentTimeMillis());
147 
148         DestinationStore destinations = new DestinationStore(connection);
149         ConsumerStore consumers = new ConsumerStore(destinations, connection);
150         MessageStore messages = new MessageStore(destinations, connection);
151         UserStore users = new UserStore(connection);
152 
153         // export data from the master database to the migration database
154         _database.start();
155 
156         _log.info("Exporting destinations...");
157         apply(new MasterDestinationStore(_database), destinations);
158         _log.info("Exported " + destinations.size() + " destinations");
159 
160         _log.info("Exporting messages...");
161         apply(new MasterMessageStore(_database), messages);
162         _log.info("Exported " + messages.size() + " messages");
163 
164         _log.info("Exporting consumers...");
165         apply(new MasterConsumerStore(_database), consumers);
166         _log.info("Exported " + consumers.size() + " consumers");
167 
168         _log.info("Exporting users...");
169         apply(new MasterUserStore(_database), users);
170         _log.info("Exported " + users.size() + " users");
171 
172         try {
173             connection.close();
174         } catch (SQLException exception) {
175             throw new PersistenceException("Failed to close target",
176                                            exception);
177         }
178 
179         _database.stop();
180         _dataSource.setShutdownDatabase("shutdown");
181 
182         _log.info("Export complete");
183     }
184 
185     /***
186      * Main line.
187      *
188      * @param args command line arguments
189      */
190     public static void main(String[] args) {
191         CommandLine commands = new CommandLine(args);
192 
193         String path = commands.value("config");
194         if (path == null) {
195             usage();
196             System.exit(1);
197         } else {
198             try {
199                 Configuration config = ConfigurationReader.read(path);
200 
201                 String database = commands.value("db");
202                 if (database == null) {
203                     database = "openjms_migdb";
204                 }
205                 boolean delete = commands.exists("delete");
206 
207                 Exporter exporter = new Exporter(config, database, delete);
208                 exporter.apply();
209 
210                 System.exit(0);
211             } catch (Exception exception) {
212                 exception.printStackTrace();
213                 System.exit(1);
214             }
215         }
216     }
217 
218     /***
219      * Initialise the target database.
220      *
221      * @param delete if <code>true</code>, indicates to delete data in the
222      *               proxy database, if it exists
223      * @throws PersistenceException for any persistence error
224      */
225     private void init(boolean delete) throws PersistenceException {
226         RDBMSTool tool;
227         try {
228             tool = new RDBMSTool(_dataSource.getConnection());
229         } catch (SQLException exception) {
230             throw new PersistenceException(exception);
231         }
232 
233         try {
234             Database schema = MigrationHelper.getSchema();
235             if (tool.hasTables(schema.getTable())) {
236                 if (delete) {
237                     tool.delete(schema);
238                 } else {
239                     throw new PersistenceException(
240                             "Cannot export data: migration database already "
241                             + "exists but delete not specified");
242                 }
243             } else {
244                 tool.create(schema);
245             }
246         } finally {
247             tool.close();
248         }
249     }
250 
251     /***
252      * Export data from a source store, and import it to a target store.
253      *
254      * @param source the source store
255      * @param target the target store
256      * @throws JMSException         for any JMS error
257      * @throws PersistenceException for any persistence error
258      */
259     private void apply(Store source, Store target)
260             throws JMSException, PersistenceException {
261 
262         StoreIterator iterator = source.exportCollection();
263         target.importCollection(iterator);
264     }
265 
266     /***
267      * Displays usage information for this tool when invoked from the command
268      * line
269      */
270     private static void usage() {
271         System.err.println(
272                 "usage: " + Exporter.class.getName()
273                 + " <arguments> [options]\n"
274                 + "arguments:\n"
275                 + "  -config <path>  specifies the path to an OpenJMS "
276                 + "configuration file\n"
277                 + "  -db <name>  specifies the path to export data to\n");
278     }
279 
280 }