Skip to content

Commit 6a0ee78

Browse files
committed
Add base persistence APIs for Policy Mapping
1 parent 2e6aef1 commit 6a0ee78

File tree

10 files changed

+801
-217
lines changed

10 files changed

+801
-217
lines changed

extension/persistence/eclipselink/src/main/java/org/apache/polaris/extension/persistence/impl/eclipselink/PolarisEclipseLinkMetaStoreSessionImpl.java

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
import org.apache.polaris.core.persistence.BaseMetaStoreManager;
5353
import org.apache.polaris.core.persistence.PrincipalSecretsGenerator;
5454
import org.apache.polaris.core.persistence.RetryOnConcurrencyException;
55+
import org.apache.polaris.core.policy.PolarisPolicyMappingRecord;
5556
import org.apache.polaris.core.persistence.transactional.AbstractTransactionalPersistence;
5657
import org.apache.polaris.core.storage.PolarisStorageConfigurationInfo;
5758
import org.apache.polaris.core.storage.PolarisStorageIntegration;
@@ -60,6 +61,7 @@
6061
import org.apache.polaris.jpa.models.ModelEntityActive;
6162
import org.apache.polaris.jpa.models.ModelEntityChangeTracking;
6263
import org.apache.polaris.jpa.models.ModelGrantRecord;
64+
import org.apache.polaris.jpa.models.ModelPolicyMappingRecord;
6365
import org.apache.polaris.jpa.models.ModelPrincipalSecrets;
6466
import org.slf4j.Logger;
6567
import org.slf4j.LoggerFactory;
@@ -529,6 +531,90 @@ public int lookupEntityGrantRecordsVersion(
529531
.toList();
530532
}
531533

