blob: 0616dd2a3a342931ad052b62511d2df7abca3cdd [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF 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.
*/
package org.apache.druid.sql.calcite.schema;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Scopes;
import com.google.inject.TypeLiteral;
import com.google.inject.name.Names;
import org.apache.druid.client.FilteredServerInventoryView;
import org.apache.druid.client.TimelineServerView;
import org.apache.druid.client.coordinator.Coordinator;
import org.apache.druid.client.coordinator.CoordinatorClient;
import org.apache.druid.client.coordinator.NoopCoordinatorClient;
import org.apache.druid.client.indexing.IndexingService;
import org.apache.druid.client.indexing.NoopOverlordClient;
import org.apache.druid.discovery.DruidLeaderClient;
import org.apache.druid.discovery.DruidNodeDiscoveryProvider;
import org.apache.druid.guice.LazySingleton;
import org.apache.druid.guice.LifecycleModule;
import org.apache.druid.guice.annotations.Json;
import org.apache.druid.java.util.emitter.service.ServiceEmitter;
import org.apache.druid.query.lookup.LookupExtractorFactoryContainerProvider;
import org.apache.druid.query.lookup.LookupReferencesManager;
import org.apache.druid.rpc.indexing.OverlordClient;
import org.apache.druid.segment.join.JoinableFactory;
import org.apache.druid.segment.join.MapJoinableFactory;
import org.apache.druid.server.QueryLifecycleFactory;
import org.apache.druid.server.SegmentManager;
import org.apache.druid.server.security.AuthorizerMapper;
import org.apache.druid.server.security.Escalator;
import org.apache.druid.sql.calcite.planner.CatalogResolver;
import org.apache.druid.sql.calcite.planner.DruidOperatorTable;
import org.apache.druid.sql.calcite.planner.PlannerConfig;
import org.apache.druid.sql.calcite.util.CalciteTestBase;
import org.apache.druid.sql.calcite.view.ViewManager;
import org.easymock.EasyMock;
import org.easymock.EasyMockExtension;
import org.easymock.Mock;
import org.junit.Assert;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import java.util.Set;
import java.util.stream.Collectors;
@ExtendWith(EasyMockExtension.class)
public class DruidCalciteSchemaModuleTest extends CalciteTestBase
{
private static final String DRUID_SCHEMA_NAME = "druid";
@Mock
private QueryLifecycleFactory queryLifecycleFactory;
@Mock
private TimelineServerView serverView;
@Mock
private PlannerConfig plannerConfig;
@Mock
private ViewManager viewManager;
@Mock
private Escalator escalator;
@Mock
AuthorizerMapper authorizerMapper;
@Mock
private FilteredServerInventoryView serverInventoryView;
@Mock
private DruidLeaderClient coordinatorDruidLeaderClient;
@Mock
private DruidLeaderClient overlordDruidLeaderClient;
@Mock
private DruidNodeDiscoveryProvider druidNodeDiscoveryProvider;
@Mock
private ObjectMapper objectMapper;
@Mock
private LookupReferencesManager lookupReferencesManager;
@Mock
private SegmentManager segmentManager;
@Mock
private DruidOperatorTable druidOperatorTable;
private DruidCalciteSchemaModule target;
private Injector injector;
@BeforeEach
public void setUp()
{
EasyMock.replay(plannerConfig);
target = new DruidCalciteSchemaModule();
injector = Guice.createInjector(
binder -> {
binder.bind(QueryLifecycleFactory.class).toInstance(queryLifecycleFactory);
binder.bind(TimelineServerView.class).toInstance(serverView);
binder.bind(JoinableFactory.class).toInstance(new MapJoinableFactory(ImmutableSet.of(), ImmutableMap.of()));
binder.bind(PlannerConfig.class).toInstance(plannerConfig);
binder.bind(ViewManager.class).toInstance(viewManager);
binder.bind(Escalator.class).toInstance(escalator);
binder.bind(AuthorizerMapper.class).toInstance(authorizerMapper);
binder.bind(FilteredServerInventoryView.class).toInstance(serverInventoryView);
binder.bind(SegmentManager.class).toInstance(segmentManager);
binder.bind(DruidOperatorTable.class).toInstance(druidOperatorTable);
binder.bind(DruidLeaderClient.class)
.annotatedWith(Coordinator.class)
.toInstance(coordinatorDruidLeaderClient);
binder.bind(DruidLeaderClient.class)
.annotatedWith(IndexingService.class)
.toInstance(overlordDruidLeaderClient);
binder.bind(DruidNodeDiscoveryProvider.class).toInstance(druidNodeDiscoveryProvider);
binder.bind(DruidSchemaManager.class).toInstance(new NoopDruidSchemaManager());
binder.bind(ObjectMapper.class).annotatedWith(Json.class).toInstance(objectMapper);
binder.bindScope(LazySingleton.class, Scopes.SINGLETON);
binder.bind(LookupExtractorFactoryContainerProvider.class).toInstance(lookupReferencesManager);
binder.bind(CatalogResolver.class).toInstance(CatalogResolver.NULL_RESOLVER);
binder.bind(ServiceEmitter.class).toInstance(new ServiceEmitter("", "", null));
binder.bind(OverlordClient.class).to(NoopOverlordClient.class);
binder.bind(CoordinatorClient.class).to(NoopCoordinatorClient.class);
},
new LifecycleModule(),
target);
}
@Test
public void testDruidSchemaNameIsInjected()
{
String schemaName = injector.getInstance(Key.get(String.class, DruidSchemaName.class));
Assert.assertEquals(DRUID_SCHEMA_NAME, schemaName);
}
@Test
public void testDruidSqlSchemaIsInjectedAsSingleton()
{
NamedDruidSchema namedDruidSchema = injector.getInstance(NamedDruidSchema.class);
Assert.assertNotNull(namedDruidSchema);
NamedDruidSchema other = injector.getInstance(NamedDruidSchema.class);
Assert.assertSame(other, namedDruidSchema);
}
@Test
public void testSystemSqlSchemaIsInjectedAsSingleton()
{
NamedSystemSchema namedSystemSchema = injector.getInstance(NamedSystemSchema.class);
Assert.assertNotNull(namedSystemSchema);
NamedSystemSchema other = injector.getInstance(NamedSystemSchema.class);
Assert.assertSame(other, namedSystemSchema);
}
@Test
public void testDruidCalciteSchemasAreInjected()
{
Set<NamedSchema> sqlSchemas = injector.getInstance(Key.get(new TypeLiteral<Set<NamedSchema>>(){}));
Set<Class<? extends NamedSchema>> expectedSchemas =
ImmutableSet.of(NamedSystemSchema.class, NamedDruidSchema.class, NamedLookupSchema.class, NamedViewSchema.class);
Assert.assertEquals(expectedSchemas.size(), sqlSchemas.size());
Assert.assertEquals(
expectedSchemas,
sqlSchemas.stream().map(NamedSchema::getClass).collect(Collectors.toSet()));
}
@Test
public void testDruidSchemaIsInjectedAsSingleton()
{
DruidSchema schema = injector.getInstance(DruidSchema.class);
Assert.assertNotNull(schema);
DruidSchema other = injector.getInstance(DruidSchema.class);
Assert.assertSame(other, schema);
}
@Test
public void testSystemSchemaIsInjectedAsSingleton()
{
SystemSchema schema = injector.getInstance(SystemSchema.class);
Assert.assertNotNull(schema);
SystemSchema other = injector.getInstance(SystemSchema.class);
Assert.assertSame(other, schema);
}
@Test
public void testInformationSchemaIsInjectedAsSingleton()
{
InformationSchema schema = injector.getInstance(InformationSchema.class);
Assert.assertNotNull(schema);
InformationSchema other = injector.getInstance(InformationSchema.class);
Assert.assertSame(other, schema);
}
@Test
public void testLookupSchemaIsInjectedAsSingleton()
{
LookupSchema schema = injector.getInstance(LookupSchema.class);
Assert.assertNotNull(schema);
LookupSchema other = injector.getInstance(LookupSchema.class);
Assert.assertSame(other, schema);
}
@Test
public void testRootSchemaAnnotatedIsInjectedAsSingleton()
{
DruidSchemaCatalog rootSchema = injector.getInstance(
Key.get(DruidSchemaCatalog.class, Names.named(DruidCalciteSchemaModule.INCOMPLETE_SCHEMA))
);
Assert.assertNotNull(rootSchema);
DruidSchemaCatalog other = injector.getInstance(
Key.get(DruidSchemaCatalog.class, Names.named(DruidCalciteSchemaModule.INCOMPLETE_SCHEMA))
);
Assert.assertSame(other, rootSchema);
}
@Test
public void testRootSchemaIsInjectedAsSingleton()
{
DruidSchemaCatalog rootSchema = injector.getInstance(Key.get(DruidSchemaCatalog.class));
Assert.assertNotNull(rootSchema);
DruidSchemaCatalog other = injector.getInstance(
Key.get(DruidSchemaCatalog.class, Names.named(DruidCalciteSchemaModule.INCOMPLETE_SCHEMA))
);
Assert.assertSame(other, rootSchema);
}
@Test
public void testRootSchemaIsInjectedAndHasInformationSchema()
{
DruidSchemaCatalog rootSchema = injector.getInstance(Key.get(DruidSchemaCatalog.class));
InformationSchema expectedSchema = injector.getInstance(InformationSchema.class);
Assert.assertNotNull(rootSchema);
Assert.assertSame(expectedSchema, rootSchema.getSubSchema("INFORMATION_SCHEMA").unwrap(InformationSchema.class));
}
}