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.Validator;
025    import com.liferay.portal.upgrade.v7_0_0.util.ClassNameTable;
026    import com.liferay.portal.upgrade.v7_0_0.util.ClusterGroupTable;
027    import com.liferay.portal.upgrade.v7_0_0.util.CounterTable;
028    import com.liferay.portal.upgrade.v7_0_0.util.CountryTable;
029    import com.liferay.portal.upgrade.v7_0_0.util.PortalPreferencesTable;
030    import com.liferay.portal.upgrade.v7_0_0.util.RegionTable;
031    import com.liferay.portal.upgrade.v7_0_0.util.ReleaseTable;
032    import com.liferay.portal.upgrade.v7_0_0.util.ResourceActionTable;
033    import com.liferay.portal.upgrade.v7_0_0.util.ServiceComponentTable;
034    import com.liferay.portal.upgrade.v7_0_0.util.VirtualHostTable;
035    import com.liferay.portal.util.PropsUtil;
036    
037    import java.sql.Connection;
038    import java.sql.PreparedStatement;
039    import java.sql.ResultSet;
040    
041    import java.util.ArrayList;
042    import java.util.List;
043    
044    import javax.sql.DataSource;
045    
046    /**
047     * @author Manuel de la Pe??a
048     */
049    public class UpgradeSharding extends UpgradeProcess {
050    
051            protected void copyControlTable(
052                            Connection sourceConnection, Connection targetConnection,
053                            String tableName, Object[][] columns, String createSQL)
054                    throws Exception {
055    
056                    UpgradeTable upgradeTable = UpgradeTableFactoryUtil.getUpgradeTable(
057                            tableName, columns);
058    
059                    upgradeTable.setCreateSQL(createSQL);
060    
061                    upgradeTable.copyTable(sourceConnection, targetConnection);
062            }
063    
064            protected void copyControlTables(List<String> shardNames) throws Exception {
065                    String defaultShardName = PropsUtil.get("shard.default.name");
066    
067                    if (Validator.isNull(defaultShardName)) {
068                            throw new RuntimeException(
069                                    "The property \"shard.default.name\" is not set in " +
070                                            "portal.properties");
071                    }
072    
073                    for (String shardName : shardNames) {
074                            if (!shardName.equals(defaultShardName)) {
075                                    copyControlTables(shardName);
076                            }
077                    }
078            }
079    
080            protected void copyControlTables(String shardName) throws Exception {
081                    Connection sourceConnection =
082                            DataAccess.getUpgradeOptimizedConnection();
083    
084                    DataSourceFactoryBean dataSourceFactoryBean =
085                            new DataSourceFactoryBean();
086    
087                    dataSourceFactoryBean.setPropertyPrefix("jdbc." + shardName + ".");
088    
089                    DataSource dataSource = dataSourceFactoryBean.createInstance();
090    
091                    Connection targetConnection = dataSource.getConnection();
092    
093                    try {
094                            copyControlTable(
095                                    sourceConnection, targetConnection, ClassNameTable.TABLE_NAME,
096                                    ClassNameTable.TABLE_COLUMNS, ClassNameTable.TABLE_SQL_CREATE);
097                            copyControlTable(
098                                    sourceConnection, targetConnection,
099                                    ClusterGroupTable.TABLE_NAME, ClusterGroupTable.TABLE_COLUMNS,
100                                    ClusterGroupTable.TABLE_SQL_CREATE);
101                            copyControlTable(
102                                    sourceConnection, targetConnection, CounterTable.TABLE_NAME,
103                                    CounterTable.TABLE_COLUMNS, CounterTable.TABLE_SQL_CREATE);
104                            copyControlTable(
105                                    sourceConnection, targetConnection, CountryTable.TABLE_NAME,
106                                    CountryTable.TABLE_COLUMNS, CountryTable.TABLE_SQL_CREATE);
107                            copyControlTable(
108                                    sourceConnection, targetConnection,
109                                    PortalPreferencesTable.TABLE_NAME,
110                                    PortalPreferencesTable.TABLE_COLUMNS,
111                                    PortalPreferencesTable.TABLE_SQL_CREATE);
112                            copyControlTable(
113                                    sourceConnection, targetConnection, RegionTable.TABLE_NAME,
114                                    RegionTable.TABLE_COLUMNS, RegionTable.TABLE_SQL_CREATE);
115                            copyControlTable(
116                                    sourceConnection, targetConnection, ReleaseTable.TABLE_NAME,
117                                    ReleaseTable.TABLE_COLUMNS, ReleaseTable.TABLE_SQL_CREATE);
118                            copyControlTable(
119                                    sourceConnection, targetConnection,
120                                    ResourceActionTable.TABLE_NAME,
121                                    ResourceActionTable.TABLE_COLUMNS,
122                                    ResourceActionTable.TABLE_SQL_CREATE);
123                            copyControlTable(
124                                    sourceConnection, targetConnection,
125                                    ServiceComponentTable.TABLE_NAME,
126                                    ServiceComponentTable.TABLE_COLUMNS,
127                                    ServiceComponentTable.TABLE_SQL_CREATE);
128                            copyControlTable(
129                                    sourceConnection, targetConnection, VirtualHostTable.TABLE_NAME,
130                                    VirtualHostTable.TABLE_COLUMNS,
131                                    VirtualHostTable.TABLE_SQL_CREATE);
132                    }
133                    catch (Exception e) {
134                            _log.error("Unable to copy control tables", e);
135                    }
136                    finally {
137                            DataAccess.cleanUp(sourceConnection);
138    
139                            DataAccess.cleanUp(targetConnection);
140                    }
141            }
142    
143            @Override
144            protected void doUpgrade() throws Exception {
145                    List<String> shardNames = getShardNames();
146    
147                    if (shardNames.size() <= 1) {
148                            return;
149                    }
150    
151                    copyControlTables(shardNames);
152            }
153    
154            protected List<String> getShardNames() throws Exception {
155                    Connection con = null;
156                    PreparedStatement ps = null;
157                    ResultSet rs = null;
158    
159                    List<String> shardNames = new ArrayList<>();
160    
161                    try {
162                            con = DataAccess.getUpgradeOptimizedConnection();
163    
164                            ps = con.prepareStatement("select name from Shard");
165    
166                            rs = ps.executeQuery();
167    
168                            while (rs.next()) {
169                                    shardNames.add(rs.getString("name"));
170                            }
171                    }
172                    finally {
173                            DataAccess.cleanUp(con, ps, rs);
174                    }
175    
176                    return shardNames;
177            }
178    
179            private static final Log _log = LogFactoryUtil.getLog(
180                    UpgradeSharding.class);
181    
182    }