001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.upgrade.v7_0_0;
016    
017    import com.liferay.portal.dao.jdbc.spring.DataSourceFactoryBean;
018    import com.liferay.portal.kernel.dao.jdbc.DataAccess;
019    import com.liferay.portal.kernel.log.Log;
020    import com.liferay.portal.kernel.log.LogFactoryUtil;
021    import com.liferay.portal.kernel.upgrade.UpgradeProcess;
022    import com.liferay.portal.kernel.upgrade.util.UpgradeTable;
023    import com.liferay.portal.kernel.upgrade.util.UpgradeTableFactoryUtil;
024    import com.liferay.portal.kernel.util.StringUtil;
025    import com.liferay.portal.kernel.util.Validator;
026    import com.liferay.portal.upgrade.v7_0_0.util.ClassNameTable;
027    import com.liferay.portal.upgrade.v7_0_0.util.ClusterGroupTable;
028    import com.liferay.portal.upgrade.v7_0_0.util.CounterTable;
029    import com.liferay.portal.upgrade.v7_0_0.util.CountryTable;
030    import com.liferay.portal.upgrade.v7_0_0.util.PortalPreferencesTable;
031    import com.liferay.portal.upgrade.v7_0_0.util.RegionTable;
032    import com.liferay.portal.upgrade.v7_0_0.util.ReleaseTable;
033    import com.liferay.portal.upgrade.v7_0_0.util.ResourceActionTable;
034    import com.liferay.portal.upgrade.v7_0_0.util.ServiceComponentTable;
035    import com.liferay.portal.upgrade.v7_0_0.util.VirtualHostTable;
036    import com.liferay.portal.util.PropsUtil;
037    
038    import java.sql.Connection;
039    import java.sql.PreparedStatement;
040    import java.sql.ResultSet;
041    
042    import java.util.ArrayList;
043    import java.util.List;
044    
045    import javax.sql.DataSource;
046    
047    /**
048     * @author Manuel de la Pe??a
049     */
050    public class UpgradeSharding extends UpgradeProcess {
051    
052            protected void copyControlTable(
053                            Connection sourceConnection, Connection targetConnection,
054                            String tableName, Object[][] columns, String createSQL)
055                    throws Exception {
056    
057                    UpgradeTable upgradeTable = UpgradeTableFactoryUtil.getUpgradeTable(
058                            tableName, columns);
059    
060                    upgradeTable.setCreateSQL(createSQL);
061    
062                    upgradeTable.copyTable(sourceConnection, targetConnection);
063            }
064    
065            protected void copyControlTables(List<String> shardNames) throws Exception {
066                    String defaultShardName = PropsUtil.get("shard.default.name");
067    
068                    if (Validator.isNull(defaultShardName)) {
069                            throw new RuntimeException(
070                                    "The property \"shard.default.name\" is not set in " +
071                                            "portal.properties. Please specify a default shard name " +
072                                                    "from: " + StringUtil.merge(shardNames, ", ") + ".");
073                    }
074    
075                    for (String shardName : shardNames) {
076                            if (!shardName.equals(defaultShardName)) {
077                                    copyControlTables(shardName);
078                            }
079                    }
080            }
081    
082            protected void copyControlTables(String shardName) throws Exception {
083                    Connection sourceConnection =
084                            DataAccess.getUpgradeOptimizedConnection();
085    
086                    DataSourceFactoryBean dataSourceFactoryBean =
087                            new DataSourceFactoryBean();
088    
089                    dataSourceFactoryBean.setPropertyPrefix("jdbc." + shardName + ".");
090    
091                    DataSource dataSource = dataSourceFactoryBean.createInstance();
092    
093                    Connection targetConnection = dataSource.getConnection();
094    
095                    try {
096                            copyControlTable(
097                                    sourceConnection, targetConnection, ClassNameTable.TABLE_NAME,
098                                    ClassNameTable.TABLE_COLUMNS, ClassNameTable.TABLE_SQL_CREATE);
099                            copyControlTable(
100                                    sourceConnection, targetConnection,
101                                    ClusterGroupTable.TABLE_NAME, ClusterGroupTable.TABLE_COLUMNS,
102                                    ClusterGroupTable.TABLE_SQL_CREATE);
103                            copyControlTable(
104                                    sourceConnection, targetConnection, CounterTable.TABLE_NAME,
105                                    CounterTable.TABLE_COLUMNS, CounterTable.TABLE_SQL_CREATE);
106                            copyControlTable(
107                                    sourceConnection, targetConnection, CountryTable.TABLE_NAME,
108                                    CountryTable.TABLE_COLUMNS, CountryTable.TABLE_SQL_CREATE);
109                            copyControlTable(
110                                    sourceConnection, targetConnection,
111                                    PortalPreferencesTable.TABLE_NAME,
112                                    PortalPreferencesTable.TABLE_COLUMNS,
113                                    PortalPreferencesTable.TABLE_SQL_CREATE);
114                            copyControlTable(
115                                    sourceConnection, targetConnection, RegionTable.TABLE_NAME,
116                                    RegionTable.TABLE_COLUMNS, RegionTable.TABLE_SQL_CREATE);
117                            copyControlTable(
118                                    sourceConnection, targetConnection, ReleaseTable.TABLE_NAME,
119                                    ReleaseTable.TABLE_COLUMNS, ReleaseTable.TABLE_SQL_CREATE);
120                            copyControlTable(
121                                    sourceConnection, targetConnection,
122                                    ResourceActionTable.TABLE_NAME,
123                                    ResourceActionTable.TABLE_COLUMNS,
124                                    ResourceActionTable.TABLE_SQL_CREATE);
125                            copyControlTable(
126                                    sourceConnection, targetConnection,
127                                    ServiceComponentTable.TABLE_NAME,
128                                    ServiceComponentTable.TABLE_COLUMNS,
129                                    ServiceComponentTable.TABLE_SQL_CREATE);
130                            copyControlTable(
131                                    sourceConnection, targetConnection, VirtualHostTable.TABLE_NAME,
132                                    VirtualHostTable.TABLE_COLUMNS,
133                                    VirtualHostTable.TABLE_SQL_CREATE);
134                    }
135                    catch (Exception e) {
136                            _log.error("Unable to copy control tables", e);
137                    }
138                    finally {
139                            DataAccess.cleanUp(sourceConnection);
140    
141                            DataAccess.cleanUp(targetConnection);
142                    }
143            }
144    
145            @Override
146            protected void doUpgrade() throws Exception {
147                    List<String> shardNames = getShardNames();
148    
149                    if (shardNames.size() <= 1) {
150                            return;
151                    }
152    
153                    copyControlTables(shardNames);
154            }
155    
156            protected List<String> getShardNames() throws Exception {
157                    PreparedStatement ps = null;
158                    ResultSet rs = null;
159    
160                    List<String> shardNames = new ArrayList<>();
161    
162                    try {
163                            ps = connection.prepareStatement("select name from Shard");
164    
165                            rs = ps.executeQuery();
166    
167                            while (rs.next()) {
168                                    shardNames.add(rs.getString("name"));
169                            }
170                    }
171                    finally {
172                            DataAccess.cleanUp(ps, rs);
173                    }
174    
175                    return shardNames;
176            }
177    
178            private static final Log _log = LogFactoryUtil.getLog(
179                    UpgradeSharding.class);
180    
181    }