1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shardingsphere.mode.manager;
19
20 import lombok.Getter;
21 import lombok.extern.slf4j.Slf4j;
22 import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
23 import org.apache.shardingsphere.infra.config.props.ConfigurationPropertyKey;
24 import org.apache.shardingsphere.infra.config.rule.RuleConfiguration;
25 import org.apache.shardingsphere.infra.datasource.pool.props.domain.DataSourcePoolProperties;
26 import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions;
27 import org.apache.shardingsphere.infra.exception.dialect.exception.syntax.database.NoDatabaseSelectedException;
28 import org.apache.shardingsphere.infra.exception.dialect.exception.syntax.database.UnknownDatabaseException;
29 import org.apache.shardingsphere.infra.executor.kernel.ExecutorEngine;
30 import org.apache.shardingsphere.infra.instance.InstanceContext;
31 import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
32 import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
33 import org.apache.shardingsphere.infra.metadata.database.resource.unit.StorageUnit;
34 import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
35 import org.apache.shardingsphere.infra.metadata.database.schema.builder.GenericSchemaBuilder;
36 import org.apache.shardingsphere.infra.metadata.database.schema.builder.GenericSchemaBuilderMaterial;
37 import org.apache.shardingsphere.infra.metadata.database.schema.manager.GenericSchemaManager;
38 import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
39 import org.apache.shardingsphere.infra.rule.builder.global.GlobalRulesBuilder;
40 import org.apache.shardingsphere.infra.state.cluster.ClusterState;
41 import org.apache.shardingsphere.metadata.persist.MetaDataBasedPersistService;
42 import org.apache.shardingsphere.mode.manager.context.ConfigurationContextManager;
43 import org.apache.shardingsphere.mode.manager.context.ResourceMetaDataContextManager;
44 import org.apache.shardingsphere.mode.manager.context.ShardingSphereDatabaseContextManager;
45 import org.apache.shardingsphere.mode.manager.switcher.ResourceSwitchManager;
46 import org.apache.shardingsphere.mode.manager.switcher.SwitchingResource;
47 import org.apache.shardingsphere.mode.metadata.MetaDataContexts;
48 import org.apache.shardingsphere.mode.state.StateContext;
49 import org.apache.shardingsphere.mode.state.StateService;
50
51 import java.sql.SQLException;
52 import java.util.Collection;
53 import java.util.Collections;
54 import java.util.Map;
55 import java.util.concurrent.atomic.AtomicReference;
56
57
58
59
60 @Getter
61 @Slf4j
62 public final class ContextManager implements AutoCloseable {
63
64 private final AtomicReference<MetaDataContexts> metaDataContexts;
65
66 private final InstanceContext instanceContext;
67
68 private final ShardingSphereDatabaseContextManager shardingSphereDatabaseContextManager;
69
70 private final ConfigurationContextManager configurationContextManager;
71
72 private final ResourceMetaDataContextManager resourceMetaDataContextManager;
73
74 private final ExecutorEngine executorEngine;
75
76 private final StateContext stateContext;
77
78 public ContextManager(final MetaDataContexts metaDataContexts, final InstanceContext instanceContext) {
79 this.metaDataContexts = new AtomicReference<>(metaDataContexts);
80 this.instanceContext = instanceContext;
81 shardingSphereDatabaseContextManager = new ShardingSphereDatabaseContextManager(this.metaDataContexts);
82 configurationContextManager = new ConfigurationContextManager(this.metaDataContexts, instanceContext);
83 resourceMetaDataContextManager = new ResourceMetaDataContextManager(this.metaDataContexts);
84 executorEngine = ExecutorEngine.createExecutorEngineWithSize(metaDataContexts.getMetaData().getProps().<Integer>getValue(ConfigurationPropertyKey.KERNEL_EXECUTOR_SIZE));
85 stateContext = new StateContext(new StateService(metaDataContexts.getPersistService().getRepository()));
86 }
87
88
89
90
91
92
93 public MetaDataContexts getMetaDataContexts() {
94 return metaDataContexts.get();
95 }
96
97
98
99
100
101
102 public void renewMetaDataContexts(final MetaDataContexts metaDataContexts) {
103 this.metaDataContexts.set(metaDataContexts);
104 }
105
106
107
108
109
110
111
112 public ShardingSphereDatabase getDatabase(final String name) {
113 ShardingSpherePreconditions.checkNotEmpty(name, NoDatabaseSelectedException::new);
114 ShardingSphereMetaData metaData = getMetaDataContexts().getMetaData();
115 ShardingSpherePreconditions.checkState(metaData.containsDatabase(name), () -> new UnknownDatabaseException(name));
116 return metaData.getDatabase(name);
117 }
118
119
120
121
122
123
124
125 public Map<String, StorageUnit> getStorageUnits(final String databaseName) {
126 return getDatabase(databaseName).getResourceMetaData().getStorageUnits();
127 }
128
129
130
131
132
133
134
135 public void refreshDatabaseMetaData(final ShardingSphereDatabase database, final boolean force) {
136 try {
137 MetaDataContexts reloadedMetaDataContexts = createMetaDataContexts(database);
138 MetaDataBasedPersistService persistService = metaDataContexts.get().getPersistService();
139 if (force) {
140 metaDataContexts.set(reloadedMetaDataContexts);
141 metaDataContexts.get().getMetaData().getDatabase(database.getName()).getSchemas()
142 .forEach((schemaName, schema) -> persistService.getDatabaseMetaDataService().persistByAlterConfiguration(database.getName(), schemaName, schema));
143 } else {
144 deletedSchemaNames(database.getName(), reloadedMetaDataContexts.getMetaData().getDatabase(database.getName()), database);
145 metaDataContexts.set(reloadedMetaDataContexts);
146 metaDataContexts.get().getMetaData().getDatabase(database.getName()).getSchemas()
147 .forEach((schemaName, schema) -> persistService.getDatabaseMetaDataService().compareAndPersist(database.getName(), schemaName, schema));
148 }
149 } catch (final SQLException ex) {
150 log.error("Refresh database meta data: {} failed", database.getName(), ex);
151 }
152 }
153
154
155
156
157
158
159 public void refreshTableMetaData(final ShardingSphereDatabase database) {
160 try {
161 MetaDataContexts reloadedMetaDataContexts = createMetaDataContexts(database);
162 deletedSchemaNames(database.getName(), reloadedMetaDataContexts.getMetaData().getDatabase(database.getName()), database);
163 metaDataContexts.set(reloadedMetaDataContexts);
164 metaDataContexts.get().getMetaData().getDatabase(database.getName()).getSchemas()
165 .forEach((schemaName, schema) -> metaDataContexts.get().getPersistService().getDatabaseMetaDataService().compareAndPersist(database.getName(), schemaName, schema));
166 } catch (final SQLException ex) {
167 log.error("Refresh table meta data: {} failed", database.getName(), ex);
168 }
169 }
170
171 private MetaDataContexts createMetaDataContexts(final ShardingSphereDatabase database) throws SQLException {
172 MetaDataBasedPersistService metaDataPersistService = metaDataContexts.get().getPersistService();
173 Map<String, DataSourcePoolProperties> dataSourcePoolPropsFromRegCenter = metaDataPersistService.getDataSourceUnitService().load(database.getName());
174 SwitchingResource switchingResource = new ResourceSwitchManager().alterStorageUnit(database.getResourceMetaData(), dataSourcePoolPropsFromRegCenter);
175 metaDataContexts.get().getMetaData().getDatabases().putAll(configurationContextManager.renewDatabase(database, switchingResource));
176 Collection<RuleConfiguration> ruleConfigs = metaDataPersistService.getDatabaseRulePersistService().load(database.getName());
177 Map<String, ShardingSphereDatabase> changedDatabases = configurationContextManager.createChangedDatabases(database.getName(), false, switchingResource, ruleConfigs);
178 ConfigurationProperties props = new ConfigurationProperties(metaDataPersistService.getPropsService().load());
179 Collection<RuleConfiguration> globalRuleConfigs = metaDataPersistService.getGlobalRuleService().load();
180 RuleMetaData changedGlobalMetaData = new RuleMetaData(GlobalRulesBuilder.buildRules(globalRuleConfigs, changedDatabases, props));
181 MetaDataContexts result = new MetaDataContexts(metaDataPersistService,
182 new ShardingSphereMetaData(changedDatabases, metaDataContexts.get().getMetaData().getGlobalResourceMetaData(), changedGlobalMetaData, props));
183 switchingResource.closeStaleDataSources();
184 return result;
185 }
186
187
188
189
190
191
192
193
194 public void deletedSchemaNames(final String databaseName, final ShardingSphereDatabase reloadDatabase, final ShardingSphereDatabase currentDatabase) {
195 GenericSchemaManager.getToBeDeletedSchemaNames(reloadDatabase.getSchemas(), currentDatabase.getSchemas()).keySet()
196 .forEach(each -> metaDataContexts.get().getPersistService().getDatabaseMetaDataService().dropSchema(databaseName, each));
197 }
198
199
200
201
202
203
204
205
206 public void reloadSchema(final ShardingSphereDatabase database, final String schemaName, final String dataSourceName) {
207 try {
208 ShardingSphereSchema reloadedSchema = loadSchema(database, schemaName, dataSourceName);
209 if (reloadedSchema.getTables().isEmpty()) {
210 database.dropSchema(schemaName);
211 metaDataContexts.get().getPersistService().getDatabaseMetaDataService().dropSchema(database.getName(),
212 schemaName);
213 } else {
214 database.addSchema(schemaName, reloadedSchema);
215 metaDataContexts.get().getPersistService().getDatabaseMetaDataService()
216 .compareAndPersist(database.getName(), schemaName, reloadedSchema);
217 }
218 } catch (final SQLException ex) {
219 log.error("Reload meta data of database: {} schema: {} with data source: {} failed", database.getName(), schemaName, dataSourceName, ex);
220 }
221 }
222
223 private ShardingSphereSchema loadSchema(final ShardingSphereDatabase database, final String schemaName, final String dataSourceName) throws SQLException {
224 database.reloadRules();
225 GenericSchemaBuilderMaterial material = new GenericSchemaBuilderMaterial(database.getProtocolType(),
226 Collections.singletonMap(dataSourceName, database.getResourceMetaData().getStorageUnits().get(dataSourceName).getStorageType()),
227 Collections.singletonMap(dataSourceName, database.getResourceMetaData().getStorageUnits().get(dataSourceName).getDataSource()),
228 database.getRuleMetaData().getRules(), metaDataContexts.get().getMetaData().getProps(), schemaName);
229 ShardingSphereSchema result = GenericSchemaBuilder.build(material).get(schemaName);
230 result.getViews().putAll(metaDataContexts.get().getPersistService().getDatabaseMetaDataService().getViewMetaDataPersistService().load(database.getName(), schemaName));
231 return result;
232 }
233
234
235
236
237
238
239
240
241 public void reloadTable(final ShardingSphereDatabase database, final String schemaName, final String tableName) {
242 GenericSchemaBuilderMaterial material = new GenericSchemaBuilderMaterial(database.getProtocolType(),
243 database.getResourceMetaData().getStorageUnits(), database.getRuleMetaData().getRules(), metaDataContexts.get().getMetaData().getProps(), schemaName);
244 try {
245 persistTable(database, schemaName, tableName, material);
246 } catch (final SQLException ex) {
247 log.error("Reload table: {} meta data of database: {} schema: {} failed", tableName, database.getName(), schemaName, ex);
248 }
249 }
250
251
252
253
254
255
256
257
258
259 public void reloadTable(final ShardingSphereDatabase database, final String schemaName, final String dataSourceName, final String tableName) {
260 StorageUnit storageUnit = database.getResourceMetaData().getStorageUnits().get(dataSourceName);
261 GenericSchemaBuilderMaterial material = new GenericSchemaBuilderMaterial(database.getProtocolType(),
262 Collections.singletonMap(dataSourceName, storageUnit.getStorageType()), Collections.singletonMap(dataSourceName, storageUnit.getDataSource()),
263 database.getRuleMetaData().getRules(), metaDataContexts.get().getMetaData().getProps(), schemaName);
264 try {
265 persistTable(database, schemaName, tableName, material);
266 } catch (final SQLException ex) {
267 log.error("Reload table: {} meta data of database: {} schema: {} with data source: {} failed", tableName, database.getName(), schemaName, dataSourceName, ex);
268 }
269 }
270
271 private void persistTable(final ShardingSphereDatabase database, final String schemaName, final String tableName, final GenericSchemaBuilderMaterial material) throws SQLException {
272 ShardingSphereSchema schema = GenericSchemaBuilder.build(Collections.singleton(tableName), material).getOrDefault(schemaName, new ShardingSphereSchema());
273 metaDataContexts.get().getPersistService().getDatabaseMetaDataService().getTableMetaDataPersistService()
274 .persist(database.getName(), schemaName, Collections.singletonMap(tableName, schema.getTable(tableName)));
275 }
276
277
278
279
280
281
282 public void updateClusterState(final ClusterState clusterState) {
283 stateContext.switchState(clusterState);
284 }
285
286 @Override
287 public void close() {
288 executorEngine.close();
289 metaDataContexts.get().close();
290 }
291 }