Starting in Elasticsearch 7.x, colons are no longer allowed in index names. This logic will + * make sure the pattern in our index template doesn't use them either. + * + *
See https://github.com/openzipkin/zipkin/issues/2219
+ */
+ static char indexTypeDelimiter(ElasticsearchVersion version) {
+ return version.compareTo(V7_0) < 0 ? ':' : '-';
+ }
+
+ @Override String maybeWrap(String type, ElasticsearchVersion version, String json) {
+ // ES 7.x defaults include_type_name to false https://www.elastic.co/guide/en/elasticsearch/reference/current/breaking-changes-7.0.html#_literal_include_type_name_literal_now_defaults_to_literal_false_literal
+ if (version.compareTo(V7_0) >= 0) return json;
+ return " \"" + type + "\": {\n " + json.replace("\n", "\n ") + " }\n";
+ }
+
+ @Override IndexTemplates get(ElasticsearchVersion version) {
+ if (version.compareTo(V5_0) < 0 || version.compareTo(V9_0) >= 0) {
+ throw new IllegalArgumentException(
+ "Elasticsearch versions 5-8.x are supported, was: " + version);
+ }
+ return IndexTemplates.newBuilder()
+ .version(version)
+ .indexTypeDelimiter(indexTypeDelimiter(version))
+ .span(spanIndexTemplate(version))
+ .dependency(dependencyTemplate(version))
+ .autocomplete(autocompleteTemplate(version))
+ .build();
+ }
+}
diff --git a/zipkin-storage/elasticsearch/src/main/java/zipkin2/elasticsearch/ElasticsearchStorage.java b/zipkin-storage/elasticsearch/src/main/java/zipkin2/elasticsearch/ElasticsearchStorage.java
index 0658681a95..067226ce49 100644
--- a/zipkin-storage/elasticsearch/src/main/java/zipkin2/elasticsearch/ElasticsearchStorage.java
+++ b/zipkin-storage/elasticsearch/src/main/java/zipkin2/elasticsearch/ElasticsearchStorage.java
@@ -36,9 +36,6 @@
import zipkin2.storage.Traces;
import static com.linecorp.armeria.common.HttpMethod.GET;
-import static zipkin2.elasticsearch.ElasticsearchVersion.V6_7;
-import static zipkin2.elasticsearch.ElasticsearchVersion.V7_0;
-import static zipkin2.elasticsearch.ElasticsearchVersion.V7_8;
import static zipkin2.elasticsearch.EnsureIndexTemplate.ensureIndexTemplate;
import static zipkin2.elasticsearch.VersionSpecificTemplates.TYPE_AUTOCOMPLETE;
import static zipkin2.elasticsearch.VersionSpecificTemplates.TYPE_DEPENDENCY;
@@ -240,17 +237,17 @@ public final Builder dateSeparator(char dateSeparator) {
return new ElasticsearchSpanConsumer(this);
}
- /** Returns the Elasticsearch version of the connected cluster. Internal use only */
- @Memoized public ElasticsearchVersion version() {
+ /** Returns the Elasticsearch / OpenSearch version of the connected cluster. Internal use only */
+ @Memoized public BaseVersion version() {
try {
- return ElasticsearchVersion.get(http());
+ return BaseVersion.get(http());
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
char indexTypeDelimiter() {
- return VersionSpecificTemplates.indexTypeDelimiter(version());
+ return VersionSpecificTemplates.forVersion(version()).indexTypeDelimiter();
}
/** This is an internal blocking call, only used in tests. */
@@ -337,35 +334,20 @@ IndexTemplates doEnsureIndexTemplates() {
}
}
- IndexTemplates versionSpecificTemplates(ElasticsearchVersion version) {
- return new VersionSpecificTemplates(
+ IndexTemplates versionSpecificTemplates(BaseVersion version) {
+ return VersionSpecificTemplates.forVersion(version).get(
indexNameFormatter().index(),
indexReplicas(),
indexShards(),
searchEnabled(),
strictTraceId(),
templatePriority()
- ).get(version);
+ );
}
String buildUrl(IndexTemplates templates, String type) {
String indexPrefix = indexNameFormatter().index() + templates.indexTypeDelimiter();
-
- if (version().compareTo(V7_8) >= 0 && templatePriority() != null) {
- return "/_index_template/" + indexPrefix + type + "_template";
- }
- if (version().compareTo(V6_7) >= 0 && version().compareTo(V7_0) < 0) {
- // because deprecation warning on 6 to prepare for 7:
- //
- // [types removal] The parameter include_type_name should be explicitly specified in get
- // template requests to prepare for 7.0. In 7.0 include_type_name will default to 'false',
- // which means responses will omit the type name in mapping definitions.
- //
- // The parameter include_type_name was added in 6.7. Using this with ES older than
- // 6.7 will result in unrecognized parameter: [include_type_name].
- return "/_template/" + indexPrefix + type + "_template?include_type_name=true";
- }
- return "/_template/" + indexPrefix + type + "_template";
+ return VersionSpecificTemplates.forVersion(version()).indexTemplatesUrl(indexPrefix, type, templatePriority());
}
@Override public final String toString() {
diff --git a/zipkin-storage/elasticsearch/src/main/java/zipkin2/elasticsearch/ElasticsearchVersion.java b/zipkin-storage/elasticsearch/src/main/java/zipkin2/elasticsearch/ElasticsearchVersion.java
index e7d17ce04c..e7c821e0c9 100644
--- a/zipkin-storage/elasticsearch/src/main/java/zipkin2/elasticsearch/ElasticsearchVersion.java
+++ b/zipkin-storage/elasticsearch/src/main/java/zipkin2/elasticsearch/ElasticsearchVersion.java
@@ -4,20 +4,10 @@
*/
package zipkin2.elasticsearch;
-import com.fasterxml.jackson.core.JsonParser;
-import com.linecorp.armeria.common.AggregatedHttpRequest;
-import com.linecorp.armeria.common.HttpMethod;
-import java.io.IOException;
import java.util.Objects;
-import java.util.function.Supplier;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import zipkin2.elasticsearch.internal.client.HttpCall;
-
-import static zipkin2.elasticsearch.internal.JsonReaders.enterPath;
/** Helps avoid problems comparing versions by number. Ex 7.10 should be > 7.9 */
-public final class ElasticsearchVersion implements Comparable Starting in Elasticsearch 7.x, colons are no longer allowed in index names. This logic will
- * make sure the pattern in our index template doesn't use them either.
- *
- * See https://github.com/openzipkin/zipkin/issues/2219
+ * Wraps the JSON payload if needed
+ * @param type type
+ * @param version distribution version
+ * @param json JSON payload
+ * @return wrapped JSON payload if needed
*/
- static char indexTypeDelimiter(ElasticsearchVersion version) {
- return version.compareTo(V7_0) < 0 ? ':' : '-';
+ abstract String maybeWrap(String type, V version, String json);
+
+ /**
+ * Returns distribution specific templates (index templates URL, index
+ * type delimiter, {@link IndexTemplates});
+ */
+ abstract static class DistributionSpecificTemplates {
+ /**
+ * Returns distribution specific index templates URL
+ * @param indexPrefix index prefix
+ * @param type type
+ * @param templatePriority index template priority
+ * @return index templates URL
+ */
+ abstract String indexTemplatesUrl(String indexPrefix, String type, @Nullable Integer templatePriority);
+
+ /**
+ * Returns distribution specific index type delimiter
+ * @return index type delimiter
+ */
+ abstract char indexTypeDelimiter();
+
+ /**
+ * Returns distribution specific index templates
+ * @param indexPrefix index prefix
+ * @param indexReplicas number of replicas
+ * @param indexShards number of shards
+ * @param searchEnabled search is enabled or disabled
+ * @param strictTraceId strict trace ID
+ * @param templatePriority index template priority
+ * @return index templates
+ */
+ abstract IndexTemplates get(String indexPrefix, int indexReplicas, int indexShards,
+ boolean searchEnabled, boolean strictTraceId, Integer templatePriority);
}
- static String maybeWrap(String type, ElasticsearchVersion version, String json) {
- // ES 7.x defaults include_type_name to false https://www.elastic.co/guide/en/elasticsearch/reference/current/breaking-changes-7.0.html#_literal_include_type_name_literal_now_defaults_to_literal_false_literal
- if (version.compareTo(V7_0) >= 0) return json;
- return " \"" + type + "\": {\n " + json.replace("\n", "\n ") + " }\n";
+ /**
+ * Creates a new {@link DistributionSpecificTemplates} instance based on the distribution
+ * @param version distribution version
+ * @return {@link OpensearchSpecificTemplates} or {@link ElasticsearchSpecificTemplates} instance
+ */
+ static DistributionSpecificTemplates forVersion(BaseVersion version) {
+ if (version instanceof ElasticsearchVersion) {
+ return new ElasticsearchSpecificTemplates.DistributionTemplate((ElasticsearchVersion) version);
+ } else if (version instanceof OpensearchVersion) {
+ return new OpensearchSpecificTemplates.DistributionTemplate((OpensearchVersion) version);
+ } else {
+ throw new IllegalArgumentException("The distribution version is not supported: " + version);
+ }
}
}
-
diff --git a/zipkin-storage/elasticsearch/src/main/java/zipkin2/elasticsearch/internal/BulkCallBuilder.java b/zipkin-storage/elasticsearch/src/main/java/zipkin2/elasticsearch/internal/BulkCallBuilder.java
index 1c66a40eff..57236d2b4b 100644
--- a/zipkin-storage/elasticsearch/src/main/java/zipkin2/elasticsearch/internal/BulkCallBuilder.java
+++ b/zipkin-storage/elasticsearch/src/main/java/zipkin2/elasticsearch/internal/BulkCallBuilder.java
@@ -27,13 +27,13 @@
import java.util.List;
import java.util.concurrent.RejectedExecutionException;
import java.util.function.Supplier;
+
+import zipkin2.elasticsearch.BaseVersion;
import zipkin2.elasticsearch.ElasticsearchStorage;
-import zipkin2.elasticsearch.ElasticsearchVersion;
import zipkin2.elasticsearch.internal.client.HttpCall;
import zipkin2.elasticsearch.internal.client.HttpCall.BodyConverter;
import static zipkin2.Call.propagateIfFatal;
-import static zipkin2.elasticsearch.ElasticsearchVersion.V7_0;
import static zipkin2.elasticsearch.internal.JsonSerializers.OBJECT_MAPPER;
import static zipkin2.elasticsearch.internal.client.HttpCall.maybeRootCauseReason;
@@ -79,9 +79,9 @@ public final class BulkCallBuilder {
// Mutated for each call to index
final List