Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ subprojects {
apply plugin: "java-library"
}

project(":polaris-eclipselink") {
apply plugin: "java-library"
}

dependencies {
implementation(platform("com.fasterxml.jackson:jackson-bom:${jacksonVersion}"))
implementation("com.fasterxml.jackson.core:jackson-annotations")
Expand Down
1 change: 1 addition & 0 deletions extension/persistence/eclipselink/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ dependencies {
implementation(project(":polaris-service"))
implementation("org.eclipse.persistence:eclipselink:4.0.3")
implementation("io.dropwizard:dropwizard-jackson:${dropwizardVersion}")
implementation("com.h2database:h2:2.2.224")

testImplementation("com.h2database:h2:2.2.224")
testImplementation(testFixtures(project(":polaris-core")))
Expand Down
5 changes: 1 addition & 4 deletions polaris-server.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ featureConfiguration:
- AZURE
- FILE


# Whether we want to enable Snowflake OAuth locally. Setting this to true requires
# that you go through the setup outlined in the `README.md` file, specifically the
# `OAuth + Snowflake: Local Testing And Then Some` section
Expand All @@ -88,7 +87,7 @@ defaultRealms:
- default-realm

metaStoreManager:
type: in-memory
type: eclipse-link

# TODO - avoid duplicating token broker config
oauth2:
Expand Down Expand Up @@ -126,7 +125,6 @@ cors:
# Logging settings.

logging:

# The default level of all loggers. Can be OFF, ERROR, WARN, INFO, DEBUG, TRACE, or ALL.
level: INFO

Expand All @@ -136,7 +134,6 @@ logging:
io.polaris: DEBUG

appenders:

- type: console
# If true, write log statements to stdout.
# enabled: true
Expand Down
10 changes: 10 additions & 0 deletions polaris-service/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ plugins {

dependencies {
implementation(project(":polaris-core"))
runtimeOnly(project(":polaris-eclipselink"))

implementation(platform("org.apache.iceberg:iceberg-bom:${icebergVersion}"))
implementation("org.apache.iceberg:iceberg-api")
Expand Down Expand Up @@ -193,6 +194,15 @@ task runApp(type: JavaExec) {
args "server", "$rootDir/polaris-server.yml"
}

task runBootstrap(type: JavaExec) {
if (System.getenv("AWS_REGION") == null) {
environment "AWS_REGION", "us-west-2"
}
classpath = sourceSets.main.runtimeClasspath
mainClass = "io.polaris.service.PolarisApplication"
args "bootstrap", "$rootDir/polaris-server.yml"
}

application {
mainClass = "io.polaris.service.PolarisApplication"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,45 +114,45 @@ public static void main(final String[] args) throws Exception {
}

private static void printAsciiArt() {
String bannerArt =
String.join(
"\n",
" @@@@ @@@ @ @ @@@@ @ @@@@ @@@@ @ @@@@@ @ @ @@@ @@@@ ",
" @ @ @ @ @ @ @ @ @ @ @@ @ @ @ @ @ @ @ @ @ @ ",
" @@@@ @ @ @ @@@@@ @@@@ @ @@ @ @@@@@ @ @@@@@ @ @ @ @ @@@",
" @ @@@ @@@@ @ @ @ @@ @ @@@@ @@@@ @ @ @ @@ @@ @@@@ @@@ @@@@ ",
" ",
" ",
" ",
" ",
" /////| ",
" //||///T||| ",
" ///|||////|||||| ",
" //||||T////||||||||| ",
" /T| //|||||T///T||//T|||||| ",
" //|||/////T||////||/////||||||| //|| ",
" //||||||T///////////////////T|||||||T||||| ",
" //||||/////T|//////////|///////T|||||T|||||||| ",
" //|||||/////|||T////////////////||||||/||||||||| ",
",,..,,,..,,,..,//||||////////||||||||||/////////|||||///||||||||||,,,..,,..,,,..,,,.",
",,..,,,..,,,..,,,..,,,..,,,..,,,..,,,..,,,..,,,..,,,..,,,..,,,..,,,..,,,.,,,..,,,..,");
String bannerArt = String.join(
"\n",
" @@@@ @@@ @ @ @@@@ @ @@@@ @@@@ @ @@@@@ @ @ @@@ @@@@ ",
" @ @ @ @ @ @ @ @ @ @ @@ @ @ @ @ @ @ @ @ @ @ ",
" @@@@ @ @ @ @@@@@ @@@@ @ @@ @ @@@@@ @ @@@@@ @ @ @ @ @@@",
" @ @@@ @@@@ @ @ @ @@ @ @@@@ @@@@ @ @ @ @@ @@ @@@@ @@@ @@@@ ",
" ",
" ",
" ",
" ",
" /////| ",
" //||///T||| ",
" ///|||////|||||| ",
" //||||T////||||||||| ",
" /T| //|||||T///T||//T|||||| ",
" //|||/////T||////||/////||||||| //|| ",
" //||||||T///////////////////T|||||||T||||| ",
" //||||/////T|//////////|///////T|||||T|||||||| ",
" //|||||/////|||T////////////////||||||/||||||||| ",
",,..,,,..,,,..,//||||////////||||||||||/////////|||||///||||||||||,,,..,,..,,,..,,,.",
",,..,,,..,,,..,,,..,,,..,,,..,,,..,,,..,,,..,,,..,,,..,,,..,,,..,,,..,,,.,,,..,,,..,");
System.out.println(bannerArt.replaceAll("\\|", "\\\\"));
}

@Override
public void initialize(Bootstrap<PolarisApplicationConfig> bootstrap) {
// Enable variable substitution with environment variables
EnvironmentVariableSubstitutor substitutor = new EnvironmentVariableSubstitutor(false);
SubstitutingSourceProvider provider =
new SubstitutingSourceProvider(bootstrap.getConfigurationSourceProvider(), substitutor);
SubstitutingSourceProvider provider = new SubstitutingSourceProvider(bootstrap.getConfigurationSourceProvider(),
substitutor);
bootstrap.setConfigurationSourceProvider(provider);

bootstrap.addCommand(new BootstrapRealmsCommand());
}

@Override
public void run(PolarisApplicationConfig configuration, Environment environment) {
// PolarisEntityManager will be used for Management APIs and optionally the core Catalog APIs
// PolarisEntityManager will be used for Management APIs and optionally the core
// Catalog APIs
// depending on the value of the baseCatalogType config.
MetaStoreManagerFactory metaStoreManagerFactory = configuration.getMetaStoreManagerFactory();
StsClientBuilder stsClientBuilder = StsClient.builder();
Expand All @@ -163,8 +163,8 @@ public void run(PolarisApplicationConfig configuration, Environment environment)
metaStoreManagerFactory.setStorageIntegrationProvider(
new PolarisStorageIntegrationProviderImpl(stsClientBuilder::build));

PolarisMetricRegistry polarisMetricRegistry =
new PolarisMetricRegistry(new PrometheusMeterRegistry(PrometheusConfig.DEFAULT));
PolarisMetricRegistry polarisMetricRegistry = new PolarisMetricRegistry(
new PrometheusMeterRegistry(PrometheusConfig.DEFAULT));
metaStoreManagerFactory.setMetricRegistry(polarisMetricRegistry);

OpenTelemetry openTelemetry = setupTracing();
Expand All @@ -175,8 +175,7 @@ public void run(PolarisApplicationConfig configuration, Environment environment)
if (metaStoreManagerFactory instanceof ConfigurationStoreAware) {
((ConfigurationStoreAware) metaStoreManagerFactory).setConfigurationStore(configurationStore);
}
RealmEntityManagerFactory entityManagerFactory =
new RealmEntityManagerFactory(metaStoreManagerFactory);
RealmEntityManagerFactory entityManagerFactory = new RealmEntityManagerFactory(metaStoreManagerFactory);
CallContextResolver callContextResolver = configuration.getCallContextResolver();
callContextResolver.setEntityManagerFactory(entityManagerFactory);
if (callContextResolver instanceof ConfigurationStoreAware csa) {
Expand All @@ -192,8 +191,7 @@ public void run(PolarisApplicationConfig configuration, Environment environment)
.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");

TaskHandlerConfiguration taskConfig = configuration.getTaskHandler();
TaskExecutorImpl taskExecutor =
new TaskExecutorImpl(taskConfig.executorService(), metaStoreManagerFactory);
TaskExecutorImpl taskExecutor = new TaskExecutorImpl(taskConfig.executorService(), metaStoreManagerFactory);
TaskFileIOSupplier fileIOSupplier = new TaskFileIOSupplier(metaStoreManagerFactory);
taskExecutor.addTaskHandler(
new TableCleanupTaskHandler(taskExecutor, metaStoreManagerFactory, fileIOSupplier));
Expand All @@ -219,13 +217,11 @@ public void run(PolarisApplicationConfig configuration, Environment environment)
}

PolarisAuthorizer authorizer = new PolarisAuthorizer(configurationStore);
IcebergCatalogAdapter catalogAdapter =
new IcebergCatalogAdapter(catalogFactory, entityManagerFactory, authorizer);
IcebergCatalogAdapter catalogAdapter = new IcebergCatalogAdapter(catalogFactory, entityManagerFactory, authorizer);
environment.jersey().register(new IcebergRestCatalogApi(catalogAdapter));
environment.jersey().register(new IcebergRestConfigurationApi(catalogAdapter));

FilterRegistration.Dynamic corsRegistration =
environment.servlets().addFilter("CORS", CrossOriginFilter.class);
FilterRegistration.Dynamic corsRegistration = environment.servlets().addFilter("CORS", CrossOriginFilter.class);
corsRegistration.setInitParameter(
CrossOriginFilter.ALLOWED_ORIGINS_PARAM,
String.join(",", configuration.getCorsConfiguration().getAllowedOrigins()));
Expand All @@ -252,14 +248,13 @@ public void run(PolarisApplicationConfig configuration, Environment environment)
.servlets()
.addFilter("tracing", new TracingFilter(openTelemetry))
.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
DiscoverableAuthenticator<String, AuthenticatedPolarisPrincipal> authenticator =
configuration.getPolarisAuthenticator();
DiscoverableAuthenticator<String, AuthenticatedPolarisPrincipal> authenticator = configuration
.getPolarisAuthenticator();
authenticator.setEntityManagerFactory(entityManagerFactory);
AuthFilter<String, AuthenticatedPolarisPrincipal> oauthCredentialAuthFilter =
new OAuthCredentialAuthFilter.Builder<AuthenticatedPolarisPrincipal>()
.setAuthenticator(authenticator)
.setPrefix("Bearer")
.buildAuthFilter();
AuthFilter<String, AuthenticatedPolarisPrincipal> oauthCredentialAuthFilter = new OAuthCredentialAuthFilter.Builder<AuthenticatedPolarisPrincipal>()
.setAuthenticator(authenticator)
.setPrefix("Bearer")
.buildAuthFilter();
environment.jersey().register(new AuthDynamicFeature(oauthCredentialAuthFilter));
environment.healthChecks().register("polaris", new PolarisHealthCheck());
OAuth2ApiService oauth2Service = configuration.getOauth2Service();
Expand Down Expand Up @@ -299,27 +294,28 @@ public void run(PolarisApplicationConfig configuration, Environment environment)
.getPrometheusRegistry()))
.addMapping("/metrics");

// For in-memory metastore we need to bootstrap Service and Service principal at startup (for
// For in-memory metastore we need to bootstrap Service and Service principal at
// startup (for
// default realm)
// We can not utilize dropwizard Bootstrap command as command and server will be running two
// We can not utilize dropwizard Bootstrap command as command and server will be
// running two
// different processes
// and in-memory state will be lost b/w invocation of bootstrap command and running a server
// and in-memory state will be lost b/w invocation of bootstrap command and
// running a server
if (metaStoreManagerFactory instanceof InMemoryPolarisMetaStoreManagerFactory) {
metaStoreManagerFactory.getOrCreateMetaStoreManager(configuration::getDefaultRealm);
}
}

private static OpenTelemetry setupTracing() {
Resource resource =
Resource.getDefault().toBuilder()
.put(ServiceAttributes.SERVICE_NAME, "polaris")
.put(ServiceAttributes.SERVICE_VERSION, "0.1.0")
.build();
SdkTracerProvider sdkTracerProvider =
SdkTracerProvider.builder()
.addSpanProcessor(SimpleSpanProcessor.create(LoggingSpanExporter.create()))
.setResource(resource)
.build();
Resource resource = Resource.getDefault().toBuilder()
.put(ServiceAttributes.SERVICE_NAME, "polaris")
.put(ServiceAttributes.SERVICE_VERSION, "0.1.0")
.build();
SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder()
.addSpanProcessor(SimpleSpanProcessor.create(LoggingSpanExporter.create()))
.setResource(resource)
.build();
return OpenTelemetrySdk.builder()
.setTracerProvider(sdkTracerProvider)
.setPropagators(
Expand All @@ -329,7 +325,10 @@ private static OpenTelemetry setupTracing() {
.build();
}

/** Resolves and sets ThreadLocal CallContext/RealmContext based on the request contents. */
/**
* Resolves and sets ThreadLocal CallContext/RealmContext based on the request
* contents.
*/
private static class ContextResolverFilter implements Filter {
private final RealmContextResolver realmContextResolver;
private final CallContextResolver callContextResolver;
Expand All @@ -345,37 +344,31 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
Stream<String> headerNames = Collections.list(httpRequest.getHeaderNames()).stream();
Map<String, String> headers =
headerNames.collect(Collectors.toMap(Function.identity(), httpRequest::getHeader));
RealmContext currentRealmContext =
realmContextResolver.resolveRealmContext(
httpRequest.getRequestURL().toString(),
httpRequest.getMethod(),
httpRequest.getRequestURI().substring(1),
request.getParameterMap().entrySet().stream()
.collect(
Collectors.toMap(Map.Entry::getKey, (e) -> ((String[]) e.getValue())[0])),
headers);
CallContext currentCallContext =
callContextResolver.resolveCallContext(
currentRealmContext,
httpRequest.getMethod(),
httpRequest.getRequestURI().substring(1),
request.getParameterMap().entrySet().stream()
.collect(
Collectors.toMap(Map.Entry::getKey, (e) -> ((String[]) e.getValue())[0])),
headers);
Map<String, String> headers = headerNames.collect(Collectors.toMap(Function.identity(), httpRequest::getHeader));
RealmContext currentRealmContext = realmContextResolver.resolveRealmContext(
httpRequest.getRequestURL().toString(),
httpRequest.getMethod(),
httpRequest.getRequestURI().substring(1),
request.getParameterMap().entrySet().stream()
.collect(
Collectors.toMap(Map.Entry::getKey, (e) -> ((String[]) e.getValue())[0])),
headers);
CallContext currentCallContext = callContextResolver.resolveCallContext(
currentRealmContext,
httpRequest.getMethod(),
httpRequest.getRequestURI().substring(1),
request.getParameterMap().entrySet().stream()
.collect(
Collectors.toMap(Map.Entry::getKey, (e) -> ((String[]) e.getValue())[0])),
headers);
CallContext.setCurrentContext(currentCallContext);
try (MDC.MDCCloseable context =
MDC.putCloseable("realm", currentRealmContext.getRealmIdentifier());
MDC.MDCCloseable requestId =
MDC.putCloseable("request_id", httpRequest.getHeader("request_id"))) {
try (MDC.MDCCloseable context = MDC.putCloseable("realm", currentRealmContext.getRealmIdentifier());
MDC.MDCCloseable requestId = MDC.putCloseable("request_id", httpRequest.getHeader("request_id"))) {
chain.doFilter(request, response);
} finally {
Object contextCatalog =
currentCallContext
.contextVariables()
.get(CallContext.REQUEST_PATH_CATALOG_INSTANCE_KEY);
Object contextCatalog = currentCallContext
.contextVariables()
.get(CallContext.REQUEST_PATH_CATALOG_INSTANCE_KEY);
if (contextCatalog != null && contextCatalog instanceof Closeable) {
((Closeable) contextCatalog).close();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">

<persistence-unit name="polaris-dev" transaction-type="RESOURCE_LOCAL">
<persistence-unit name="polaris" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>io.polaris.core.persistence.models.ModelEntity</class>
<class>io.polaris.core.persistence.models.ModelEntityActive</class>
Expand Down