53
53
import org .elasticsearch .common .ValidationException ;
54
54
import org .elasticsearch .common .compress .CompressedXContent ;
55
55
import org .elasticsearch .common .io .PathUtils ;
56
+ import org .elasticsearch .common .logging .DeprecationLogger ;
56
57
import org .elasticsearch .common .settings .IndexScopedSettings ;
57
58
import org .elasticsearch .common .settings .Setting ;
58
59
import org .elasticsearch .common .settings .Settings ;
70
71
import org .elasticsearch .indices .IndexCreationException ;
71
72
import org .elasticsearch .indices .IndicesService ;
72
73
import org .elasticsearch .indices .InvalidIndexNameException ;
74
+ import org .elasticsearch .indices .SystemIndexDescriptor ;
73
75
import org .elasticsearch .indices .cluster .IndicesClusterStateService .AllocatedIndices .IndexRemovalReason ;
74
76
import org .elasticsearch .threadpool .ThreadPool ;
75
77
78
80
import java .nio .file .Path ;
79
81
import java .time .Instant ;
80
82
import java .util .ArrayList ;
83
+ import java .util .Collection ;
81
84
import java .util .Collections ;
82
85
import java .util .HashMap ;
83
86
import java .util .List ;
89
92
import java .util .function .BiFunction ;
90
93
import java .util .function .Predicate ;
91
94
import java .util .function .Supplier ;
95
+ import java .util .stream .Collectors ;
92
96
import java .util .stream .IntStream ;
93
97
94
98
import static java .util .stream .Collectors .toList ;
103
107
*/
104
108
public class MetaDataCreateIndexService {
105
109
private static final Logger logger = LogManager .getLogger (MetaDataCreateIndexService .class );
110
+ private static final DeprecationLogger deprecationLogger = new DeprecationLogger (logger );
106
111
107
112
public static final int MAX_INDEX_NAME_BYTES = 255 ;
108
113
@@ -115,19 +120,21 @@ public class MetaDataCreateIndexService {
115
120
private final IndexScopedSettings indexScopedSettings ;
116
121
private final ActiveShardsObserver activeShardsObserver ;
117
122
private final NamedXContentRegistry xContentRegistry ;
123
+ private final Collection <SystemIndexDescriptor > systemIndexDescriptors ;
118
124
private final boolean forbidPrivateIndexSettings ;
119
125
120
126
public MetaDataCreateIndexService (
121
- final Settings settings ,
122
- final ClusterService clusterService ,
123
- final IndicesService indicesService ,
124
- final AllocationService allocationService ,
125
- final AliasValidator aliasValidator ,
126
- final Environment env ,
127
- final IndexScopedSettings indexScopedSettings ,
128
- final ThreadPool threadPool ,
129
- final NamedXContentRegistry xContentRegistry ,
130
- final boolean forbidPrivateIndexSettings ) {
127
+ final Settings settings ,
128
+ final ClusterService clusterService ,
129
+ final IndicesService indicesService ,
130
+ final AllocationService allocationService ,
131
+ final AliasValidator aliasValidator ,
132
+ final Environment env ,
133
+ final IndexScopedSettings indexScopedSettings ,
134
+ final ThreadPool threadPool ,
135
+ final NamedXContentRegistry xContentRegistry ,
136
+ final Collection <SystemIndexDescriptor > systemIndexDescriptors ,
137
+ final boolean forbidPrivateIndexSettings ) {
131
138
this .settings = settings ;
132
139
this .clusterService = clusterService ;
133
140
this .indicesService = indicesService ;
@@ -137,17 +144,40 @@ public MetaDataCreateIndexService(
137
144
this .indexScopedSettings = indexScopedSettings ;
138
145
this .activeShardsObserver = new ActiveShardsObserver (clusterService , threadPool );
139
146
this .xContentRegistry = xContentRegistry ;
147
+ this .systemIndexDescriptors = systemIndexDescriptors ;
140
148
this .forbidPrivateIndexSettings = forbidPrivateIndexSettings ;
141
149
}
142
150
143
151
/**
144
152
* Validate the name for an index against some static rules and a cluster state.
145
153
*/
146
- public static void validateIndexName (String index , ClusterState state ) {
154
+ public void validateIndexName (String index , ClusterState state , @ Nullable Boolean isHidden ) {
147
155
validateIndexOrAliasName (index , InvalidIndexNameException ::new );
148
156
if (!index .toLowerCase (Locale .ROOT ).equals (index )) {
149
157
throw new InvalidIndexNameException (index , "must be lowercase" );
150
158
}
159
+
160
+ if (index .charAt (0 ) == '.' ) {
161
+ List <SystemIndexDescriptor > matchingDescriptors = systemIndexDescriptors .stream ()
162
+ .filter (descriptor -> descriptor .matchesIndexPattern (index ))
163
+ .collect (toList ());
164
+ if (matchingDescriptors .isEmpty () && (isHidden == null || isHidden == Boolean .FALSE )) {
165
+ deprecationLogger .deprecated ("index name [{}] starts with a dot '.', in the next major version, index names " +
166
+ "starting with a dot are reserved for hidden indices and system indices" , index );
167
+ } else if (matchingDescriptors .size () > 1 ) {
168
+ // This should be prevented by erroring on overlapping patterns at startup time, but is here just in case.
169
+ StringBuilder errorMessage = new StringBuilder ()
170
+ .append ("index name [" )
171
+ .append (index )
172
+ .append ("] is claimed as a system index by multiple system index patterns: [" )
173
+ .append (matchingDescriptors .stream ()
174
+ .map (descriptor -> "pattern: [" + descriptor .getIndexPattern () +
175
+ "], description: [" + descriptor .getDescription () + "]" ).collect (Collectors .joining ("; " )));
176
+ // Throw AssertionError if assertions are enabled, or a regular exception otherwise:
177
+ assert false : errorMessage .toString ();
178
+ throw new IllegalStateException (errorMessage .toString ());
179
+ }
180
+ }
151
181
if (state .routingTable ().hasIndex (index )) {
152
182
throw new ResourceAlreadyExistsException (state .routingTable ().index (index ).getIndex ());
153
183
}
@@ -653,7 +683,8 @@ private static IndexService validateActiveShardCountAndCreateIndexService(String
653
683
}
654
684
655
685
private void validate (CreateIndexClusterStateUpdateRequest request , ClusterState state ) {
656
- validateIndexName (request .index (), state );
686
+ boolean isHidden = IndexMetaData .INDEX_HIDDEN_SETTING .get (request .settings ());
687
+ validateIndexName (request .index (), state , isHidden );
657
688
validateIndexSettings (request .index (), request .settings (), forbidPrivateIndexSettings );
658
689
}
659
690
0 commit comments