ConfigurationService.java 8.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/*
 * Copyright 1999-2015 dangdang.com.
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * </p>
 */

package io.shardingjdbc.orchestration.internal.config;

H
haocao 已提交
20
import com.google.common.base.Strings;
21 22
import io.shardingjdbc.core.api.config.MasterSlaveRuleConfiguration;
import io.shardingjdbc.core.api.config.ShardingRuleConfiguration;
23
import io.shardingjdbc.core.jdbc.core.datasource.MasterSlaveDataSource;
24
import io.shardingjdbc.core.jdbc.core.datasource.ShardingDataSource;
25
import io.shardingjdbc.orchestration.api.config.OrchestrationMasterSlaveConfiguration;
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
import io.shardingjdbc.orchestration.api.config.OrchestrationShardingConfiguration;
import io.shardingjdbc.orchestration.internal.json.DataSourceJsonConverter;
import io.shardingjdbc.orchestration.internal.json.GsonFactory;
import io.shardingjdbc.orchestration.internal.json.ShardingRuleConfigurationConverter;
import io.shardingjdbc.orchestration.internal.storage.DataNodeStorage;
import io.shardingjdbc.orchestration.reg.base.CoordinatorRegistryCenter;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.cache.ChildData;
import org.apache.curator.framework.recipes.cache.TreeCache;
import org.apache.curator.framework.recipes.cache.TreeCacheEvent;
import org.apache.curator.framework.recipes.cache.TreeCacheListener;

import javax.sql.DataSource;
import java.util.Map;
import java.util.Properties;

/**
T
terrymanu 已提交
43
 * configuration service.
44 45 46 47 48 49 50
 * 
 * @author caohao
 */
public final class ConfigurationService {
    
    private final DataNodeStorage dataNodeStorage;
    
T
terrymanu 已提交
51 52
    public ConfigurationService(final String name, final CoordinatorRegistryCenter regCenter) {
        dataNodeStorage = new DataNodeStorage(name, regCenter);
53 54
    }
    
H
haocao 已提交
55 56 57 58 59 60
    /**
     * Persist sharding configuration.
     *
     * @param config orchestration sharding configuration
     * @param props sharding properties
     */
T
terrymanu 已提交
61
    public void persistShardingConfiguration(final OrchestrationShardingConfiguration config, final Properties props) {
62
        persistShardingRuleConfiguration(config.getShardingRuleConfig(), config.isOverwrite());
H
haocao 已提交
63
        persistShardingProperties(props, config.isOverwrite());
H
haocao 已提交
64
        persistDataSourceConfiguration(config.getDataSourceMap(), config.isOverwrite());
65 66
    }
    
H
haocao 已提交
67 68 69 70 71 72 73 74 75 76 77 78
    /**
     * Add sharding configuration change listener.
     *
     * @param name configuration name 
     * @param registryCenter registry center
     * @param shardingDataSource sharding datasource
     */
    public void addShardingConfigurationChangeListener(final String name, final CoordinatorRegistryCenter registryCenter, final ShardingDataSource shardingDataSource) {
        addShardingConfigurationNodeChangeListener(name, ConfigurationNode.DATA_SOURCE_NODE_PATH, registryCenter, shardingDataSource);
        addShardingConfigurationNodeChangeListener(name, ConfigurationNode.MASTER_SLAVE_NODE_PATH, registryCenter, shardingDataSource);
        addShardingConfigurationNodeChangeListener(name, ConfigurationNode.SHARDING_NODE_PATH, registryCenter, shardingDataSource);
        addShardingConfigurationNodeChangeListener(name, ConfigurationNode.PROPS_NODE_PATH, registryCenter, shardingDataSource);
79 80
    }
    
H
haocao 已提交
81 82
    private void addShardingConfigurationNodeChangeListener(final String name, final String node, final CoordinatorRegistryCenter registryCenter, final ShardingDataSource shardingDataSource) {
        String cachePath = "/" + name + "/" + node;
83 84 85 86 87 88 89 90 91 92 93 94 95 96
        registryCenter.addCacheData(cachePath);
        TreeCache cache = (TreeCache) registryCenter.getRawCache(cachePath);
        cache.getListenable().addListener(new TreeCacheListener() {
            
            @Override
            public void childEvent(final CuratorFramework client, final TreeCacheEvent event) throws Exception {
                ChildData childData = event.getData();
                if (null == childData || null == childData.getData()) {
                    return;
                }
                String path = childData.getPath();
                if (path.isEmpty()) {
                    return;
                }
H
haocao 已提交
97
                shardingDataSource.renew(loadShardingRuleConfiguration().build(loadDataSourceMap()), loadShardingProperties());
98 99 100 101
            }
        });
    }
    
T
terrymanu 已提交
102
    public void addMasterSlaveConfiguration(final OrchestrationMasterSlaveConfiguration config, final MasterSlaveDataSource masterSlaveDataSource) {
H
haocao 已提交
103 104
        persistMasterSlaveConfiguration(config);
        addMasterSlaveConfigurationChangeListener(config.getName(), config.getRegistryCenter(), masterSlaveDataSource);
H
haocao 已提交
105 106
    }
    
T
terrymanu 已提交
107
    private void persistMasterSlaveConfiguration(final OrchestrationMasterSlaveConfiguration config) {
H
haocao 已提交
108 109 110 111 112 113
        persistMasterSlaveRuleConfiguration(config.getMasterSlaveRuleConfiguration(), config.isOverwrite());
        persistDataSourceConfiguration(config.getDataSourceMap(), config.isOverwrite());
    }
    
