Source Code Cross Referenced for MSSQLBackuper.java in  » Database-JDBC-Connection-Pool » sequoia-2.10.9 » org » continuent » sequoia » controller » backup » backupers » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database JDBC Connection Pool » sequoia 2.10.9 » org.continuent.sequoia.controller.backup.backupers 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /**
002:         * Sequoia: Database clustering technology.
003:         * Copyright (C) 2006 Continuent Inc.
004:         * Contact: sequoia@continuent.org
005:         * 
006:         * Licensed under the Apache License, Version 2.0 (the "License");
007:         * you may not use this file except in compliance with the License.
008:         * You may obtain a copy of the License at
009:         * 
010:         * http://www.apache.org/licenses/LICENSE-2.0
011:         * 
012:         * Unless required by applicable law or agreed to in writing, software
013:         * distributed under the License is distributed on an "AS IS" BASIS,
014:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015:         * See the License for the specific language governing permissions and
016:         * limitations under the License. 
017:         *
018:         * Initial developer(s): Adam Fletcher, Mykola Paliyenko.
019:         * Contributor(s): Emmanuel Cecchet, Stephane Giron
020:         */package org.continuent.sequoia.controller.backup.backupers;
021:
022:        import java.io.File;
023:        import java.io.IOException;
024:        import java.io.InputStream;
025:        import java.sql.Connection;
026:        import java.sql.DriverManager;
027:        import java.sql.Statement;
028:        import java.util.ArrayList;
029:        import java.util.Date;
030:        import java.util.HashMap;
031:        import java.util.Iterator;
032:        import java.util.StringTokenizer;
033:        import java.util.regex.Matcher;
034:        import java.util.regex.Pattern;
035:
036:        import org.continuent.sequoia.common.exceptions.BackupException;
037:        import org.continuent.sequoia.common.log.Trace;
038:        import org.continuent.sequoia.controller.backend.DatabaseBackend;
039:        import org.continuent.sequoia.controller.backup.BackupManager;
040:        import org.continuent.sequoia.controller.backup.Backuper;
041:        import org.continuent.sequoia.controller.backup.DumpTransferInfo;
042:
043:        /**
044:         * MSSQL backuper inspired from the PostgreSQL backuper. <br>
045:         * This backuper takes the following options: <br>
046:         * urlHeader: expected URL header for the backend. Default is
047:         * "jdbc:jtds:sqlserver:" <br>
048:         * driverClassName: driver class name to load. Default is the driver class
049:         * defined for the targeted backend. If you need to use a specific driver for
050:         * backup/restore operation, you can force it here.
051:         * <p>
052:         * To use it, edit the virtual database config's <Backup> node:
053:         * 
054:         * <pre>
055:         * <Backup>
056:         *   <Backuper backuperName="MSSQLServer" className="org.continuent.sequoia.controller.backup.backupers.MSSQLBackuper" options=""/>
057:         *   <Backuper backuperName="MSSQLServerWithjTDSDriver" className="org.continuent.sequoia.controller.backup.backupers.MSSQLBackuper" options="urlHeader=jdbc:jtds:sqlserver:,driverClassName=net.sourceforge.jtds.jdbc.Driver"/>
058:         *   <Backuper backuperName="MSSQLServerWithMSDriver" className="org.continuent.sequoia.controller.backup.backupers.MSSQLBackuper" options="urlHeader=jdbc:microsoft:sqlserver:,driverClassName=com.microsoft.jdbc.sqlserver.SQLServerDriver"/>
059:         * </Backup>
060:         *</pre>
061:         * 
062:         * Then in the console to take the backups:<br>
063:         * backup mybackend database.dump MSSQLServer \\<fileserver>\<share>
064:         * 
065:         * @author <a href="mailto:adamf@powersteeringsoftware.com">Adam Fletcher</a>
066:         * @author <a href="mailto:mpaliyenko@gmail.com">Mykola Paliyenko</a>
067:         * @author <a href="mailto:emmanuel.cecchet@continuent.com">Emmanuel Cecchet</a>
068:         * @author <a href="mailto:stephane.giron@continuent.com">Stephane Giron</a>
069:         */
070:        public class MSSQLBackuper implements  Backuper {
071:            protected HashMap optionsMap = new HashMap();
072:            protected String optionsString = null;
073:
074:            private static final String DEFAULT_MSSQL_PORT = "1433";
075:            private static final String DEFAULT_MSSQL_HOST = "localhost";
076:            private static final String DEFAULT_JDBC_URL = "jdbc:jtds:sqlserver:";
077:
078:            private static final Object URL_OPTION = "urlHeader";
079:            private static final Object DRIVER_CLASS_NAME_OPTION = "driverClassName";
080:
081:            static Trace logger = Trace
082:                    .getLogger(MSSQLBackuper.class.getName());
083:
084:            private ArrayList errors;
085:
086:            /**
087:             * Creates a new <code>MSSQLBackuper</code> object
088:             */
089:            public MSSQLBackuper() {
090:                errors = new ArrayList();
091:            }
092:
093:            /**
094:             * @see org.continuent.sequoia.controller.backup.Backuper#getDumpFormat()
095:             */
096:            public String getDumpFormat() {
097:                return "MSSQL raw dump";
098:            }
099:
100:            /**
101:             * @see Backuper#getOptions()
102:             */
103:            public String getOptions() {
104:                return optionsString;
105:            }
106:
107:            /**
108:             * @see Backuper#setOptions(java.lang.String)
109:             */
110:            public void setOptions(String options) {
111:                if (options != null) {
112:                    StringTokenizer strTok = new StringTokenizer(options, ",");
113:                    String option = null;
114:                    String name = null;
115:                    String value = null;
116:
117:                    // Parse the string of options, add them to the HashMap
118:                    while (strTok.hasMoreTokens()) {
119:                        option = strTok.nextToken();
120:                        name = option.substring(0, option.indexOf("="));
121:                        value = option.substring(option.indexOf("=") + 1,
122:                                option.length());
123:                        optionsMap.put(name, value);
124:                    }
125:
126:                    optionsString = options;
127:                }
128:            }
129:
130:            /**
131:             * @see org.continuent.sequoia.controller.backup.Backuper#backup(org.continuent.sequoia.controller.backend.DatabaseBackend,
132:             *      java.lang.String, java.lang.String, java.lang.String,
133:             *      java.lang.String, java.util.ArrayList)
134:             */
135:            public Date backup(DatabaseBackend backend, String login,
136:                    String password, String dumpName, String path,
137:                    ArrayList tables) throws BackupException {
138:                String url = backend.getURL();
139:
140:                String expectedUrl = (String) optionsMap.get(URL_OPTION);
141:                if (expectedUrl == null)
142:                    expectedUrl = DEFAULT_JDBC_URL;
143:
144:                if (!url.startsWith(expectedUrl)) {
145:                    throw new BackupException("Unsupported db url " + url);
146:                }
147:                MSSQLUrlInfo info = new MSSQLUrlInfo(url);
148:                Connection con;
149:
150:                try {
151:                    String driverClassName = (String) optionsMap
152:                            .get(DRIVER_CLASS_NAME_OPTION);
153:                    if (driverClassName == null)
154:                        driverClassName = backend.getDriverClassName();
155:
156:                    // Load the driver and connect to the database
157:                    Class.forName(driverClassName);
158:                    con = DriverManager.getConnection(url + ";user=" + login
159:                            + ";password=" + password);
160:                } catch (Exception e) {
161:                    String msg = "Error while performing backup during creation of connection";
162:                    logger.error(msg, e);
163:                    throw new BackupException(msg, e);
164:                }
165:
166:                try {
167:                    File pathDir = new File(path);
168:                    if (!pathDir.exists()) {
169:                        pathDir.mkdirs();
170:                        pathDir.mkdir();
171:                    }
172:
173:                    /*
174:                     * What should be done here: 1) verify the path is a UNC path 2) connect
175:                     * to the server via JDBC 3) issue the 'BACKUP <dbname> TO DISK='<path>'
176:                     * <path> must be UNC connect to the configured backend with JDBC
177:                     */
178:                    // String dumpPath = path + File.separator + dumpName;
179:                    // we don't use File.seperator here because we are using UNC paths
180:                    String dumpPath = path + "\\" + dumpName;
181:
182:                    if (logger.isDebugEnabled()) {
183:                        logger.debug("Dumping " + backend.getURL() + " in "
184:                                + dumpPath);
185:                    }
186:
187:                    Statement stmt = con.createStatement();
188:                    String sqlStatement = "BACKUP DATABASE " + info.getDbName()
189:                            + " TO DISK = '" + dumpPath + "'";
190:
191:                    logger.debug("sql statement for backup: " + sqlStatement);
192:
193:                    boolean backupResult = stmt.execute(sqlStatement);
194:
195:                    if (backupResult) {
196:                        String msg = "BACKUP returned false";
197:                        logger.error(msg);
198:                        throw new BackupException(msg);
199:                    }
200:                } catch (Exception e) {
201:                    String msg = "Error while performing backup";
202:                    logger.error(msg, e);
203:                    throw new BackupException(msg, e);
204:                } finally {
205:                    try {
206:                        con.close();
207:                    } catch (Exception e) {
208:                        String msg = "Error while performing backup during close connection";
209:                        logger.error(msg, e);
210:                        throw new BackupException(msg, e);
211:                    }
212:                }
213:                return new Date();
214:            }
215:
216:            /**
217:             * @see org.continuent.sequoia.controller.backup.Backuper#restore(org.continuent.sequoia.controller.backend.DatabaseBackend,
218:             *      java.lang.String, java.lang.String, java.lang.String,
219:             *      java.lang.String, java.util.ArrayList)
220:             */
221:            public void restore(DatabaseBackend backend, String login,
222:                    String password, String dumpName, String path,
223:                    ArrayList tables) throws BackupException {
224:                String url = backend.getURL();
225:
226:                String expectedUrl = (String) optionsMap.get(URL_OPTION);
227:
228:                if (expectedUrl == null)
229:                    expectedUrl = DEFAULT_JDBC_URL;
230:
231:                if (!url.startsWith(expectedUrl)) {
232:                    throw new BackupException("Unsupported db url " + url);
233:                }
234:
235:                MSSQLUrlInfo info = new MSSQLUrlInfo(url);
236:                Connection con;
237:                try {
238:                    String driverClassName = (String) optionsMap
239:                            .get(DRIVER_CLASS_NAME_OPTION);
240:                    if (driverClassName == null)
241:                        driverClassName = backend.getDriverClassName();
242:
243:                    // Load the driver and connect to the database
244:                    Class.forName(driverClassName);
245:
246:                    // NOTE: you have to connect to the master database to restore,
247:                    // because if you connect to the current DB you are USING the db
248:                    // and therefore LOCKING the db.
249:
250:                    con = DriverManager
251:                            .getConnection(expectedUrl + "//" + info.getHost()
252:                                    + ":" + info.getPort() + "/master;user="
253:                                    + login + ";password=" + password);
254:                } catch (Exception e) {
255:                    String msg = "Error while performing restore during creation of connection";
256:                    logger.error(msg, e);
257:                    throw new BackupException(msg, e);
258:                }
259:
260:                try {
261:                    File pathDir = new File(path);
262:                    if (!pathDir.exists()) {
263:                        pathDir.mkdirs();
264:                        pathDir.mkdir();
265:                    }
266:                    String dumpPath = path + File.separator + dumpName;
267:                    if (logger.isDebugEnabled()) {
268:                        logger.debug("Restoring " + backend.getURL() + " from "
269:                                + dumpPath);
270:                    }
271:
272:                    Statement stmt = con.createStatement();
273:
274:                    String sqlAtatement = "RESTORE DATABASE "
275:                            + info.getDbName() + " FROM DISK = '" + dumpPath
276:                            + "'";
277:
278:                    boolean backupResult = stmt.execute(sqlAtatement);
279:
280:                    if (backupResult) {
281:                        String msg = "restore returned false";
282:                        logger.error(msg);
283:                        throw new BackupException(msg);
284:                    }
285:                } catch (Exception e) {
286:                    String msg = "Error while performing restore";
287:                    logger.error(msg, e);
288:                    throw new BackupException(msg, e);
289:                } finally {
290:                    try {
291:                        con.close();
292:                    } catch (Exception e) {
293:                        String msg = "Error while performing restore during close connection";
294:                        logger.error(msg, e);
295:                        throw new BackupException(msg, e);
296:                    }
297:                }
298:            }
299:
300:            String getProcessOutput(Process process) throws IOException {
301:                StringBuffer sb = new StringBuffer();
302:
303:                InputStream pis = process.getInputStream();
304:                InputStream pes = process.getErrorStream();
305:
306:                int c = pis.read();
307:                while (c != -1) {
308:                    sb.append(new Character((char) c));
309:                    c = pis.read();
310:                }
311:                c = pes.read();
312:                while (c != -1) {
313:                    sb.append(new Character((char) c));
314:                    c = pes.read();
315:                }
316:
317:                return sb.toString();
318:            }
319:
320:            /**
321:             * @see org.continuent.sequoia.controller.backup.Backuper#deleteDump(java.lang.String,
322:             *      java.lang.String)
323:             */
324:            public void deleteDump(String path, String dumpName)
325:                    throws BackupException {
326:                File toRemove = new File(getDumpPhysicalPath(path, dumpName));
327:                if (logger.isDebugEnabled())
328:                    logger.debug("Deleting compressed dump " + toRemove);
329:                toRemove.delete();
330:            }
331:
332:            /**
333:             * Get the dump physical path from its logical name
334:             * 
335:             * @param path the path where the dump is stored
336:             * @param dumpName dump logical name
337:             * @return path to zip file
338:             */
339:            private String getDumpPhysicalPath(String path, String dumpName) {
340:                return path + File.separator + dumpName;
341:            }
342:
343:            /**
344:             * @see org.continuent.sequoia.controller.backup.Backuper#fetchDump(org.continuent.sequoia.controller.backup.DumpTransferInfo,
345:             *      java.lang.String, java.lang.String)
346:             */
347:            public void fetchDump(DumpTransferInfo dumpTransferInfo,
348:                    String path, String dumpName) throws BackupException,
349:                    IOException {
350:                BackupManager.fetchDumpFile(dumpTransferInfo, path, dumpName);
351:            }
352:
353:            /**
354:             * @see org.continuent.sequoia.controller.backup.Backuper#setupDumpServer()
355:             */
356:            public DumpTransferInfo setupDumpServer() throws IOException {
357:                return BackupManager.setupDumpFileServer();
358:            }
359:
360:            /**
361:             * Allow to parse PostgreSQL URL.
362:             */
363:            protected class MSSQLUrlInfo {
364:                private boolean isLocal;
365:
366:                private String host;
367:
368:                private String port;
369:
370:                private String dbName;
371:
372:                /**
373:                 * Creates a new <code>MSSQLUrlInfo</code> object, used to parse the MSSQL
374:                 * JDBC options. If host and/or port aren't specified, will default to
375:                 * localhost:1433. Note that database name must be specified.
376:                 * 
377:                 * @param url the MSSQL JDBC url to parse
378:                 */
379:                public MSSQLUrlInfo(String url) {
380:                    String expectedUrl = (String) optionsMap.get(URL_OPTION);
381:
382:                    if (expectedUrl == null)
383:                        expectedUrl = DEFAULT_JDBC_URL;
384:
385:                    // Used to parse url
386:                    Pattern pattern = Pattern
387:                            .compile(expectedUrl
388:                                    + "((//([a-zA-Z0-9_\\-.]+|\\[[a-fA-F0-9:]+])((:(\\d+))|))/|)([a-zA-Z][a-zA-Z0-9_\\-]*)(\\?.*)?");
389:
390:                    Matcher matcher;
391:
392:                    matcher = pattern.matcher(url);
393:
394:                    if (matcher.matches()) {
395:                        if (matcher.group(3) != null)
396:                            host = matcher.group(3);
397:                        else
398:                            host = DEFAULT_MSSQL_HOST;
399:
400:                        if (matcher.group(6) != null)
401:                            port = matcher.group(6);
402:                        else
403:                            port = DEFAULT_MSSQL_PORT;
404:
405:                        dbName = matcher.group(7);
406:                    }
407:                }
408:
409:                /**
410:                 * Gets the HostParameters of this postgresql jdbc url as a String that can
411:                 * be used to pass into cmd line/shell calls.
412:                 * 
413:                 * @return a string that can be used to pass into a cmd line/shell call.
414:                 */
415:                public String getHostParametersString() {
416:                    logger.debug("getHostParamertsString host: " + host
417:                            + " port: " + port);
418:
419:                    if (isLocal) {
420:                        return "//localhost";
421:                    } else {
422:                        return "//" + host + ":" + port;
423:                    }
424:                }
425:
426:                /**
427:                 * Gets the database name part of this postgresql jdbc url.
428:                 * 
429:                 * @return the database name part of this postgresql jdbc url.
430:                 */
431:                public String getDbName() {
432:                    return dbName;
433:                }
434:
435:                /**
436:                 * Gets the host part of this postgresql jdbc url.
437:                 * 
438:                 * @return the host part of this postgresql jdbc url.
439:                 */
440:                public String getHost() {
441:                    return host;
442:                }
443:
444:                /**
445:                 * Gets the port part of this postgresql jdbc url.
446:                 * 
447:                 * @return the port part of this postgresql jdbc url.
448:                 */
449:                public String getPort() {
450:                    return port;
451:                }
452:
453:                /**
454:                 * Checks whether this postgresql jdbc url refers to a local db or not, i.e.
455:                 * has no host specified, e.g. jdbc:postgresql:myDb.
456:                 * 
457:                 * @return true if this postgresql jdbc url has no host specified, i.e.
458:                 *         refers to a local db.
459:                 */
460:                public boolean isLocal() {
461:                    return isLocal;
462:                }
463:
464:            }
465:
466:            protected void printErrors() {
467:                Iterator it = errors.iterator();
468:                while (it.hasNext()) {
469:                    logger.info(it.next());
470:                }
471:            }
472:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.