534+
/** {@inheritDoc} */
535+
@Override
536+
public void writeToPolicyMappingRecords(
537+
@Nonnull PolarisCallContext callCtx, @Nonnull PolarisPolicyMappingRecord record) {
538+
539+
this.store.writeToPolicyMappingRecords(localSession.get(), record);
540+
}
541+
542+
/** {@inheritDoc} */
543+
@Override
544+
public void deleteFromPolicyMappingRecords(
545+
@Nonnull PolarisCallContext callCtx, @Nonnull PolarisPolicyMappingRecord record) {
546+
this.store.deleteFromPolicyMappingRecords(localSession.get(), record);
547+
}
548+
549+
/** {@inheritDoc} */
550+
@Override
551+
public void deleteAllEntityPolicyMappingRecords(
552+
@Nonnull PolarisCallContext callCtx,
553+
@Nonnull PolarisEntityCore entity,
554+
@Nonnull List<PolarisPolicyMappingRecord> mappingOnTarget,
555+
@Nonnull List<PolarisPolicyMappingRecord> mappingOnPolicy) {
556+
this.store.deleteAllEntityPolicyMappingRecords(localSession.get(), entity);
557+
}
558+
559+
/** {@inheritDoc} */
560+
@Nullable
561+
@Override
562+
public PolarisPolicyMappingRecord lookupPolicyMappingRecord(
563+
@Nonnull PolarisCallContext callCtx,
564+
long targetCatalogId,
565+
long targetId,
566+
int policyTypeCode,
567+
long policyCatalogId,
568+
long policyId) {
569+
return ModelPolicyMappingRecord.toPolicyMappingRecord(
570+
this.store.lookupPolicyMappingRecord(
571+
localSession.get(),
572+
targetCatalogId,
573+
targetId,
574+
policyTypeCode,
575+
policyCatalogId,
576+
policyId));
577+
}
578+
579+
/** {@inheritDoc} */
580+
@Nonnull
581+
@Override
582+
public List<PolarisPolicyMappingRecord> loadPoliciesOnTargetByType(
583+
@Nonnull PolarisCallContext callCtx,
584+
long targetCatalogId,
585+
long targetId,
586+
int policyTypeCode) {
587+
return this.store
588+
.loadPoliciesOnTargetByType(localSession.get(), targetCatalogId, targetId, policyTypeCode)
589+
.stream()
590+
.map(ModelPolicyMappingRecord::toPolicyMappingRecord)
591+
.toList();
592+
}
593+
594+
/** {@inheritDoc} */
595+
@Nonnull
596+
@Override
597+
public List<PolarisPolicyMappingRecord> loadAllPoliciesOnTarget(
598+
@Nonnull PolarisCallContext callCtx, long targetCatalogId, long targetId) {
599+
return this.store
600+
.loadAllPoliciesOnTarget(localSession.get(), targetCatalogId, targetId)
601+
.stream()
602+
.map(ModelPolicyMappingRecord::toPolicyMappingRecord)
603+
.toList();
604+
}
605+
606+
/** {@inheritDoc} */
607+
@Nonnull
608+
@Override
609+
public List<PolarisPolicyMappingRecord> loadAllPoliciesOnPolicy(
610+
@Nonnull PolarisCallContext callCtx, long policyCatalogId, long policyId) {
611+
return this.store
612+
.loadAllPoliciesOnPolicy(localSession.get(), policyCatalogId, policyId)
613+
.stream()
614+
.map(ModelPolicyMappingRecord::toPolicyMappingRecord)
615+
.toList();
616+
}
617+
532618
/** {@inheritDoc} */
533619
@Override
534620
public @Nullable PolarisPrincipalSecrets loadPrincipalSecrets(

extension/persistence/eclipselink/src/main/java/org/apache/polaris/extension/persistence/impl/eclipselink/PolarisEclipseLinkStore.java

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,12 @@
3535
import org.apache.polaris.core.entity.PolarisEntityType;
3636
import org.apache.polaris.core.entity.PolarisGrantRecord;
3737
import org.apache.polaris.core.entity.PolarisPrincipalSecrets;
38+
import org.apache.polaris.core.policy.PolarisPolicyMappingRecord;
3839
import org.apache.polaris.jpa.models.ModelEntity;
3940
import org.apache.polaris.jpa.models.ModelEntityActive;
4041
import org.apache.polaris.jpa.models.ModelEntityChangeTracking;
4142
import org.apache.polaris.jpa.models.ModelGrantRecord;
43+
import org.apache.polaris.jpa.models.ModelPolicyMappingRecord;
4244
import org.apache.polaris.jpa.models.ModelPrincipalSecrets;
4345
import org.slf4j.Logger;
4446
import org.slf4j.LoggerFactory;
@@ -411,6 +413,121 @@ void deletePrincipalSecrets(EntityManager session, String clientId) {
411413
session.remove(modelPrincipalSecrets);
412414
}
413415

416+
void writeToPolicyMappingRecords(
417+
EntityManager session, PolarisPolicyMappingRecord mappingRecord) {
418+
diagnosticServices.check(session != null, "session_is_null");
419+
checkInitialized();
420+
421+
session.persist(ModelPolicyMappingRecord.fromPolicyMappingRecord(mappingRecord));
422+
}
423+
424+
void deleteFromPolicyMappingRecords(
425+
EntityManager session, PolarisPolicyMappingRecord mappingRecord) {
426+
diagnosticServices.check(session != null, "session_is_null");
427+
checkInitialized();
428+
429+
ModelPolicyMappingRecord lookupPolicyMappingRecord =
430+
lookupPolicyMappingRecord(
431+
session,
432+
mappingRecord.getTargetCatalogId(),
433+
mappingRecord.getTargetId(),
434+
mappingRecord.getPolicyTypeCode(),
435+
mappingRecord.getPolicyCatalogId(),
436+
mappingRecord.getPolicyId());
437+
438+
diagnosticServices.check(lookupPolicyMappingRecord != null, "policy_mapping_record_not_found");
439+
session.remove(lookupPolicyMappingRecord);
440+
}
441+
442+
void deleteAllEntityPolicyMappingRecords(EntityManager session, PolarisEntityCore entity) {
443+
diagnosticServices.check(session != null, "session_is_null");
444+
checkInitialized();
445+
446+
loadAllPoliciesOnPolicy(session, entity.getCatalogId(), entity.getId())
447+
.forEach(session::remove);
448+
loadAllPoliciesOnTarget(session, entity.getCatalogId(), entity.getId())
449+
.forEach(session::remove);
450+
}
451+
452+
ModelPolicyMappingRecord lookupPolicyMappingRecord(
453+
EntityManager session,
454+
long targetCatalogId,
455+
long targetId,
456+
long policyTypeCode,
457+
long policyCatalogId,
458+
long policyId) {
459+
diagnosticServices.check(session != null, "session_is_null");
460+
checkInitialized();
461+
462+
return session
463+
.createQuery(
464+
"SELECT m from ModelPolicyMappingRecord m "
465+
+ "where m.targetCatalogId=:targetCatalogId "
466+
+ "and m.targetId=:targetId "
467+
+ "and m.policyTypeCode=:policyTypeCode "
468+
+ "and m.policyCatalogId=:policyCatalogId "
469+
+ "and m.policyId=:policyId",
470+
ModelPolicyMappingRecord.class)
471+
.setParameter("targetCatalogId", targetCatalogId)
472+
.setParameter("targetId", targetId)
473+
.setParameter("policyTypeCode", policyTypeCode)
474+
.setParameter("policyCatalogId", policyCatalogId)
475+
.setParameter("policyId", policyId)
476+
.getResultStream()
477+
.findFirst()
478+
.orElse(null);
479+
}
480+
481+
List<ModelPolicyMappingRecord> loadPoliciesOnTargetByType(
482+
EntityManager session, long targetCatalogId, long targetId, int policyTypeCode) {
483+
diagnosticServices.check(session != null, "session_is_null");
484+
checkInitialized();
485+
486+
return session
487+
.createQuery(
488+
"SELECT m from ModelPolicyMappingRecord m "
489+
+ "where m.targetCatalogId=:targetCatalogId "
490+
+ "and m.targetId=:targetId "
491+
+ "and m.policyTypeCode=:policyTypeCode",
492+
ModelPolicyMappingRecord.class)
493+
.setParameter("targetCatalogId", targetCatalogId)
494+
.setParameter("targetId", targetId)
495+
.setParameter("policyTypeCode", policyTypeCode)
496+
.getResultList();
497+
}
498+
499+
List<ModelPolicyMappingRecord> loadAllPoliciesOnTarget(
500+
EntityManager session, long targetCatalogId, long targetId) {
501+
diagnosticServices.check(session != null, "session_is_null");
502+
checkInitialized();
503+
504+
return session
505+
.createQuery(
506+
"SELECT m from ModelPolicyMappingRecord m "
507+
+ " where m.targetCatalogId=:targetCatalogId "
508+
+ "and m.targetId=:targetId",
509+
ModelPolicyMappingRecord.class)
510+
.setParameter("targetCatalogId", targetCatalogId)
511+
.setParameter("targetId", targetId)
512+
.getResultList();
513+
}
514+
515+
List<ModelPolicyMappingRecord> loadAllPoliciesOnPolicy(
516+
EntityManager session, long policyCatalogId, long policyId) {
517+
diagnosticServices.check(session != null, "session_is_null");
518+
checkInitialized();
519+
520+
return session
521+
.createQuery(
522+
"SELECT m from ModelPolicyMappingRecord m "
523+
+ "where m.policyCatalogId=:policyCatalogId "
524+
+ "and m.policyId=:policyId",
525+
ModelPolicyMappingRecord.class)
526+
.setParameter("policyCatalogId", policyCatalogId)
527+
.setParameter("policyId", policyId)
528+
.getResultList();
529+
}
530+
414531
private void checkInitialized() {
415532
diagnosticServices.check(this.initialized.get(), "store_not_initialized");
416533
}
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
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.jpa.models;
20+
21+
import jakarta.persistence.Entity;
22+
import jakarta.persistence.Id;
23+
import jakarta.persistence.Index;
24+
import jakarta.persistence.Table;
25+
import jakarta.persistence.Version;
26+
import org.apache.polaris.core.policy.PolarisPolicyMappingRecord;
27+
28+
@Entity
29+
@Table(
30+
name = "POLICY_MAPPING_RECORDS",
31+
indexes = {
32+
@Index(
33+
name = "POLICY_MAPPING_RECORDS_BY_POLICY_INDEX",
34+
columnList = "policyCatalogId,policyId,targetCatalogId,targetId")
35+
})
36+
public class ModelPolicyMappingRecord {
37+
// id of the catalog where target entity resides
38+
@Id private long targetCatalogId;
39+
40+
// id of the target entity
41+
@Id private long targetId;
42+
43+
// id associated to the policy type
44+
@Id private int policyTypeCode;
45+
46+
// id of the catalog where the policy entity resides
47+
@Id private long policyCatalogId;
48+
49+
// id of the policy
50+
@Id private long policyId;
51+
52+
// additional parameters of the mapping
53+
private String parameters;
54+
55+
// Used for Optimistic Locking to handle concurrent reads and updates
56+
@Version private long version;
57+
58+
public long getTargetCatalogId() {
59+
return targetCatalogId;
60+
}
61+
62+
public long getTargetId() {
63+
return targetId;
64+
}
65+
66+
public int getPolicyTypeCode() {
67+
return policyTypeCode;
68+
}
69+
70+
public long getPolicyCatalogId() {
71+
return policyCatalogId;
72+
}
73+
74+
public long getPolicyId() {
75+
return policyId;
76+
}
77+
78+
public String getParameters() {
79+
return parameters;
80+
}
81+
82+
public static ModelPolicyMappingRecord.Builder builder() {
83+
return new ModelPolicyMappingRecord.Builder();
84+
}
85+
86+
public static final class Builder {
87+
private final ModelPolicyMappingRecord policyMappingRecord;
88+
89+
private Builder() {
90+
policyMappingRecord = new ModelPolicyMappingRecord();
91+
}
92+
93+
public Builder targetCatalogId(long targetCatalogId) {
94+
policyMappingRecord.targetCatalogId = targetCatalogId;
95+
return this;
96+
}
97+
98+
public Builder targetId(long targetId) {
99+
policyMappingRecord.targetId = targetId;
100+
return this;
101+
}
102+
103+
public Builder policyTypeCode(int policyTypeCode) {
104+
policyMappingRecord.policyTypeCode = policyTypeCode;
105+
return this;
106+
}
107+
108+
public Builder policyCatalogId(long policyCatalogId) {
109+
policyMappingRecord.policyCatalogId = policyCatalogId;
110+
return this;
111+
}
112+
113+
public Builder policyId(long policyId) {
114+
policyMappingRecord.policyId = policyId;
115+
return this;
116+
}
117+
118+
public Builder parameters(String parameters) {
119+
policyMappingRecord.parameters = parameters;
120+
return this;
121+
}
122+
123+
public ModelPolicyMappingRecord build() {
124+
return policyMappingRecord;
125+
}
126+
}
127+
128+
public static ModelPolicyMappingRecord fromPolicyMappingRecord(
129+
PolarisPolicyMappingRecord record) {
130+
if (record == null) return null;
131+
132+
return ModelPolicyMappingRecord.builder()
133+
.targetCatalogId(record.getTargetCatalogId())
134+
.targetId(record.getTargetId())
135+
.policyTypeCode(record.getPolicyTypeCode())
136+
.policyCatalogId(record.getPolicyCatalogId())
137+
.policyId(record.getPolicyId())
138+
.parameters(record.getParameters())
139+
.build();
140+
}
141+
142+
public static PolarisPolicyMappingRecord toPolicyMappingRecord(ModelPolicyMappingRecord model) {
143+
if (model == null) return null;
144+
145+
return new PolarisPolicyMappingRecord(
146+
model.getTargetCatalogId(),
147+
model.getTargetId(),
148+
model.getPolicyCatalogId(),
149+
model.getPolicyId(),
150+
model.getPolicyTypeCode(),
151+
model.getParameters());
152+
}
153+
}

0 commit comments

Comments
 (0)