    private void addMasterSlaveConfigurationChangeListener(final String name, final CoordinatorRegistryCenter registryCenter, final MasterSlaveDataSource masterSlaveDataSource) {
        String cachePath = "/" + name + "/" + ConfigurationNode.ROOT;
114 115 116 117 118 119 120 121 122 123 124 125 126 127
        registryCenter.addCacheData(cachePath);
        TreeCache cache = (TreeCache) registryCenter.getRawCache(cachePath);
        cache.getListenable().addListener(new TreeCacheListener() {
            
            @Override
            public void childEvent(final CuratorFramework client, final TreeCacheEvent event) throws Exception {
                ChildData childData = event.getData();
                if (null == childData || null == childData.getData()) {
                    return;
                }
                String path = childData.getPath();
                if (path.isEmpty()) {
                    return;
                }
H
haocao 已提交
128
                masterSlaveDataSource.renew(loadMasterSlaveRuleConfiguration().build(loadDataSourceMap()));
129 130 131 132
            }
        });
    }
    
H
haocao 已提交
133
    private Properties loadShardingProperties() {
H
haocao 已提交
134 135 136 137
        String data = dataNodeStorage.getNodeData(ConfigurationNode.PROPS_NODE_PATH);
        return Strings.isNullOrEmpty(data) ? new Properties() : GsonFactory.getGson().fromJson(data, Properties.class);
    }
    
H
haocao 已提交
138
    private ShardingRuleConfiguration loadShardingRuleConfiguration() {
139 140 141
        return ShardingRuleConfigurationConverter.fromJson(dataNodeStorage.getNodeData(ConfigurationNode.SHARDING_NODE_PATH));
    }
    
H
haocao 已提交
142
    private MasterSlaveRuleConfiguration loadMasterSlaveRuleConfiguration() {
143 144 145
        return GsonFactory.getGson().fromJson(dataNodeStorage.getNodeData(ConfigurationNode.MASTER_SLAVE_NODE_PATH), MasterSlaveRuleConfiguration.class);
    }
    
H
haocao 已提交
146
    private Map<String, DataSource> loadDataSourceMap() {
147 148 149
        return DataSourceJsonConverter.fromJson(dataNodeStorage.getNodeData(ConfigurationNode.DATA_SOURCE_NODE_PATH));
    }
    
H
haocao 已提交
150
    private void persistShardingRuleConfiguration(final ShardingRuleConfiguration config, final boolean isOverwrite) {
151 152 153
        if (!dataNodeStorage.isNodeExisted(ConfigurationNode.SHARDING_NODE_PATH) || isOverwrite) {
            dataNodeStorage.fillNode(ConfigurationNode.SHARDING_NODE_PATH, ShardingRuleConfigurationConverter.toJson(config));
        }
H
haocao 已提交
154 155
    }
    
H
haocao 已提交
156
    private void persistShardingProperties(final Properties props, final boolean isOverwrite) {
H
haocao 已提交
157 158 159
        if (!dataNodeStorage.isNodeExisted(ConfigurationNode.PROPS_NODE_PATH) || isOverwrite) {
            dataNodeStorage.fillNode(ConfigurationNode.PROPS_NODE_PATH, GsonFactory.getGson().toJson(props));
        }
160 161
    }
    
H
haocao 已提交
162
    private void persistMasterSlaveRuleConfiguration(final MasterSlaveRuleConfiguration config, final boolean isOverwrite) {
163 164 165 166 167
        if (!dataNodeStorage.isNodeExisted(ConfigurationNode.MASTER_SLAVE_NODE_PATH) || isOverwrite) {
            dataNodeStorage.fillNode(ConfigurationNode.MASTER_SLAVE_NODE_PATH, GsonFactory.getGson().toJson(config));
        }
    }
    
H
haocao 已提交
168
    private void persistDataSourceConfiguration(final Map<String, DataSource> dataSourceMap, final boolean isOverwrite) {
169 170 171 172 173
        if (!dataNodeStorage.isNodeExisted(ConfigurationNode.DATA_SOURCE_NODE_PATH) || isOverwrite) {
            dataNodeStorage.fillNode(ConfigurationNode.DATA_SOURCE_NODE_PATH, DataSourceJsonConverter.toJson(dataSourceMap));
        }
    }
}