Skip to content

Commit 67d53ea

Browse files
committed
Add OSI semantic-model API scaffolding
Wire the Open Semantic Interchange (OSI) semantic-model REST endpoints behind the ENABLE_SEMANTIC_MODELS feature flag (default false until the implementation lands). - spec: semantic-models-api.yaml defining create/list/load/update/drop under namespaces, plus catalog-service wiring - generated models + API enabled in polaris-catalog-service build - feature flag, REST resource paths, and endpoint set - endpoints advertised in catalog config only when the flag is enabled - SemanticModelCatalogAdapter stub: feature-gated, returns 501 for every operation pending persistence/validation The document body carries an OSI `version` and the `semantic_model` serialized as a JSON string, stored verbatim. Update is last-writer-wins.
1 parent ac634c9 commit 67d53ea

9 files changed

Lines changed: 573 additions & 2 deletions

File tree

api/polaris-catalog-service/build.gradle.kts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,17 @@ val policyManagementModels =
4949
"ListPoliciesResponse",
5050
)
5151

52-
val models = (genericTableModels + policyManagementModels).joinToString(",")
52+
val semanticModelModels =
53+
listOf(
54+
"SemanticModelDocument",
55+
"SemanticModelIdentifier",
56+
"CreateSemanticModelRequest",
57+
"UpdateSemanticModelRequest",
58+
"LoadSemanticModelResponse",
59+
"ListSemanticModelsResponse",
60+
)
61+
62+
val models = (genericTableModels + policyManagementModels + semanticModelModels).joinToString(",")
5363

