Skip to content

Commit 5936c9d

Browse files
committed
NoSQL persistence
1 parent 6f28c70 commit 5936c9d

File tree

452 files changed

+43092
-39
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

452 files changed

+43092
-39
lines changed

LICENSE

+3
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,9 @@ This product includes code from Project Nessie.
304304
* tools/config-docs/generator/src/test/java/tests/smallrye/SomeEnum.java
305305
* tools/config-docs/generator/src/test/java/tests/smallrye/VeryNested.java
306306

307+
Code underneath the components/persistence directory, especially pluggable object types, index related, cache,
308+
atomic commit logic and fundamental persistence implementations.
309+
307310
Copyright: Copyright 2015-2025 Dremio Corporation
308311
Home page: https://projectnessie.org/
309312
License: https://www.apache.org/licenses/LICENSE-2.0

bom/build.gradle.kts

+34
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,40 @@ dependencies {
4343
api(project(":polaris-idgen-impl"))
4444
api(project(":polaris-idgen-spi"))
4545

46+
api(project(":polaris-nodes-api"))
47+
api(project(":polaris-nodes-impl"))
48+
api(project(":polaris-nodes-spi"))
49+
api(project(":polaris-nodes-store"))
50+
51+
api(project(":polaris-realms-api"))
52+
api(project(":polaris-realms-impl"))
53+
api(project(":polaris-realms-spi"))
54+
api(project(":polaris-realms-store"))
55+
56+
api(project(":polaris-authz-api"))
57+
api(project(":polaris-authz-impl"))
58+
api(project(":polaris-authz-spi"))
59+
api(project(":polaris-authz-store"))
60+
61+
api(project(":polaris-persistence-api"))
62+
api(project(":polaris-persistence-impl"))
63+
api(project(":polaris-persistence-benchmark"))
64+
api(project(":polaris-persistence-bridge"))
65+
api(project(":polaris-persistence-cache"))
66+
api(project(":polaris-persistence-cdi-common"))
67+
api(project(":polaris-persistence-cdi-quarkus"))
68+
api(project(":polaris-persistence-cdi-weld"))
69+
api(project(":polaris-persistence-commits"))
70+
api(project(":polaris-persistence-correctness"))
71+
api(project(":polaris-persistence-delegate"))
72+
api(project(":polaris-persistence-index"))
73+
api(project(":polaris-persistence-standalone"))
74+
api(project(":polaris-persistence-testextension"))
75+
api(project(":polaris-persistence-types"))
76+
77+
api(project(":polaris-persistence-inmemory"))
78+
api(project(":polaris-persistence-mongodb"))
79+
4680
api(project(":polaris-config-docs-annotations"))
4781
api(project(":polaris-config-docs-generator"))
4882

build.gradle.kts

+4
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ tasks.named<RatTask>("rat").configure {
7272
// Manifest files do not allow comments
7373
excludes.add("tools/version/src/jarTest/resources/META-INF/FAKE_MANIFEST.MF")
7474

75+
excludes.add(
76+
"nosql/persistence/index/src/testFixtures/resources/org/apache/polaris/persistence/indexes/words.gz"
77+
)
78+
7579
excludes.add("ide-name.txt")
7680
excludes.add("version.txt")
7781
excludes.add(".git")

gradle/libs.versions.toml

+5
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ swagger = "1.6.15"
3737
# If a dependency is removed, check whether the LICENSE and/or NOTICE files need to be adopted
3838
# (aka mention of the dependency removed).
3939
#
40+
agrona = { module = "org.agrona:agrona", version = "2.1.0" }
4041
antlr4-runtime = { module = "org.antlr:antlr4-runtime", version.strictly = "4.9.3" } # spark integration tests
4142
assertj-core = { module = "org.assertj:assertj-core", version = "3.27.3" }
4243
auth0-jwt = { module = "com.auth0:java-jwt", version = "4.5.0" }
@@ -47,6 +48,7 @@ caffeine = { module = "com.github.ben-manes.caffeine:caffeine", version = "3.2.0
4748
commons-codec1 = { module = "commons-codec:commons-codec", version = "1.18.0" }
4849
commons-lang3 = { module = "org.apache.commons:commons-lang3", version = "3.17.0" }
4950
commons-text = { module = "org.apache.commons:commons-text", version = "1.13.0" }
51+
docker-java-api = { module = "com.github.docker-java:docker-java-api", version = "3.5.0" }
5052
eclipselink = { module = "org.eclipse.persistence:eclipselink", version = "4.0.5" }
5153
errorprone = { module = "com.google.errorprone:error_prone_core", version = "2.37.0" }
5254
google-cloud-storage-bom = { module = "com.google.cloud:google-cloud-storage-bom", version = "2.50.0" }
@@ -79,7 +81,9 @@ logback-classic = { module = "ch.qos.logback:logback-classic", version = "1.5.18
7981
micrometer-bom = { module = "io.micrometer:micrometer-bom", version = "1.14.5" }
8082
mockito-core = { module = "org.mockito:mockito-core", version = "5.17.0" }
8183
mockito-junit-jupiter = { module = "org.mockito:mockito-junit-jupiter", version = "5.17.0" }
84+
mongodb-driver-sync = { module = "org.mongodb:mongodb-driver-sync", version = "5.4.0" }
8285
opentelemetry-bom = { module = "io.opentelemetry:opentelemetry-bom", version = "1.49.0" }
86+
opentelemetry-instrumentation-bom-alpha = { module = "io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha", version= "2.14.0-alpha" }
8387
opentelemetry-semconv = { module = "io.opentelemetry.semconv:opentelemetry-semconv", version = "1.32.0" }
8488
picocli = { module = "info.picocli:picocli-codegen", version.ref = "picocli" }
8589
picocli-codegen = { module = "info.picocli:picocli-codegen", version.ref = "picocli" }
@@ -92,6 +96,7 @@ s3mock-testcontainers = { module = "com.adobe.testing:s3mock-testcontainers", ve
9296
slf4j-api = { module = "org.slf4j:slf4j-api", version.ref = "slf4j" }
9397
smallrye-common-annotation = { module = "io.smallrye.common:smallrye-common-annotation", version = "2.11.0" }
9498
smallrye-config-core = { module = "io.smallrye.config:smallrye-config-core", version = "3.12.4" }
99+
smallrye-jandex = { module = "io.smallrye:jandex", version = "3.2.7" }
95100
spark35-sql-scala212 = { module = "org.apache.spark:spark-sql_2.12", version.ref = "spark35" }
96101
spotbugs-annotations = { module = "com.github.spotbugs:spotbugs-annotations", version = "4.9.3" }
97102
swagger-annotations = { module = "io.swagger:swagger-annotations", version.ref = "swagger" }

gradle/projects.main.properties

+36-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ polaris-immutables=tools/immutables
3939
polaris-container-spec-helper=tools/container-spec-helper
4040
polaris-version=tools/version
4141
polaris-misc-types=tools/misc-types
42-
polaris-persistence-varint=nosql/persistence/varint
4342

4443
polaris-config-docs-annotations=tools/config-docs/annotations
4544
polaris-config-docs-generator=tools/config-docs/generator
@@ -52,4 +51,40 @@ polaris-async-vertx=nosql/async/vertx
5251
# id generation
5352
polaris-idgen-api=nosql/idgen/api
5453
polaris-idgen-impl=nosql/idgen/impl
54+
polaris-idgen-mocks=nosql/idgen/mocks
5555
polaris-idgen-spi=nosql/idgen/spi
56+
# nodes
57+
polaris-nodes-api=nosql/nodes/api
58+
polaris-nodes-impl=nosql/nodes/impl
59+
polaris-nodes-spi=nosql/nodes/spi
60+
polaris-nodes-store=nosql/nodes/store
61+
# realms
62+
polaris-realms-api=nosql/realms/api
63+
polaris-realms-impl=nosql/realms/impl
64+
polaris-realms-spi=nosql/realms/spi
65+
polaris-realms-store=nosql/realms/store
66+
# authz
67+
polaris-authz-api=nosql/authz/api
68+
polaris-authz-impl=nosql/authz/impl
69+
polaris-authz-spi=nosql/authz/spi
70+
polaris-authz-store=nosql/authz/store
71+
# persistence / database agnostic
72+
polaris-persistence-api=nosql/persistence/api
73+
polaris-persistence-impl=nosql/persistence/impl
74+
polaris-persistence-benchmark=nosql/persistence/benchmark
75+
polaris-persistence-bridge=nosql/persistence/bridge
76+
polaris-persistence-cache=nosql/persistence/cache
77+
polaris-persistence-cdi-common=nosql/persistence/cdi/common
78+
polaris-persistence-cdi-quarkus=nosql/persistence/cdi/quarkus
79+
polaris-persistence-cdi-weld=nosql/persistence/cdi/weld
80+
polaris-persistence-commits=nosql/persistence/commits
81+
polaris-persistence-correctness=nosql/persistence/correctness
82+
polaris-persistence-delegate=nosql/persistence/delegate
83+
polaris-persistence-index=nosql/persistence/index
84+
polaris-persistence-standalone=nosql/persistence/standalone
85+
polaris-persistence-testextension=nosql/persistence/testextension
86+
polaris-persistence-types=nosql/persistence/types
87+
polaris-persistence-varint=nosql/persistence/varint
88+
# persistence / database specific implementations
89+
polaris-persistence-inmemory=nosql/persistence/db/inmemory
90+
polaris-persistence-mongodb=nosql/persistence/db/mongodb

nosql/async/java/src/main/java/org/apache/polaris/async/java/JavaPoolAsyncExec.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
* Java thread pool to execute blocking task.
5252
*/
5353
@ApplicationScoped
54-
class JavaPoolAsyncExec implements AsyncExec {
54+
public class JavaPoolAsyncExec implements AsyncExec {
5555
private static final Logger LOGGER = LoggerFactory.getLogger(JavaPoolAsyncExec.class.getName());
5656

5757
private final ThreadPoolExecutor executorService;

nosql/authz/README.md

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<!--
2+
Licensed to the Apache Software Foundation (ASF) under one
3+
or more contributor license agreements. See the NOTICE file
4+
distributed with this work for additional information
5+
regarding copyright ownership. The ASF licenses this file
6+
to you under the Apache License, Version 2.0 (the
7+
"License"); you may not use this file except in compliance
8+
with the License. You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing,
13+
software distributed under the License is distributed on an
14+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
KIND, either express or implied. See the License for the
16+
specific language governing permissions and limitations
17+
under the License.
18+
-->
19+
20+
# AuthZ framework with pluggable privileges
21+
22+
Provides a framework and implementations pluggable privileges and privilege checks.
23+
24+
## Privileges
25+
26+
A privilege is globally identified by its name. Privileges can be inheritable (from its parents) or not. Multiple
27+
privileges can be grouped together to a _composite_ privilege (think: `ALL_DML` having `SELECT`, `INSERT`, `UPDATE` and
28+
`DELETE`) - a composite privilege matches, if all its individual privileges match. Multiple privileges can also be
29+
grouped to an _alternative_ privilege, which matches if any of its individual privileges matches.
30+
31+
Available privileges are provided by one or more `PrivilegeProvider`s, which are discovered at runtime.
32+
Note: currently there is only one `ProvilegeProvider` that plugs in the Polaris privileges.
33+
34+
## ACLs, ACL entries and ACL chains
35+
36+
Each securable object can have its own ACL. ACLs consist of ACL entries, which define the _granted_ and _restricted_
37+
privileges by role name. The the number of roles is technically unbounded and the number of ACL entries can become
38+
quite large.
39+
40+
This framework implements [separation of duties](https://en.wikipedia.org/wiki/Separation_of_duties) ("SoD"), which is a
41+
quite demanded functionality not just by large(r) user organizations. TL;DR _SoD_ allows "security administrators" to
42+
grant and revoke privileges to other users, but not leverage those privileges themselves.
43+
44+
The _effective_ set of privileges for a specific operation performed by a specific caller needs to be computed against
45+
the target objects and their parents. _ACL chains_ are the vehicle to model this hierarchy and let the implementation
46+
compute the set of _effective_ privileges based on the individual ACLs and roles.
47+
48+
Note: Privilege checks and _SoD_ are currently not performed via this framework.
49+
50+
## Jackson support & Storage friendly representation
51+
52+
The persistable types `Acl`, `AclEntry`, and `PrivilegeSet` can all be serialized using Jackson.
53+
54+
As the number of ACL entries can become quite large, space efficient serialization is quite important. The
55+
implementation uses bit-set encoding when serializing `PrivilegeSet`s for persistence.
56+
57+
## Code structure
58+
59+
The code is structured into multiple modules. Consuming code should almost always pull in only the API module.
60+
61+
* `polaris-authz-api` provides the necessary Java interfaces and immutable types.
62+
* `polaris-authz-impl` provides the storage agnostic implementation.
63+
* `polaris-authz-spi` provides the necessary interfaces to provide custom privileges and storage implementation.
64+
* `polaris-authz-store` provides the storage implementation based on `polaris-persistence-api`.

nosql/authz/api/build.gradle.kts

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
plugins {
21+
alias(libs.plugins.jandex)
22+
id("polaris-server")
23+
}
24+
25+
description = "Polaris AuthZ API"
26+
27+
dependencies {
28+
implementation(libs.guava)
29+
30+
implementation(platform(libs.jackson.bom))
31+
implementation("com.fasterxml.jackson.core:jackson-databind")
32+
33+
compileOnly(libs.jakarta.annotation.api)
34+
compileOnly(libs.jakarta.validation.api)
35+
compileOnly(libs.jakarta.inject.api)
36+
compileOnly(libs.jakarta.enterprise.cdi.api)
37+
38+
compileOnly(project(":polaris-immutables"))
39+
annotationProcessor(project(":polaris-immutables", configuration = "processor"))
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.polaris.authz.api;
20+
21+
import com.google.errorprone.annotations.CanIgnoreReturnValue;
22+
import jakarta.annotation.Nonnull;
23+
import java.util.Set;
24+
import java.util.function.BiConsumer;
25+
import java.util.function.Consumer;
26+
27+
public interface Acl {
28+
29+
void entriesForRoleIds(
30+
@Nonnull Set<String> roleIds, @Nonnull Consumer<AclEntry> aclEntryConsumer);
31+
32+
void forEach(@Nonnull BiConsumer<String, AclEntry> consumer);
33+
34+
interface AclBuilder {
35+
@CanIgnoreReturnValue
36+
AclBuilder from(@Nonnull Acl instance);
37+
38+
@CanIgnoreReturnValue
39+
AclBuilder addEntry(@Nonnull String roleId, @Nonnull AclEntry entry);
40+
41+
@CanIgnoreReturnValue
42+
AclBuilder removeEntry(@Nonnull String roleId);
43+
44+
/**
45+
* Add, remove or update an {@linkplain AclEntry ACL entry} for a role.
46+
*
47+
* <p>The {@linkplain Consumer consumer} is called with an empty builder, if no ACL entry for
48+
* the role exists, otherwise with a builder constructed from the existing entry. If the given
49+
* {@linkplain Consumer consumer} removes all privileges from the ACL entry, the ACL entry will
50+
* be removed.
51+
*/
52+
@CanIgnoreReturnValue
53+
AclBuilder modify(@Nonnull String roleId, @Nonnull Consumer<AclEntry.AclEntryBuilder> entry);
54+
55+
Acl build();
56+
}
57+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.polaris.authz.api;
20+
21+
import java.util.Optional;
22+
import org.apache.polaris.immutables.PolarisImmutable;
23+
import org.immutables.value.Value;
24+
25+
/** Container for an {@linkplain Acl ACL} of an individual entity and a pointer to its parent. */
26+
@PolarisImmutable
27+
public interface AclChain {
28+
@Value.Parameter(order = 1)
29+
Acl acl();
30+
31+
@Value.Parameter(order = 2)
32+
Optional<AclChain> parent();
33+
34+
static AclChain aclChain(Acl acl, Optional<AclChain> parent) {
35+
return ImmutableAclChain.of(acl, parent);
36+
}
37+
}

0 commit comments

Comments
 (0)