Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
3 changes: 3 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,9 @@ This product includes code from Project Nessie.
* helm/polaris/templates/servicemonitor.yaml
* helm/polaris/templates/storage.yaml

Code underneath the components/persistence directory, especially pluggable object types, index related, cache,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

components/persistence does not exist in the current main 🤔 Shall we list individual files (as above)?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jbonofre : WDYT?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hard to name "individual files", as it's only inspired. But I see this causes confusion. Removing this from the PR.

atomic commit logic and fundamental persistence implementations.

Copyright: Copyright 2015-2025 Dremio Corporation
Home page: https://projectnessie.org/
License: https://www.apache.org/licenses/LICENSE-2.0
1 change: 1 addition & 0 deletions bom/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ dependencies {
api(project(":polaris-persistence-nosql-benchmark"))
api(project(":polaris-persistence-nosql-correctness"))
api(project(":polaris-persistence-nosql-cdi-common"))
api(project(":polaris-persistence-nosql-cdi-quarkus"))
api(project(":polaris-persistence-nosql-cdi-quarkus-distcache"))
api(project(":polaris-persistence-nosql-cdi-weld"))
api(project(":polaris-persistence-nosql-standalone"))
Expand Down
1 change: 1 addition & 0 deletions gradle/projects.main.properties
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ polaris-persistence-nosql-impl=persistence/nosql/persistence/impl
polaris-persistence-nosql-benchmark=persistence/nosql/persistence/benchmark
polaris-persistence-nosql-correctness=persistence/nosql/persistence/correctness
polaris-persistence-nosql-cdi-common=persistence/nosql/persistence/cdi/common
polaris-persistence-nosql-cdi-quarkus=persistence/nosql/persistence/cdi/quarkus
polaris-persistence-nosql-cdi-quarkus-distcache=persistence/nosql/persistence/cdi/quarkus-distcache
polaris-persistence-nosql-cdi-weld=persistence/nosql/persistence/cdi/weld
polaris-persistence-nosql-standalone=persistence/nosql/persistence/standalone
Expand Down
66 changes: 66 additions & 0 deletions persistence/nosql/persistence/cdi/quarkus/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* 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.
*/

plugins {
id("org.kordamp.gradle.jandex")
id("polaris-server")
}

description = "Polaris NoSQL persistence, providers for Quarkus."

dependencies {
implementation(project(":polaris-persistence-nosql-cdi-common"))
implementation(project(":polaris-persistence-nosql-api"))
implementation(project(":polaris-persistence-nosql-inmemory"))
implementation(project(":polaris-persistence-nosql-mongodb"))
Comment thread
dimas-b marked this conversation as resolved.
implementation(project(":polaris-idgen-api"))
runtimeOnly(project(":polaris-nodes-impl"))
runtimeOnly(project(":polaris-nodes-store-nosql"))
runtimeOnly(project(":polaris-persistence-nosql-realms-impl"))
runtimeOnly(project(":polaris-persistence-nosql-realms-store-nosql"))
runtimeOnly(project(":polaris-async-vertx"))
runtimeOnly(project(":polaris-idgen-impl"))
runtimeOnly(project(":polaris-persistence-nosql-authz-impl"))
runtimeOnly(project(":polaris-persistence-nosql-authz-store-nosql"))

compileOnly(platform(libs.micrometer.bom))
compileOnly("io.micrometer:micrometer-core")
compileOnly(platform(libs.opentelemetry.instrumentation.bom.alpha))
compileOnly("io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations")

compileOnly(libs.smallrye.config.core)

compileOnly(project(":polaris-immutables"))
annotationProcessor(project(":polaris-immutables", configuration = "processor"))

implementation(platform(libs.quarkus.bom))
implementation("io.quarkus:quarkus-core")
implementation("io.quarkus:quarkus-mongodb-client")
runtimeOnly("io.quarkus:quarkus-micrometer")

implementation(libs.jakarta.ws.rs.api)

implementation(libs.guava)
implementation(libs.slf4j.api)

compileOnly(libs.jakarta.annotation.api)
compileOnly(libs.jakarta.validation.api)
compileOnly(libs.jakarta.inject.api)
compileOnly(libs.jakarta.enterprise.cdi.api)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* 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.polaris.persistence.nosql.quarkus.backend;

import org.apache.polaris.persistence.nosql.api.backend.Backend;

interface BackendBuilder {
Backend buildBackend();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* 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.polaris.persistence.nosql.quarkus.backend;

import static java.lang.String.format;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Any;
import jakarta.enterprise.inject.Instance;
import jakarta.enterprise.inject.Produces;
import java.util.Optional;
import org.apache.polaris.persistence.nosql.api.backend.Backend;
import org.apache.polaris.persistence.nosql.api.backend.BackendConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@ApplicationScoped
class BackendProvider {
private static final Logger LOGGER = LoggerFactory.getLogger(BackendProvider.class);

@Produces
@ApplicationScoped
@NotObserved
Backend backend(
BackendConfiguration backendConfiguration, @Any Instance<BackendBuilder> backendBuilders) {

var backendName =
backendConfiguration
.type()
.orElseThrow(
() ->
new IllegalStateException(
"Mandatory configuration option polaris.persistence.backend.type is missing!"));
Comment thread
singhpk234 marked this conversation as resolved.
Outdated

var backendBuilder = backendBuilders.select(BackendType.Literal.of(backendName));
if (!backendBuilder.isResolvable()) {
throw new IllegalStateException(
format(
"Backend '%s' provided in configuration polaris.persistence.backend.type is not available. Available backends: %s",
backendName,
backendBuilders
.handlesStream()
.map(
h ->
h.getBean().getQualifiers().stream()
.filter(q -> q instanceof BackendType)
.map(BackendType.class::cast)
.findFirst()
.map(BackendType::value))
.filter(Optional::isPresent)
.map(Optional::get)
.toList()));
}
if (backendBuilder.isAmbiguous()) {
throw new IllegalStateException(
format(
"Multiple implementations match the backend name '%s' provided in configuration polaris.persistence.backend.type is not available. All available backends: %s",
backendName,
backendBuilders
.handlesStream()
.map(
h ->
h.getBean().getQualifiers().stream()
.filter(q -> q instanceof BackendType)
.map(BackendType.class::cast)
.findFirst()
.map(BackendType::value))
.filter(Optional::isPresent)
.map(Optional::get)
.toList()));
}
var builder = backendBuilder.get();

var backend = builder.buildBackend();
try {
var setupSchemaResult = backend.setupSchema().orElse("");
LOGGER.info("Opened new persistence backend '{}' {}", backend.type(), setupSchemaResult);

return builder.buildBackend();
} catch (Exception e) {
try {
backend.close();
} catch (Exception e2) {
e.addSuppressed(e2);
}
throw e;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* 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.polaris.persistence.nosql.quarkus.backend;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import jakarta.enterprise.util.AnnotationLiteral;
import jakarta.inject.Qualifier;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

@Target({TYPE, METHOD, PARAMETER, FIELD})
@Retention(RUNTIME)
@Documented
@Qualifier
public @interface BackendType {
/** Gets the store type. */
String value();

/** Supports inline instantiation of the {@link BackendType} qualifier. */
final class Literal extends AnnotationLiteral<BackendType> implements BackendType {

private final String value;

private Literal(String value) {
this.value = value;
}

public static Literal of(String value) {
return new Literal(value);
}

@Override
public String value() {
return value;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* 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.polaris.persistence.nosql.quarkus.backend;

import jakarta.enterprise.context.ApplicationScoped;
import org.apache.polaris.persistence.nosql.api.backend.Backend;
import org.apache.polaris.persistence.nosql.inmemory.InMemoryBackendFactory;
import org.apache.polaris.persistence.nosql.inmemory.InMemoryConfiguration;

@BackendType(InMemoryBackendFactory.NAME)
@ApplicationScoped
class InMemoryBackendBuilder implements BackendBuilder {
@Override
public Backend buildBackend() {
var factory = new InMemoryBackendFactory();
return factory.buildBackend(factory.buildConfiguration(new InMemoryConfiguration() {}));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* 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.polaris.persistence.nosql.quarkus.backend;

import com.mongodb.client.MongoClient;
import io.quarkus.arc.Arc;
import io.quarkus.mongodb.runtime.MongoClientBeanUtil;
import io.quarkus.mongodb.runtime.MongoClients;
import jakarta.enterprise.context.Dependent;
import jakarta.inject.Inject;
import org.apache.polaris.persistence.nosql.api.backend.Backend;
import org.apache.polaris.persistence.nosql.mongodb.MongoDbBackendConfig;
import org.apache.polaris.persistence.nosql.mongodb.MongoDbBackendFactory;
import org.eclipse.microprofile.config.inject.ConfigProperty;

@BackendType(MongoDbBackendFactory.NAME)
@Dependent
class MongoDbBackendBuilder implements BackendBuilder {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to (re-)structure CDI objects in a way that will not mix multiple backends in the same general-purpose module?

I imagine when new backends are added, it would be preferable to keep their code isolated in their respective modules as much as possible.

In other words, is it possible to build a server with classes from just one particular backend implementation present on the class path?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, we can add quarkus-specific modules next to every backend. But that's way more work at this point.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough.

@Inject
@ConfigProperty(name = "quarkus.mongodb.database", defaultValue = "polaris")
String databaseName;

@Override
public Backend buildBackend() {
MongoClients mongoClients = Arc.container().instance(MongoClients.class).get();
MongoClient client =
mongoClients.createMongoClient(MongoClientBeanUtil.DEFAULT_MONGOCLIENT_NAME);

var config = new MongoDbBackendConfig(databaseName, client, true, false);

return new MongoDbBackendFactory().buildBackend(config);
}
}
Loading