5464
dependencies {
5565
implementation(project(":polaris-core"))
@@ -101,7 +111,7 @@ openApiGenerate {
101111
ignoreFileOverride.set(provider { rootDir.file(".openapi-generator-ignore").asFile.absolutePath })
102112
removeOperationIdPrefix.set(true)
103113
templateDir.set(provider { templatesDir.asFile.absolutePath })
104-
globalProperties.put("apis", "GenericTableApi,PolicyApi")
114+
globalProperties.put("apis", "GenericTableApi,PolicyApi,SemanticModelApi")
105115
globalProperties.put("models", models)
106116
globalProperties.put("apiDocs", "false")
107117
globalProperties.put("modelTests", "false")

polaris-core/src/main/java/org/apache/polaris/core/config/FeatureConfiguration.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,13 @@ public static void enforceFeatureEnabledOrThrow(
372372
.defaultValue(true)
373373
.buildFeatureConfiguration();
374374

375+
public static final FeatureConfiguration<Boolean> ENABLE_SEMANTIC_MODELS =
376+
PolarisConfiguration.<Boolean>builder()
377+
.key("ENABLE_SEMANTIC_MODELS")
378+
.description("If true, the semantic-model (OSI) endpoints are enabled")
379+
.defaultValue(false) // keep it to false until the implementation is done
380+
.buildFeatureConfiguration();
381+
375382
public static final FeatureConfiguration<List<String>> SUPPORTED_CATALOG_CONNECTION_TYPES =
376383
PolarisConfiguration.<List<String>>builder()
377384
.key("SUPPORTED_CATALOG_CONNECTION_TYPES")

polaris-core/src/main/java/org/apache/polaris/core/rest/PolarisEndpoints.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,27 @@ public class PolarisEndpoints {
7373
.add(V1_GET_APPLICABLE_POLICIES)
7474
.build();
7575

76+
// Semantic model endpoints
77+
public static final Endpoint V1_LIST_SEMANTIC_MODELS =
78+
Endpoint.create("GET", PolarisResourcePaths.V1_SEMANTIC_MODELS);
79+
public static final Endpoint V1_CREATE_SEMANTIC_MODEL =
80+
Endpoint.create("POST", PolarisResourcePaths.V1_SEMANTIC_MODELS);
81+
public static final Endpoint V1_LOAD_SEMANTIC_MODEL =
82+
Endpoint.create("GET", PolarisResourcePaths.V1_SEMANTIC_MODEL);
83+
public static final Endpoint V1_UPDATE_SEMANTIC_MODEL =
84+
Endpoint.create("PUT", PolarisResourcePaths.V1_SEMANTIC_MODEL);
85+
public static final Endpoint V1_DROP_SEMANTIC_MODEL =
86+
Endpoint.create("DELETE", PolarisResourcePaths.V1_SEMANTIC_MODEL);
87+
88+
public static final Set<Endpoint> SEMANTIC_MODEL_ENDPOINTS =
89+
ImmutableSet.<Endpoint>builder()
90+
.add(V1_LIST_SEMANTIC_MODELS)
91+
.add(V1_CREATE_SEMANTIC_MODEL)
92+
.add(V1_LOAD_SEMANTIC_MODEL)
93+
.add(V1_UPDATE_SEMANTIC_MODEL)
94+
.add(V1_DROP_SEMANTIC_MODEL)
95+
.build();
96+
7697
/**
7798
* Get the generic table endpoints. Returns GENERIC_TABLE_ENDPOINTS if ENABLE_GENERIC_TABLES is
7899
* set to true, otherwise, returns an empty set.
@@ -92,4 +113,14 @@ public static Set<Endpoint> getSupportedPolicyEndpoints(RealmConfig realmConfig)
92113
boolean policyStoreEnabled = realmConfig.getConfig(FeatureConfiguration.ENABLE_POLICY_STORE);
93114
return policyStoreEnabled ? POLICY_STORE_ENDPOINTS : ImmutableSet.of();
94115
}
116+
117+
/**
118+
* Get the semantic model endpoints. Returns SEMANTIC_MODEL_ENDPOINTS if ENABLE_SEMANTIC_MODELS is
119+
* set to true, otherwise, returns an empty set.
120+
*/
121+
public static Set<Endpoint> getSupportedSemanticModelEndpoints(RealmConfig realmConfig) {
122+
boolean semanticModelsEnabled =
123+
realmConfig.getConfig(FeatureConfiguration.ENABLE_SEMANTIC_MODELS);
124+
return semanticModelsEnabled ? SEMANTIC_MODEL_ENDPOINTS : ImmutableSet.of();
125+
}
95126
}

polaris-core/src/main/java/org/apache/polaris/core/rest/PolarisResourcePaths.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ public class PolarisResourcePaths {
4242
"/polaris/v1/{prefix}/namespaces/{namespace}/policies/{policy-name}/mappings";
4343
public static final String V1_APPLICABLE_POLICIES = "/polaris/v1/{prefix}/applicable-policies";
4444

45+
// Semantic Model endpoints
46+
public static final String V1_SEMANTIC_MODELS =
47+
"/polaris/v1/{prefix}/namespaces/{namespace}/semantic-models";
48+
public static final String V1_SEMANTIC_MODEL =
49+
"/polaris/v1/{prefix}/namespaces/{namespace}/semantic-models/{semantic-model-name}";
50+
4551
private final String prefix;
4652

4753
public PolarisResourcePaths(String prefix) {

runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandler.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1446,6 +1446,7 @@ public ConfigResponse getConfig() {
14461446
.addAll(VIEW_ENDPOINTS)
14471447
.addAll(PolarisEndpoints.getSupportedGenericTableEndpoints(realmConfig()))
14481448
.addAll(PolarisEndpoints.getSupportedPolicyEndpoints(realmConfig()))
1449+
.addAll(PolarisEndpoints.getSupportedSemanticModelEndpoints(realmConfig()))
14491450
.build())
14501451
.build();
14511452
}
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
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.service.catalog.semanticmodel;
20+
21+
import jakarta.enterprise.context.RequestScoped;
22+
import jakarta.inject.Inject;
23+
import jakarta.ws.rs.core.Response;
24+
import jakarta.ws.rs.core.SecurityContext;
25+
import org.apache.polaris.core.config.FeatureConfiguration;
26+
import org.apache.polaris.core.config.RealmConfig;
27+
import org.apache.polaris.core.context.CallContext;
28+
import org.apache.polaris.core.context.RealmContext;
29+
import org.apache.polaris.service.catalog.api.PolarisCatalogSemanticModelApiService;
30+
import org.apache.polaris.service.catalog.common.CatalogAdapter;
31+
import org.apache.polaris.service.types.CreateSemanticModelRequest;
32+
import org.apache.polaris.service.types.UpdateSemanticModelRequest;
33+
34+
/**
35+
* Stub adapter for the OSI semantic-model API. The endpoints are wired and gated by {@link
36+
* FeatureConfiguration#ENABLE_SEMANTIC_MODELS}, but every operation returns {@code 501 Not
37+
* Implemented}. Persistence, validation, authorization, and source-link resolution land in
38+
* subsequent phases.
39+
*/
40+
@RequestScoped
41+
public class SemanticModelCatalogAdapter
42+
implements PolarisCatalogSemanticModelApiService, CatalogAdapter {
43+
44+
private final RealmConfig realmConfig;
45+
46+
@Inject
47+
public SemanticModelCatalogAdapter(CallContext callContext) {
48+
this.realmConfig = callContext.getRealmConfig();
49+
}
50+
51+
private void ensureEnabled() {
52+
FeatureConfiguration.enforceFeatureEnabledOrThrow(
53+
realmConfig, FeatureConfiguration.ENABLE_SEMANTIC_MODELS);
54+
}
55+
56+
private static Response notImplemented() {
57+
return Response.status(Response.Status.NOT_IMPLEMENTED).build();
58+
}
59+
60+
@Override
61+
public Response createSemanticModel(
62+
String prefix,
63+
String namespace,
64+
CreateSemanticModelRequest createSemanticModelRequest,
65+
RealmContext realmContext,
66+
SecurityContext securityContext) {
67+
ensureEnabled();
68+
// TODO: authorize the principal, validate the OSI document against the bundled OSI JSON Schema,
69+
// then persist a new semantic-model entity and return the stored document. Tracked for a
70+
// follow-up phase; returns 501 until persistence lands.
71+
return notImplemented();
72+
}
73+
74+
@Override
75+
public Response listSemanticModels(
76+
String prefix,
77+
String namespace,
78+
String pageToken,
79+
Integer pageSize,
80+
RealmContext realmContext,
81+
SecurityContext securityContext) {
82+
ensureEnabled();
83+
// TODO: authorize the principal, then page through the namespace's semantic-model entities and
84+
// return their identifiers. Tracked for a follow-up phase; returns 501 until persistence lands.
85+
return notImplemented();
86+
}
87+
88+
@Override
89+
public Response loadSemanticModel(
90+
String prefix,
91+
String namespace,
92+
String semanticModelName,
93+
RealmContext realmContext,
94+
SecurityContext securityContext) {
95+
ensureEnabled();
96+
// TODO: authorize the principal, then read and return the stored OSI document. Tracked for a
97+
// follow-up phase; returns 501 until persistence lands.
98+
return notImplemented();
99+
}
100+
101+
@Override
102+
public Response updateSemanticModel(
103+
String prefix,
104+
String namespace,
105+
String semanticModelName,
106+
UpdateSemanticModelRequest updateSemanticModelRequest,
107+
RealmContext realmContext,
108+
SecurityContext securityContext) {
109+
ensureEnabled();
110+
// TODO: authorize the principal, validate the OSI document, then replace the stored document
111+
// (last-writer-wins) and return it. Tracked for a follow-up phase; returns 501 until
112+
// persistence lands.
113+
return notImplemented();
114+
}
115+
116+
@Override
117+
public Response dropSemanticModel(
118+
String prefix,
119+
String namespace,
120+
String semanticModelName,
121+
RealmContext realmContext,
122+
SecurityContext securityContext) {
123+
ensureEnabled();
124+
// TODO: authorize the principal, then delete the semantic-model entity. Tracked for a follow-up
125+
// phase; returns 501 until persistence lands.
126+
return notImplemented();
127+
}
128+
}

site/content/in-dev/unreleased/configuration/config-sections/flags-polaris_features.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,15 @@ If true, the policy-store endpoints are enabled
307307

308308
---
309309

310+
##### `polaris.features."ENABLE_SEMANTIC_MODELS"`
311+
312+
If true, the semantic-model (OSI) endpoints are enabled
313+
314+
- **Type:** `Boolean`
315+
- **Default:** `false`
316+
317+
---
318+
310319
##### `polaris.features."ENABLE_SUB_CATALOG_RBAC_FOR_FEDERATED_CATALOGS"`
311320

312321
When enabled, allows RBAC operations to create synthetic entities for entities in federated catalogs that don't exist in the local metastore.

0 commit comments

Comments
 (0)