View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.shardingsphere.sharding.rule.attribute;
19  
20  import com.cedarsoftware.util.CaseInsensitiveMap;
21  import com.google.common.base.Strings;
22  import org.apache.shardingsphere.infra.datanode.DataNode;
23  import org.apache.shardingsphere.infra.rule.attribute.datanode.DataNodeRuleAttribute;
24  import org.apache.shardingsphere.sharding.rule.ShardingTable;
25  
26  import java.util.Collection;
27  import java.util.Collections;
28  import java.util.List;
29  import java.util.Map;
30  import java.util.Optional;
31  
32  /**
33   * Sharding data node rule attribute.
34   */
35  public final class ShardingDataNodeRuleAttribute implements DataNodeRuleAttribute {
36      
37      private final Map<String, ShardingTable> shardingTables;
38      
39      private final Map<String, Collection<DataNode>> tableDataNodes;
40      
41      public ShardingDataNodeRuleAttribute(final Map<String, ShardingTable> shardingTables) {
42          this.shardingTables = shardingTables;
43          tableDataNodes = createShardingTableDataNodes(shardingTables);
44      }
45      
46      private Map<String, Collection<DataNode>> createShardingTableDataNodes(final Map<String, ShardingTable> shardingTables) {
47          Map<String, Collection<DataNode>> result = new CaseInsensitiveMap<>(shardingTables.size(), 1F);
48          for (ShardingTable each : shardingTables.values()) {
49              result.put(each.getLogicTable(), each.getActualDataNodes());
50          }
51          return result;
52      }
53      
54      @Override
55      public Map<String, Collection<DataNode>> getAllDataNodes() {
56          return tableDataNodes;
57      }
58      
59      @Override
60      public Collection<DataNode> getDataNodesByTableName(final String tableName) {
61          return tableDataNodes.getOrDefault(tableName, Collections.emptyList());
62      }
63      
64      @Override
65      public Optional<String> findFirstActualTable(final String logicTable) {
66          return findShardingTable(logicTable).map(optional -> optional.getActualDataNodes().get(0).getTableName());
67      }
68      
69      private Optional<ShardingTable> findShardingTable(final String logicTableName) {
70          return Strings.isNullOrEmpty(logicTableName) || !shardingTables.containsKey(logicTableName) ? Optional.empty() : Optional.of(shardingTables.get(logicTableName));
71      }
72      
73      @Override
74      public boolean isNeedAccumulate(final Collection<String> tables) {
75          return containsShardingTable(tables);
76      }
77      
78      private boolean containsShardingTable(final Collection<String> logicTableNames) {
79          for (String each : logicTableNames) {
80              if (isShardingTable(each)) {
81                  return true;
82              }
83          }
84          return false;
85      }
86      
87      private boolean isShardingTable(final String logicTableName) {
88          return shardingTables.containsKey(logicTableName);
89      }
90      
91      @Override
92      public Optional<String> findLogicTableByActualTable(final String actualTable) {
93          return findShardingTableByActualTable(actualTable).map(ShardingTable::getLogicTable);
94      }
95      
96      private Optional<ShardingTable> findShardingTableByActualTable(final String actualTableName) {
97          for (ShardingTable each : shardingTables.values()) {
98              if (each.isExisted(actualTableName)) {
99                  return Optional.of(each);
100             }
101         }
102         return Optional.empty();
103     }
104     
105     @Override
106     public Optional<String> findActualTableByCatalog(final String catalog, final String logicTable) {
107         return findShardingTable(logicTable).flatMap(optional -> findActualTableFromActualDataNode(catalog, optional.getActualDataNodes()));
108     }
109     
110     private Optional<String> findActualTableFromActualDataNode(final String catalog, final List<DataNode> actualDataNodes) {
111         return actualDataNodes.stream().filter(each -> each.getDataSourceName().equalsIgnoreCase(catalog)).findFirst().map(DataNode::getTableName);
112     }
113 }