diff --git a/zipkin-storage/elasticsearch-http/src/main/java/zipkin/storage/elasticsearch/http/ElasticsearchHttpStorage.java b/zipkin-storage/elasticsearch-http/src/main/java/zipkin/storage/elasticsearch/http/ElasticsearchHttpStorage.java index 5ef6442d7cb..6199ee96174 100644 --- a/zipkin-storage/elasticsearch-http/src/main/java/zipkin/storage/elasticsearch/http/ElasticsearchHttpStorage.java +++ b/zipkin-storage/elasticsearch-http/src/main/java/zipkin/storage/elasticsearch/http/ElasticsearchHttpStorage.java @@ -123,6 +123,11 @@ public final Builder indexReplicas(int indexReplicas) { return this; } + @Override public StorageComponent.Builder indexingEnabled(boolean indexingEnabled) { + delegate.indexingEnabled(indexingEnabled); + return this; + } + @Override public final ElasticsearchHttpStorage build() { return new ElasticsearchHttpStorage(delegate.build(), legacyReadsEnabled); } 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 c2383dc7e40..737977d14ff 100644 --- a/zipkin-storage/elasticsearch/src/main/java/zipkin2/elasticsearch/ElasticsearchStorage.java +++ b/zipkin-storage/elasticsearch/src/main/java/zipkin2/elasticsearch/ElasticsearchStorage.java @@ -60,6 +60,7 @@ public static Builder newBuilder(OkHttpClient client) { .hosts(Collections.singletonList("http://localhost:9200")) .maxRequests(64) .strictTraceId(true) + .indexingEnabled(true) .index("zipkin") .dateSeparator('-') .indexShards(5) @@ -177,6 +178,8 @@ public final Builder dateSeparator(char dateSeparator) { @Override public abstract Builder strictTraceId(boolean strictTraceId); + @Override public abstract Builder indexingEnabled(boolean indexingEnabled); + @Override public abstract ElasticsearchStorage build(); abstract IndexNameFormatter.Builder indexNameFormatterBuilder(); @@ -199,6 +202,8 @@ public final Builder dateSeparator(char dateSeparator) { public abstract boolean strictTraceId(); + abstract boolean indexingEnabled(); + abstract int indexShards(); abstract int indexReplicas(); diff --git a/zipkin-storage/zipkin2_cassandra/src/main/java/zipkin2/storage/cassandra/CassandraSpanConsumer.java b/zipkin-storage/zipkin2_cassandra/src/main/java/zipkin2/storage/cassandra/CassandraSpanConsumer.java index b25228fb2c0..e58b5cdad44 100644 --- a/zipkin-storage/zipkin2_cassandra/src/main/java/zipkin2/storage/cassandra/CassandraSpanConsumer.java +++ b/zipkin-storage/zipkin2_cassandra/src/main/java/zipkin2/storage/cassandra/CassandraSpanConsumer.java @@ -26,6 +26,7 @@ import zipkin2.Annotation; import zipkin2.Call; import zipkin2.Span; +import zipkin2.internal.Nullable; import zipkin2.storage.SpanConsumer; import zipkin2.storage.cassandra.internal.call.AggregateCall; @@ -36,21 +37,27 @@ class CassandraSpanConsumer implements SpanConsumer { // not final for testing = Long.getLong("zipkin2.storage.cassandra.internal.writtenNamesTtl", 60 * 60 * 1000); private final Session session; - private final boolean strictTraceId; + private final boolean strictTraceId, indexingEnabled; private final InsertSpan.Factory insertSpan; - private final InsertTraceByServiceSpan.Factory insertTraceByServiceSpan; - private final InsertServiceSpan.Factory insertServiceSpanName; + @Nullable final InsertTraceByServiceSpan.Factory insertTraceByServiceSpan; + @Nullable private final InsertServiceSpan.Factory insertServiceSpanName; CassandraSpanConsumer(CassandraStorage storage) { session = storage.session(); strictTraceId = storage.strictTraceId(); + indexingEnabled = storage.indexingEnabled(); // warns when schema problems exist Schema.readMetadata(session); - insertSpan = new InsertSpan.Factory(session, strictTraceId); - insertTraceByServiceSpan = new InsertTraceByServiceSpan.Factory(session, strictTraceId); - insertServiceSpanName = new InsertServiceSpan.Factory(session, WRITTEN_NAMES_TTL); + insertSpan = new InsertSpan.Factory(session, strictTraceId, indexingEnabled); + if (indexingEnabled) { + insertTraceByServiceSpan = new InsertTraceByServiceSpan.Factory(session, strictTraceId); + insertServiceSpanName = new InsertServiceSpan.Factory(session, WRITTEN_NAMES_TTL); + } else { + insertTraceByServiceSpan = null; + insertServiceSpanName = null; + } } /** @@ -77,6 +84,8 @@ public Call accept(List input) { spans.add(insertSpan.newInput(s, ts_uuid)); + if (!indexingEnabled) continue; + // Empty values allow for api queries with blank service or span name String service = s.localServiceName() != null ? s.localServiceName() : ""; String span = @@ -106,11 +115,13 @@ public Call accept(List input) { for (InsertSpan.Input span : spans) { calls.add(insertSpan.create(span)); } - for (InsertServiceSpan.Input serviceSpan : serviceSpans) { - calls.add(insertServiceSpanName.create(serviceSpan)); - } - for (InsertTraceByServiceSpan.Input serviceSpan : traceByServiceSpans) { - calls.add(insertTraceByServiceSpan.create(serviceSpan)); + if (indexingEnabled) { + for (InsertServiceSpan.Input serviceSpan : serviceSpans) { + calls.add(insertServiceSpanName.create(serviceSpan)); + } + for (InsertTraceByServiceSpan.Input serviceSpan : traceByServiceSpans) { + calls.add(insertTraceByServiceSpan.create(serviceSpan)); + } } return new StoreSpansCall(calls); } diff --git a/zipkin-storage/zipkin2_cassandra/src/main/java/zipkin2/storage/cassandra/CassandraSpanStore.java b/zipkin-storage/zipkin2_cassandra/src/main/java/zipkin2/storage/cassandra/CassandraSpanStore.java index cc24081a98c..4431442d54c 100644 --- a/zipkin-storage/zipkin2_cassandra/src/main/java/zipkin2/storage/cassandra/CassandraSpanStore.java +++ b/zipkin-storage/zipkin2_cassandra/src/main/java/zipkin2/storage/cassandra/CassandraSpanStore.java @@ -17,6 +17,7 @@ import com.datastax.driver.core.Session; import com.datastax.driver.core.utils.UUIDs; import java.util.ArrayList; +import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -36,7 +37,7 @@ class CassandraSpanStore implements SpanStore { // not final for testing private final int maxTraceCols; private final int indexFetchMultiplier; - private final boolean strictTraceId; + private final boolean strictTraceId, indexingEnabled; private final SelectFromSpan.Factory spans; private final SelectDependencies.Factory dependencies; private final SelectSpanNames.Factory spanNames; @@ -50,6 +51,7 @@ class CassandraSpanStore implements SpanStore { // not final for testing maxTraceCols = storage.maxTraceCols(); indexFetchMultiplier = storage.indexFetchMultiplier(); strictTraceId = storage.strictTraceId(); + indexingEnabled = storage.indexingEnabled(); KeyspaceMetadata md = Schema.getKeyspaceMetadata(session); indexTtl = md.getTable(TABLE_TRACE_BY_SERVICE_SPAN).getOptions().getDefaultTimeToLive(); @@ -74,6 +76,8 @@ class CassandraSpanStore implements SpanStore { // not final for testing */ @Override public Call>> getTraces(QueryRequest request) { + if (!indexingEnabled) return Call.emptyList(); + return strictTraceId ? doGetTraces(request) : doGetTraces(request).map(new FilterTraces(request)); } @@ -85,7 +89,8 @@ Call>> doGetTraces(QueryRequest request) { final int traceIndexFetchSize = request.limit() * indexFetchMultiplier; List>> callsToIntersect = new ArrayList<>(); - List annotationKeys = CassandraUtil.annotationKeys(request); + List annotationKeys = + indexingEnabled ? CassandraUtil.annotationKeys(request) : Collections.emptyList(); for (String annotationKey : annotationKeys) { callsToIntersect.add(spanTable.newCall( request.serviceName(), @@ -174,10 +179,12 @@ Call>> newBucketedTraceIdCall(QueryRequest request, } @Override public Call> getServiceNames() { + if (!indexingEnabled) return Call.emptyList(); return serviceNames.clone(); } @Override public Call> getSpanNames(String serviceName) { + if (!indexingEnabled) return Call.emptyList(); return spanNames.create(serviceName); } diff --git a/zipkin-storage/zipkin2_cassandra/src/main/java/zipkin2/storage/cassandra/CassandraStorage.java b/zipkin-storage/zipkin2_cassandra/src/main/java/zipkin2/storage/cassandra/CassandraStorage.java index 96ec3f36de8..cfbc890946a 100644 --- a/zipkin-storage/zipkin2_cassandra/src/main/java/zipkin2/storage/cassandra/CassandraStorage.java +++ b/zipkin-storage/zipkin2_cassandra/src/main/java/zipkin2/storage/cassandra/CassandraStorage.java @@ -51,6 +51,7 @@ public interface SessionFactory { public static Builder newBuilder() { return new AutoValue_CassandraStorage.Builder() .strictTraceId(true) + .indexingEnabled(true) .keyspace(Schema.DEFAULT_KEYSPACE) .contactPoints("localhost") // Zipkin collectors can create out a lot of async requests in bursts @@ -67,6 +68,9 @@ public static abstract class Builder extends StorageComponent.Builder { /** {@inheritDoc} */ @Override public abstract Builder strictTraceId(boolean strictTraceId); + /** {@inheritDoc} */ + @Override public abstract Builder indexingEnabled(boolean indexingEnabled); + /** Override to control how sessions are created. */ public abstract Builder sessionFactory(SessionFactory sessionFactory); @@ -146,6 +150,7 @@ public final Builder maxConnections(int maxConnections) { abstract String keyspace(); abstract int indexFetchMultiplier(); abstract boolean strictTraceId(); + abstract boolean indexingEnabled(); abstract SessionFactory sessionFactory(); /** session and close are typically called from different threads */ diff --git a/zipkin-storage/zipkin2_cassandra/src/main/java/zipkin2/storage/cassandra/InsertSpan.java b/zipkin-storage/zipkin2_cassandra/src/main/java/zipkin2/storage/cassandra/InsertSpan.java index 032f5746d39..983fd1a7319 100644 --- a/zipkin-storage/zipkin2_cassandra/src/main/java/zipkin2/storage/cassandra/InsertSpan.java +++ b/zipkin-storage/zipkin2_cassandra/src/main/java/zipkin2/storage/cassandra/InsertSpan.java @@ -18,6 +18,7 @@ import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.ResultSetFuture; import com.datastax.driver.core.Session; +import com.datastax.driver.core.querybuilder.Insert; import com.datastax.driver.core.querybuilder.QueryBuilder; import com.google.auto.value.AutoValue; import java.util.Collections; @@ -71,11 +72,11 @@ final class InsertSpan extends ResultSetFutureCall { static class Factory { final Session session; final PreparedStatement preparedStatement; - final boolean strictTraceId; + final boolean strictTraceId, indexingEnabled; - Factory(Session session, boolean strictTraceId) { + Factory(Session session, boolean strictTraceId, boolean indexingEnabled) { this.session = session; - this.preparedStatement = session.prepare(QueryBuilder.insertInto(TABLE_SPAN) + Insert insertQuery = QueryBuilder.insertInto(TABLE_SPAN) .value("trace_id", QueryBuilder.bindMarker("trace_id")) .value("trace_id_high", QueryBuilder.bindMarker("trace_id_high")) .value("ts_uuid", QueryBuilder.bindMarker("ts_uuid")) @@ -86,14 +87,20 @@ static class Factory { .value("ts", QueryBuilder.bindMarker("ts")) .value("duration", QueryBuilder.bindMarker("duration")) .value("l_ep", QueryBuilder.bindMarker("l_ep")) - .value("l_service", QueryBuilder.bindMarker("l_service")) .value("r_ep", QueryBuilder.bindMarker("r_ep")) .value("annotations", QueryBuilder.bindMarker("annotations")) .value("tags", QueryBuilder.bindMarker("tags")) .value("shared", QueryBuilder.bindMarker("shared")) - .value("debug", QueryBuilder.bindMarker("debug")) - .value("annotation_query", QueryBuilder.bindMarker("annotation_query"))); + .value("debug", QueryBuilder.bindMarker("debug")); + + if (indexingEnabled) { + insertQuery.value("l_service", QueryBuilder.bindMarker("l_service")); + insertQuery.value("annotation_query", QueryBuilder.bindMarker("annotation_query")); + } + + this.preparedStatement = session.prepare(insertQuery); this.strictTraceId = strictTraceId; + this.indexingEnabled = indexingEnabled; } Input newInput(zipkin2.Span span, UUID ts_uuid) { @@ -106,7 +113,7 @@ Input newInput(zipkin2.Span span, UUID ts_uuid) { } else { annotations = Collections.emptyList(); } - String annotation_query = CassandraUtil.annotationQuery(span); + String annotation_query = indexingEnabled ? CassandraUtil.annotationQuery(span): null; return new AutoValue_InsertSpan_Input( ts_uuid, traceIdHigh ? span.traceId().substring(0, 16) : null, @@ -178,15 +185,18 @@ Call create(Input span) { if (null != input.ts()) bound.setLong("ts", input.ts()); if (null != input.duration()) bound.setLong("duration", input.duration()); if (null != input.l_ep()) bound.set("l_ep", input.l_ep(), EndpointUDT.class); - if (null != input.l_ep()) bound.setString("l_service", input.l_ep().getService()); if (null != input.r_ep()) bound.set("r_ep", input.r_ep(), EndpointUDT.class); if (!input.annotations().isEmpty()) bound.setList("annotations", input.annotations()); if (!input.tags().isEmpty()) bound.setMap("tags", input.tags()); - if (null != input.annotation_query()) { - bound.setString("annotation_query", input.annotation_query()); - } if (input.shared()) bound.setBool("shared", true); if (input.debug()) bound.setBool("debug", true); + + if (factory.indexingEnabled) { + if (null != input.l_ep()) bound.setString("l_service", input.l_ep().getService()); + if (null != input.annotation_query()) { + bound.setString("annotation_query", input.annotation_query()); + } + } return factory.session.executeAsync(bound); } diff --git a/zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/InternalForTests.java b/zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/InternalForTests.java index 1a4fadf0528..5bd6c437edf 100644 --- a/zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/InternalForTests.java +++ b/zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/InternalForTests.java @@ -21,6 +21,7 @@ import com.google.common.util.concurrent.Uninterruptibles; import java.util.List; import java.util.concurrent.TimeUnit; +import org.junit.rules.TestName; import zipkin.DependencyLink; import zipkin2.storage.SpanConsumer; @@ -74,6 +75,11 @@ public static void blockWhileInFlight(CassandraStorage storage) { } } + public static String keyspace(TestName testName) { + String result = testName.getMethodName().toLowerCase(); + return result.length() <= 48 ? result : result.substring(result.length() - 48); + } + public static void dropKeyspace(Session session, String keyspace) { session.execute("DROP KEYSPACE IF EXISTS " + keyspace); assertThat(session.getCluster().getMetadata().getKeyspace(keyspace)).isNull(); diff --git a/zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integration/ITCassandraStorage.java b/zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integration/ITCassandraStorage.java index dc9ce96bb08..73dd2fc8f47 100644 --- a/zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integration/ITCassandraStorage.java +++ b/zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integration/ITCassandraStorage.java @@ -13,111 +13,43 @@ */ package zipkin2.storage.cassandra.integration; -import com.datastax.driver.core.Session; import org.junit.Before; import org.junit.ClassRule; import org.junit.Rule; import org.junit.experimental.runners.Enclosed; import org.junit.rules.TestName; import org.junit.runner.RunWith; +import zipkin2.storage.StorageComponent; import zipkin2.storage.cassandra.CassandraStorage; import zipkin2.storage.cassandra.CassandraStorageRule; -import zipkin2.storage.cassandra.InternalForTests; + +import static zipkin2.storage.cassandra.InternalForTests.dropKeyspace; +import static zipkin2.storage.cassandra.InternalForTests.keyspace; @RunWith(Enclosed.class) public class ITCassandraStorage { static CassandraStorageRule classRule() { - return new CassandraStorageRule("openzipkin/zipkin-cassandra:2.4.1", "test_zipkin3"); - } - - public static class DependenciesTest extends CassandraDependenciesTest { - @ClassRule public static CassandraStorageRule storage = classRule(); - @Rule public TestName testName = new TestName(); - - @Override protected String keyspace() { - return ITCassandraStorage.keyspace(testName); - } - - @Before @Override public void clear() { - InternalForTests.dropKeyspace(storage.session(), keyspace()); - } - - @Override protected CassandraStorage.Builder storageBuilder() { - return storage.computeStorageBuilder(); - } - } - - public static class SpanStoreTest extends CassandraSpanStoreTest { - @ClassRule public static CassandraStorageRule storage = classRule(); - @Rule public TestName testName = new TestName(); - - @Override protected String keyspace() { - return ITCassandraStorage.keyspace(testName); - } - - @Before @Override public void clear() { - InternalForTests.dropKeyspace(storage.session(), keyspace()); - } - - @Override protected CassandraStorage.Builder storageBuilder() { - return storage.computeStorageBuilder(); - } - } - - public static class SpanConsumerTest extends CassandraSpanConsumerTest { - @ClassRule public static CassandraStorageRule storage = classRule(); - @Rule public TestName testName = new TestName(); - - @Override protected String keyspace() { - return ITCassandraStorage.keyspace(testName); - } - - @Before public void clear() { - InternalForTests.dropKeyspace(storage.session(), keyspace()); - } - - @Override protected CassandraStorage.Builder storageBuilder() { - return storage.computeStorageBuilder(); - } + return new CassandraStorageRule("openzipkin/zipkin-cassandra:2.4.1", "test_cassandra3"); } - public static class EnsureSchemaTest extends CassandraEnsureSchemaTest { - @ClassRule public static CassandraStorageRule storage = classRule(); + public static class ITIndexingEnabledFalse extends zipkin2.storage.ITIndexingEnabledFalse { + @ClassRule public static CassandraStorageRule backend = classRule(); @Rule public TestName testName = new TestName(); - @Override protected String keyspace() { - return ITCassandraStorage.keyspace(testName); - } - - @Before public void clear() { - InternalForTests.dropKeyspace(storage.session(), keyspace()); - } + CassandraStorage storage; - @Override protected Session session() { - return storage.session(); + @Before public void connect() { + storage = backend.computeStorageBuilder().keyspace(keyspace(testName)) + .indexingEnabled(false).build(); } - } - - public static class StrictTraceIdFalseTest extends CassandraStrictTraceIdFalseTest { - @ClassRule public static CassandraStorageRule storage = classRule(); - @Rule public TestName testName = new TestName(); - @Override protected String keyspace() { - return ITCassandraStorage.keyspace(testName); + @Override protected StorageComponent storage() { + return storage; } @Before @Override public void clear() { - InternalForTests.dropKeyspace(storage.session(), keyspace()); - } - - @Override protected CassandraStorage.Builder storageBuilder() { - return storage.computeStorageBuilder(); + dropKeyspace(backend.session(), keyspace(testName)); } } - - static String keyspace(TestName testName){ - String result = testName.getMethodName().toLowerCase(); - return result.length() <= 48 ? result : result.substring(result.length() - 48); - } } diff --git a/zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integration/CassandraDependenciesTest.java b/zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integrationV1/CassandraDependenciesTest.java similarity index 97% rename from zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integration/CassandraDependenciesTest.java rename to zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integrationV1/CassandraDependenciesTest.java index 4260eafea60..f51b2c73955 100644 --- a/zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integration/CassandraDependenciesTest.java +++ b/zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integrationV1/CassandraDependenciesTest.java @@ -11,7 +11,7 @@ * or implied. See the License for the specific language governing permissions and limitations under * the License. */ -package zipkin2.storage.cassandra.integration; +package zipkin2.storage.cassandra.integrationV1; import java.util.List; import org.junit.Before; diff --git a/zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integration/CassandraEnsureSchemaTest.java b/zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integrationV1/CassandraEnsureSchemaTest.java similarity index 97% rename from zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integration/CassandraEnsureSchemaTest.java rename to zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integrationV1/CassandraEnsureSchemaTest.java index 906e3b8e135..661bcbeb2af 100644 --- a/zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integration/CassandraEnsureSchemaTest.java +++ b/zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integrationV1/CassandraEnsureSchemaTest.java @@ -11,7 +11,7 @@ * or implied. See the License for the specific language governing permissions and limitations under * the License. */ -package zipkin2.storage.cassandra.integration; +package zipkin2.storage.cassandra.integrationV1; import com.datastax.driver.core.KeyspaceMetadata; import com.datastax.driver.core.Session; diff --git a/zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integration/CassandraSpanConsumerTest.java b/zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integrationV1/CassandraSpanConsumerTest.java similarity index 98% rename from zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integration/CassandraSpanConsumerTest.java rename to zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integrationV1/CassandraSpanConsumerTest.java index 64026d8e96a..fe3002d2b33 100644 --- a/zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integration/CassandraSpanConsumerTest.java +++ b/zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integrationV1/CassandraSpanConsumerTest.java @@ -11,7 +11,7 @@ * or implied. See the License for the specific language governing permissions and limitations under * the License. */ -package zipkin2.storage.cassandra.integration; +package zipkin2.storage.cassandra.integrationV1; import java.io.IOException; import java.util.stream.IntStream; diff --git a/zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integration/CassandraSpanStoreTest.java b/zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integrationV1/CassandraSpanStoreTest.java similarity index 98% rename from zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integration/CassandraSpanStoreTest.java rename to zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integrationV1/CassandraSpanStoreTest.java index 84a4ceca271..010e0672951 100644 --- a/zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integration/CassandraSpanStoreTest.java +++ b/zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integrationV1/CassandraSpanStoreTest.java @@ -11,7 +11,7 @@ * or implied. See the License for the specific language governing permissions and limitations under * the License. */ -package zipkin2.storage.cassandra.integration; +package zipkin2.storage.cassandra.integrationV1; import java.util.ArrayList; import java.util.List; diff --git a/zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integrationV1/CassandraStrictTraceIdFalseTest.java b/zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integrationV1/CassandraStrictTraceIdFalseTest.java new file mode 100644 index 00000000000..894e7d77dd8 --- /dev/null +++ b/zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integrationV1/CassandraStrictTraceIdFalseTest.java @@ -0,0 +1,57 @@ +/** + * Copyright 2015-2017 The OpenZipkin Authors + * + * Licensed 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. + */ +package zipkin2.storage.cassandra.integrationV1; + +import java.util.List; +import org.junit.Before; +import org.junit.Test; +import zipkin.Span; +import zipkin.internal.V2StorageComponent; +import zipkin.storage.StorageComponent; +import zipkin.storage.StrictTraceIdFalseTest; +import zipkin2.storage.cassandra.CassandraStorage; + +import static org.assertj.core.api.Assertions.assertThat; + +abstract class CassandraStrictTraceIdFalseTest extends StrictTraceIdFalseTest { + + abstract protected String keyspace(); + + private CassandraStorage storage; + private V2StorageComponent storageBeforeSwitch; + + @Before public void connect() { + storage = storageBuilder().strictTraceId(false).keyspace(keyspace()).build(); + storageBeforeSwitch = V2StorageComponent.create(storageBuilder().keyspace(keyspace()).build()); + } + + protected abstract CassandraStorage.Builder storageBuilder(); + + @Override protected final StorageComponent storage() { + return V2StorageComponent.create(storage); + } + + /** Ensures we can still lookup fully 128-bit traces when strict trace ID id disabled */ + @Test public void getTraces_128BitTraceId() { + getTraces_128BitTraceId(accept128BitTrace(storageBeforeSwitch)); + } + + /** Ensures data written before strict trace ID was enabled can be read */ + @Test public void getTrace_retrievesBy128BitTraceId_afterSwitch() { + List trace = accept128BitTrace(storageBeforeSwitch); + + assertThat(store().getRawTrace(trace.get(0).traceIdHigh, trace.get(0).traceId)) + .containsOnlyElementsOf(trace); + } +} diff --git a/zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integrationV1/ITCassandraStorageV1.java b/zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integrationV1/ITCassandraStorageV1.java new file mode 100644 index 00000000000..c81f569fd7f --- /dev/null +++ b/zipkin-storage/zipkin2_cassandra/src/test/java/zipkin2/storage/cassandra/integrationV1/ITCassandraStorageV1.java @@ -0,0 +1,121 @@ +/** + * Copyright 2015-2017 The OpenZipkin Authors + * + * Licensed 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. + */ +package zipkin2.storage.cassandra.integrationV1; + +import com.datastax.driver.core.Session; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.experimental.runners.Enclosed; +import org.junit.rules.TestName; +import org.junit.runner.RunWith; +import zipkin2.storage.cassandra.CassandraStorage; +import zipkin2.storage.cassandra.CassandraStorageRule; +import zipkin2.storage.cassandra.InternalForTests; + +import static zipkin2.storage.cassandra.InternalForTests.dropKeyspace; + +@RunWith(Enclosed.class) +public class ITCassandraStorageV1 { + + static CassandraStorageRule classRule() { + return new CassandraStorageRule("openzipkin/zipkin-cassandra:2.4.1", + "test_cassandra3_zipkinv1"); + } + + public static class DependenciesTest extends CassandraDependenciesTest { + @ClassRule public static CassandraStorageRule storage = classRule(); + @Rule public TestName testName = new TestName(); + + @Override protected String keyspace() { + return InternalForTests.keyspace(testName); + } + + @Before @Override public void clear() { + dropKeyspace(storage.session(), keyspace()); + } + + @Override protected CassandraStorage.Builder storageBuilder() { + return storage.computeStorageBuilder(); + } + } + + public static class SpanStoreTest extends CassandraSpanStoreTest { + @ClassRule public static CassandraStorageRule storage = classRule(); + @Rule public TestName testName = new TestName(); + + @Override protected String keyspace() { + return InternalForTests.keyspace(testName); + } + + @Before @Override public void clear() { + dropKeyspace(storage.session(), keyspace()); + } + + @Override protected CassandraStorage.Builder storageBuilder() { + return storage.computeStorageBuilder(); + } + } + + public static class SpanConsumerTest extends CassandraSpanConsumerTest { + @ClassRule public static CassandraStorageRule storage = classRule(); + @Rule public TestName testName = new TestName(); + + @Override protected String keyspace() { + return InternalForTests.keyspace(testName); + } + + @Before public void clear() { + dropKeyspace(storage.session(), keyspace()); + } + + @Override protected CassandraStorage.Builder storageBuilder() { + return storage.computeStorageBuilder(); + } + } + + public static class EnsureSchemaTest extends CassandraEnsureSchemaTest { + @ClassRule public static CassandraStorageRule storage = classRule(); + @Rule public TestName testName = new TestName(); + + @Override protected String keyspace() { + return InternalForTests.keyspace(testName); + } + + @Before public void clear() { + dropKeyspace(storage.session(), keyspace()); + } + + @Override protected Session session() { + return storage.session(); + } + } + + public static class StrictTraceIdFalseTest extends CassandraStrictTraceIdFalseTest { + @ClassRule public static CassandraStorageRule storage = classRule(); + @Rule public TestName testName = new TestName(); + + @Override protected String keyspace() { + return InternalForTests.keyspace(testName); + } + + @Before @Override public void clear() { + InternalForTests.dropKeyspace(storage.session(), keyspace()); + } + + @Override protected CassandraStorage.Builder storageBuilder() { + return storage.computeStorageBuilder(); + } + } +} diff --git a/zipkin2/src/main/java/zipkin2/storage/InMemoryStorage.java b/zipkin2/src/main/java/zipkin2/storage/InMemoryStorage.java index 4e87f18315f..810a3fa9ccb 100644 --- a/zipkin2/src/main/java/zipkin2/storage/InMemoryStorage.java +++ b/zipkin2/src/main/java/zipkin2/storage/InMemoryStorage.java @@ -72,7 +72,7 @@ public static Builder newBuilder() { } public static final class Builder extends StorageComponent.Builder { - boolean strictTraceId = true; + boolean strictTraceId = true, indexingEnabled = true; int maxSpanCount = 500000; /** {@inheritDoc} */ @@ -81,6 +81,11 @@ public static final class Builder extends StorageComponent.Builder { return this; } + @Override public Builder indexingEnabled(boolean indexingEnabled) { + this.indexingEnabled = indexingEnabled; + return this; + } + /** Eldest traces are removed to ensure spans in memory don't exceed this value */ public Builder maxSpanCount(int maxSpanCount) { if (maxSpanCount <= 0) throw new IllegalArgumentException("maxSpanCount <= 0"); @@ -122,12 +127,13 @@ public Builder maxSpanCount(int maxSpanCount) { } }; - final boolean strictTraceId; + final boolean strictTraceId, indexingEnabled; final int maxSpanCount; volatile int acceptedSpanCount; InMemoryStorage(Builder builder) { this.strictTraceId = builder.strictTraceId; + this.indexingEnabled = builder.indexingEnabled; this.maxSpanCount = builder.maxSpanCount; } @@ -151,6 +157,7 @@ public synchronized void clear() { traceIdToTraceIdTimeStamps.put(lowTraceId, traceIdTimeStamp); acceptedSpanCount++; + if (!indexingEnabled) continue; String spanName = span.name(); if (span.localServiceName() != null) { serviceToTraceIds.put(span.localServiceName(), lowTraceId); @@ -197,8 +204,10 @@ private int deleteOldestTrace() { Collection spans = spansByTraceIdTimeStamp.remove(traceIdTimeStamp); spansEvicted += spans.size(); } - for (String orphanedService : serviceToTraceIds.removeServiceIfTraceId(lowTraceId)) { - serviceToSpanNames.remove(orphanedService); + if (indexingEnabled) { + for (String orphanedService : serviceToTraceIds.removeServiceIfTraceId(lowTraceId)) { + serviceToSpanNames.remove(orphanedService); + } } return spansEvicted; } @@ -258,6 +267,8 @@ public synchronized List> getTraces() { } Set traceIdsDescendingByTimestamp(QueryRequest request) { + if (!indexingEnabled) return Collections.emptySet(); + Collection traceIdTimestamps = request.serviceName() != null ? traceIdTimestampsByServiceName(request.serviceName()) : spansByTraceIdTimeStamp.keySet(); @@ -292,11 +303,12 @@ Set traceIdsDescendingByTimestamp(QueryRequest request) { } @Override public synchronized Call> getServiceNames() { + if (!indexingEnabled) return Call.emptyList(); return Call.create(new ArrayList<>(serviceToTraceIds.keySet())); } @Override public synchronized Call> getSpanNames(String service) { - if (service.isEmpty()) return Call.emptyList(); + if (service.isEmpty() || !indexingEnabled) return Call.emptyList(); service = service.toLowerCase(Locale.ROOT); // service names are always lowercase! return Call.create(new ArrayList<>(serviceToSpanNames.get(service))); } diff --git a/zipkin2/src/main/java/zipkin2/storage/QueryRequest.java b/zipkin2/src/main/java/zipkin2/storage/QueryRequest.java index ac581cf4d03..8f1b0be8488 100644 --- a/zipkin2/src/main/java/zipkin2/storage/QueryRequest.java +++ b/zipkin2/src/main/java/zipkin2/storage/QueryRequest.java @@ -22,9 +22,9 @@ import java.util.Locale; import java.util.Map; import java.util.Set; -import zipkin2.internal.Nullable; import zipkin2.Annotation; import zipkin2.Span; +import zipkin2.internal.Nullable; /** * Invoking this request retrieves traces matching the below filters. @@ -39,7 +39,6 @@ */ @AutoValue public abstract class QueryRequest { - /** * When present, corresponds to {@link zipkin2.Endpoint#serviceName} and constrains all other * parameters. diff --git a/zipkin2/src/main/java/zipkin2/storage/StorageComponent.java b/zipkin2/src/main/java/zipkin2/storage/StorageComponent.java index 02329a2d393..c1746946a73 100644 --- a/zipkin2/src/main/java/zipkin2/storage/StorageComponent.java +++ b/zipkin2/src/main/java/zipkin2/storage/StorageComponent.java @@ -73,6 +73,18 @@ public static abstract class Builder { */ public abstract Builder strictTraceId(boolean strictTraceId); + /** + * False is an attempt to disable indexing, leaving only {@link SpanStore#getTrace(String)} + * supported. For example, query requests will be disabled. + * + * The use case is typically to support 100% sampled data, or when traces are searched using + * alternative means such as a logging index. + * + *

Refer to implementation docs for the impact of this parameter. Operations that use indexes + * should return empty as opposed to throwing an exception. + */ + public abstract Builder indexingEnabled(boolean indexingEnabled); + public abstract StorageComponent build(); } } diff --git a/zipkin2/src/test/java/zipkin2/TestObjects.java b/zipkin2/src/test/java/zipkin2/TestObjects.java index 1facaccaabe..ee56f25fff4 100644 --- a/zipkin2/src/test/java/zipkin2/TestObjects.java +++ b/zipkin2/src/test/java/zipkin2/TestObjects.java @@ -56,9 +56,9 @@ public static long midnightUTC(long epochMillis) { .kind(Span.Kind.CLIENT) .localEndpoint(FRONTEND) .remoteEndpoint(BACKEND) - .timestamp(1472470996199000L) - .duration(207000L) - .addAnnotation(1472470996238000L, "foo") + .timestamp((TODAY - 207) * 1000L) + .duration(207 * 1000L) + .addAnnotation((TODAY - 100) * 1000L, "foo") .putTag("http.path", "/api") .putTag("clnt/finagle.version", "6.45.0") .build(); diff --git a/zipkin2/src/test/java/zipkin2/storage/ITInMemoryStorage.java b/zipkin2/src/test/java/zipkin2/storage/ITInMemoryStorage.java new file mode 100644 index 00000000000..6193a2a9d32 --- /dev/null +++ b/zipkin2/src/test/java/zipkin2/storage/ITInMemoryStorage.java @@ -0,0 +1,46 @@ +/** + * Copyright 2015-2017 The OpenZipkin Authors + * + * Licensed 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. + */ +package zipkin2.storage; + +import java.io.IOException; +import org.junit.experimental.runners.Enclosed; +import org.junit.runner.RunWith; + +@RunWith(Enclosed.class) +public class ITInMemoryStorage { + + public static class ITSpanStore extends zipkin2.storage.ITSpanStore { + InMemoryStorage storage = InMemoryStorage.newBuilder().build(); + + @Override protected InMemoryStorage storage() { + return storage; + } + + @Override public void clear() throws IOException { + // no need.. the test rule does this + } + } + + public static class ITIndexingEnabledFalse extends zipkin2.storage.ITIndexingEnabledFalse { + InMemoryStorage storage = InMemoryStorage.newBuilder().indexingEnabled(false).build(); + + @Override protected InMemoryStorage storage() { + return storage; + } + + @Override public void clear() throws IOException { + // no need.. the test rule does this + } + } +} diff --git a/zipkin2/src/test/java/zipkin2/storage/ITIndexingEnabledFalse.java b/zipkin2/src/test/java/zipkin2/storage/ITIndexingEnabledFalse.java new file mode 100644 index 00000000000..6494d6736af --- /dev/null +++ b/zipkin2/src/test/java/zipkin2/storage/ITIndexingEnabledFalse.java @@ -0,0 +1,82 @@ +/** + * Copyright 2015-2017 The OpenZipkin Authors + * + * Licensed 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. + */ +package zipkin2.storage; + +import java.io.IOException; +import org.junit.Before; +import org.junit.Test; +import zipkin2.Span; + +import static java.util.Arrays.asList; +import static org.assertj.core.api.Assertions.assertThat; +import static zipkin2.TestObjects.CLIENT_SPAN; +import static zipkin2.storage.ITSpanStore.requestBuilder; + +/** + * Base test for when {@link StorageComponent.Builder#indexingEnabled(boolean) indexingEnabled == + * false}. + * + *

Subtypes should create a connection to a real backend, even if that backend is in-process. + */ +public abstract class ITIndexingEnabledFalse { + + /** Should maintain state between multiple calls within a test. */ + protected abstract StorageComponent storage(); + + protected SpanStore store() { + return storage().spanStore(); + } + + /** Clears store between tests. */ + @Before public abstract void clear() throws Exception; + + @Test public void getTraces_indexDataReturnsNothing() throws Exception { + accept(CLIENT_SPAN); + + assertThat(store().getTraces(requestBuilder() + .build()).execute()).isEmpty(); + + assertThat(store().getTraces(requestBuilder() + .serviceName(CLIENT_SPAN.localServiceName()) + .build()).execute()).isEmpty(); + + assertThat(store().getTraces(requestBuilder() + .spanName(CLIENT_SPAN.name()) + .build()).execute()).isEmpty(); + + assertThat(store().getTraces(requestBuilder() + .annotationQuery(CLIENT_SPAN.tags()) + .build()).execute()).isEmpty(); + + assertThat(store().getTraces(requestBuilder() + .minDuration(CLIENT_SPAN.duration()) + .build()).execute()).isEmpty(); + } + + @Test public void getSpanNames_isEmpty() throws Exception { + accept(CLIENT_SPAN); + + assertThat(store().getSpanNames(CLIENT_SPAN.name()).execute()).isEmpty(); + } + + @Test public void getServiceNames_isEmpty() throws Exception { + accept(CLIENT_SPAN); + + assertThat(store().getServiceNames().execute()).isEmpty(); + } + + protected void accept(Span... spans) throws IOException { + storage().spanConsumer().accept(asList(spans)).execute(); + } +} diff --git a/zipkin2/src/test/java/zipkin2/storage/ITSpanStore.java b/zipkin2/src/test/java/zipkin2/storage/ITSpanStore.java new file mode 100644 index 00000000000..9208cf60a39 --- /dev/null +++ b/zipkin2/src/test/java/zipkin2/storage/ITSpanStore.java @@ -0,0 +1,183 @@ +/** + * Copyright 2015-2017 The OpenZipkin Authors + * + * Licensed 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. + */ +package zipkin2.storage; + +import java.io.IOException; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; +import org.junit.Before; +import org.junit.Test; +import zipkin2.Endpoint; +import zipkin2.Span; + +import static java.util.Arrays.asList; +import static org.assertj.core.api.Assertions.assertThat; +import static zipkin2.TestObjects.CLIENT_SPAN; +import static zipkin2.TestObjects.DAY; +import static zipkin2.TestObjects.TODAY; + +/** + * Base test for {@link SpanStore}. + * + *

Subtypes should create a connection to a real backend, even if that backend is in-process. + */ +public abstract class ITSpanStore { + + /** Should maintain state between multiple calls within a test. */ + protected abstract StorageComponent storage(); + + protected SpanStore store() { + return storage().spanStore(); + } + + /** Clears store between tests. */ + @Before public abstract void clear() throws Exception; + + @Test public void getTraces_filteringMatchesMostRecentTraces() throws Exception { + List endpoints = IntStream.rangeClosed(1, 10) + .mapToObj(i -> Endpoint.newBuilder().serviceName("service" + i).ip("127.0.0.1").build()) + .collect(Collectors.toList()); + + long gapBetweenSpans = 100; + Span[] earlySpans = + IntStream.rangeClosed(1, 10).mapToObj(i -> Span.newBuilder().name("early") + .traceId(Integer.toHexString(i)).id(Integer.toHexString(i)) + .timestamp((TODAY - i) * 1000).duration(1L) + .localEndpoint(endpoints.get(i - 1)).build()).toArray(Span[]::new); + + Span[] lateSpans = IntStream.rangeClosed(1, 10).mapToObj(i -> Span.newBuilder().name("late") + .traceId(Integer.toHexString(i + 10)).id(Integer.toHexString(i + 10)) + .timestamp((TODAY + gapBetweenSpans - i) * 1000).duration(1L) + .localEndpoint(endpoints.get(i - 1)).build()).toArray(Span[]::new); + + accept(earlySpans); + accept(lateSpans); + + List[] earlyTraces = + Stream.of(earlySpans).map(Collections::singletonList).toArray(List[]::new); + List[] lateTraces = + Stream.of(lateSpans).map(Collections::singletonList).toArray(List[]::new); + + assertThat(store().getTraces(requestBuilder().build()).execute()) + .hasSize(20); + + assertThat(store().getTraces(requestBuilder() + .limit(10).build()).execute()) + .containsExactly(lateTraces); + + assertThat(store().getTraces(requestBuilder() + .endTs(TODAY + gapBetweenSpans).lookback(gapBetweenSpans).build()).execute()) + .containsExactly(lateTraces); + + assertThat(store().getTraces(requestBuilder() + .endTs(TODAY).build()).execute()) + .containsExactly(earlyTraces); + } + + @Test public void getTraces_localServiceName() throws Exception { + accept(CLIENT_SPAN); + + assertThat(store().getTraces(requestBuilder() + .serviceName(CLIENT_SPAN.localServiceName() + 1) + .build()).execute()).isEmpty(); + + assertThat(store().getTraces(requestBuilder() + .serviceName(CLIENT_SPAN.localServiceName()) + .build()).execute()).flatExtracting(l -> l).contains(CLIENT_SPAN); + } + + @Test public void getTraces_spanName() throws Exception { + accept(CLIENT_SPAN); + + assertThat(store().getTraces(requestBuilder() + .spanName(CLIENT_SPAN.name() + 1) + .build()).execute()).isEmpty(); + + assertThat(store().getTraces(requestBuilder() + .spanName(CLIENT_SPAN.name()) + .build()).execute()).flatExtracting(l -> l).contains(CLIENT_SPAN); + } + + @Test public void getTraces_tags() throws Exception { + accept(CLIENT_SPAN); + + assertThat(store().getTraces(requestBuilder() + .annotationQuery(Collections.singletonMap("foo", "bar")) + .build()).execute()).isEmpty(); + + assertThat(store().getTraces(requestBuilder() + .annotationQuery(CLIENT_SPAN.tags()) + .build()).execute()).flatExtracting(l -> l).contains(CLIENT_SPAN); + } + + @Test public void getTraces_minDuration() throws Exception { + accept(CLIENT_SPAN); + + assertThat(store().getTraces(requestBuilder() + .minDuration(CLIENT_SPAN.duration() + 1) + .build()).execute()).isEmpty(); + + assertThat(store().getTraces(requestBuilder() + .minDuration(CLIENT_SPAN.duration()) + .build()).execute()).flatExtracting(l -> l).contains(CLIENT_SPAN); + } + + @Test public void getTraces_maxDuration() throws Exception { + accept(CLIENT_SPAN); + + assertThat(store().getTraces(requestBuilder() + .minDuration(CLIENT_SPAN.duration() - 2) + .maxDuration(CLIENT_SPAN.duration() - 1) + .build()).execute()).isEmpty(); + + assertThat(store().getTraces(requestBuilder() + .minDuration(CLIENT_SPAN.duration()) + .maxDuration(CLIENT_SPAN.duration()) + .build()).execute()).flatExtracting(l -> l).contains(CLIENT_SPAN); + } + + @Test public void getSpanNames() throws Exception { + assertThat(store().getSpanNames(CLIENT_SPAN.localServiceName()).execute()) + .isEmpty(); + + accept(CLIENT_SPAN); + + assertThat(store().getSpanNames(CLIENT_SPAN.localServiceName() + 1).execute()) + .isEmpty(); + + assertThat(store().getSpanNames(CLIENT_SPAN.localServiceName()).execute()) + .contains(CLIENT_SPAN.name()); + } + + @Test public void getServiceNames_includesLocalServiceName() throws Exception { + assertThat(store().getServiceNames().execute()) + .isEmpty(); + + accept(CLIENT_SPAN); + + assertThat(store().getServiceNames().execute()) + .contains(CLIENT_SPAN.localServiceName()); + } + + protected void accept(Span... spans) throws IOException { + storage().spanConsumer().accept(asList(spans)).execute(); + } + + static QueryRequest.Builder requestBuilder() { + return QueryRequest.newBuilder().endTs(TODAY + DAY).lookback(DAY * 2).limit(100); + } +} diff --git a/zipkin2/src/test/java/zipkin2/storage/InMemoryStorageTest.java b/zipkin2/src/test/java/zipkin2/storage/InMemoryStorageTest.java index f8d67c27068..a5f6337535a 100644 --- a/zipkin2/src/test/java/zipkin2/storage/InMemoryStorageTest.java +++ b/zipkin2/src/test/java/zipkin2/storage/InMemoryStorageTest.java @@ -23,13 +23,13 @@ import zipkin2.DependencyLink; import zipkin2.Endpoint; import zipkin2.Span; -import zipkin2.TestObjects; import static java.util.Arrays.asList; import static java.util.stream.Collectors.toList; import static org.assertj.core.api.Assertions.assertThat; import static zipkin2.TestObjects.CLIENT_SPAN; import static zipkin2.TestObjects.TODAY; +import static zipkin2.storage.ITSpanStore.requestBuilder; public class InMemoryStorageTest { InMemoryStorage storage = InMemoryStorage.newBuilder().build(); @@ -122,9 +122,4 @@ public class InMemoryStorageTest { "root" ); } - - static QueryRequest.Builder requestBuilder() { - return QueryRequest.newBuilder().endTs(TODAY + TestObjects.DAY).lookback( - TestObjects.DAY * 2).limit(100); - } }