/* * Licensed to CRATE Technology GmbH ("Crate") under one or more contributor * license agreements. See the NOTICE file distributed with this work for * additional information regarding copyright ownership. Crate licenses * this file to you 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. * * However, if you have executed another commercial license agreement * with Crate these terms will supersede the license and you may use the * software solely pursuant to the terms of the relevant commercial agreement. */ package io.crate.metadata; import com.carrotsearch.hppc.cursors.ObjectObjectCursor; import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.FluentIterable; import io.crate.Constants; import io.crate.analyze.NumberOfReplicas; import io.crate.analyze.TableParameterInfo; import io.crate.metadata.doc.DocIndexMetaData; import io.crate.metadata.doc.PartitionedByMappingExtractor; import io.crate.types.DataType; import io.crate.types.DataTypes; import org.apache.lucene.util.BytesRef; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.cluster.metadata.MappingMetaData; import org.elasticsearch.common.collect.Tuple; import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.lucene.BytesRefs; import javax.annotation.Nullable; import java.util.HashMap; import java.util.Iterator; import java.util.Map; public class PartitionInfos implements Iterable<PartitionInfo> { private static final Predicate<ObjectObjectCursor<String, IndexMetaData>> PARTITION_INDICES_PREDICATE = input -> input != null && input.value.getState() == IndexMetaData.State.OPEN && PartitionName.isPartition(input.key); private static final Function<ObjectObjectCursor<String, IndexMetaData>, PartitionInfo> CREATE_PARTITION_INFO_FUNCTION = new Function<ObjectObjectCursor<String, IndexMetaData>, PartitionInfo>() { @Nullable @Override public PartitionInfo apply(@Nullable ObjectObjectCursor<String, IndexMetaData> input) { assert input != null : "input must not be null"; PartitionName partitionName = PartitionName.fromIndexOrTemplate(input.key); try { MappingMetaData mappingMetaData = input.value.mapping(Constants.DEFAULT_MAPPING_TYPE); Map<String, Object> mappingMap = mappingMetaData.sourceAsMap(); Map<String, Object> valuesMap = buildValuesMap(partitionName, mappingMetaData); BytesRef numberOfReplicas = NumberOfReplicas.fromSettings(input.value.getSettings()); return new PartitionInfo( partitionName, input.value.getNumberOfShards(), numberOfReplicas, DocIndexMetaData.getRoutingHashFunction(mappingMap), DocIndexMetaData.getVersionCreated(mappingMap), DocIndexMetaData.getVersionUpgraded(mappingMap), valuesMap, TableParameterInfo.tableParametersFromIndexMetaData(input.value)); } catch (Exception e) { Loggers.getLogger(PartitionInfos.class).trace("error extracting partition infos from index {}", e, input.key); return null; // must filter on null } } }; private final ClusterService clusterService; public PartitionInfos(ClusterService clusterService) { this.clusterService = clusterService; } @Override public Iterator<PartitionInfo> iterator() { // get a fresh one for each iteration return FluentIterable.from(clusterService.state().metaData().indices()) .filter(PARTITION_INDICES_PREDICATE) .transform(CREATE_PARTITION_INFO_FUNCTION) .filter(Predicates.notNull()) .iterator(); } @Nullable private static Map<String, Object> buildValuesMap(PartitionName partitionName, MappingMetaData mappingMetaData) throws Exception { int i = 0; Map<String, Object> valuesMap = new HashMap<>(); Iterable<Tuple<ColumnIdent, DataType>> partitionColumnInfoIterable = PartitionedByMappingExtractor.extractPartitionedByColumns(mappingMetaData.sourceAsMap()); for (Tuple<ColumnIdent, DataType> columnInfo : partitionColumnInfoIterable) { String columnName = columnInfo.v1().sqlFqn(); // produce string type values as string, not bytesref Object value = BytesRefs.toString(partitionName.values().get(i)); if (!columnInfo.v2().equals(DataTypes.STRING)) { value = columnInfo.v2().value(value); } valuesMap.put(columnName, value); i++; } return valuesMap; } }