Skip to content

Commit 7f5a713

Browse files
committed
Core: resolveAll() must be called before reading resolution results
1 parent fe96918 commit 7f5a713

File tree

2 files changed

+68
-1
lines changed

2 files changed

+68
-1
lines changed

polaris-core/src/main/java/org/apache/polaris/core/persistence/resolver/PolarisResolutionManifest.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,14 @@ public class PolarisResolutionManifest implements PolarisResolutionManifestCatal
6868
// Set when resolveAll is called
6969
private ResolverStatus primaryResolverStatus = null;
7070

71+
private ResolverStatus requirePrimaryResolverStatus() {
72+
diagnostics.checkNotNull(
73+
primaryResolverStatus,
74+
"resolver_not_run_before_access",
75+
"resolveAll() must be called before reading resolution results");
76+
return primaryResolverStatus;
77+
}
78+
7179
public PolarisResolutionManifest(
7280
PolarisDiagnostics diagnostics,
7381
RealmContext realmContext,
@@ -256,7 +264,7 @@ public Set<PolarisBaseEntity> getAllActivatedPrincipalRoleEntities() {
256264
}
257265

258266
private @Nullable ResolvedPolarisEntity getResolvedRootContainerEntity() {
259-
if (primaryResolverStatus.getStatus() != ResolverStatus.StatusEnum.SUCCESS) {
267+
if (requirePrimaryResolverStatus().getStatus() != ResolverStatus.StatusEnum.SUCCESS) {
260268
return null;
261269
}
262270
ResolvedPolarisEntity resolvedEntity =
@@ -277,6 +285,7 @@ public PolarisResolvedPathWrapper getResolvedRootContainerEntityAsPath() {
277285

278286
public PolarisResolvedPathWrapper getResolvedReferenceCatalogEntity(
279287
boolean prependRootContainer) {
288+
requirePrimaryResolverStatus();
280289
// This is a server error instead of being able to legitimately return null, since this means
281290
// a callsite failed to incorporate a reference catalog into its authorization flow but is
282291
// still trying to perform operations on the (nonexistence) reference catalog.
@@ -298,6 +307,7 @@ public PolarisResolvedPathWrapper getResolvedReferenceCatalogEntity(
298307
}
299308

300309
public PolarisEntitySubType getLeafSubType(Object key) {
310+
requirePrimaryResolverStatus();
301311
diagnostics.check(
302312
pathLookup.containsKey(key),
303313
"never_registered_key_for_resolved_path",
@@ -320,6 +330,7 @@ public PolarisEntitySubType getLeafSubType(Object key) {
320330
* "optional"
321331
*/
322332
public PolarisResolvedPathWrapper getResolvedPath(Object key, boolean prependRootContainer) {
333+
requirePrimaryResolverStatus();
323334
diagnostics.check(
324335
pathLookup.containsKey(key),
325336
"never_registered_key_for_resolved_path",
@@ -384,6 +395,7 @@ public PolarisResolvedPathWrapper getResolvedPath(
384395

385396
public PolarisResolvedPathWrapper getResolvedTopLevelEntity(
386397
String entityName, PolarisEntityType entityType) {
398+
requirePrimaryResolverStatus();
387399
// For now, all top-level entities will have the root container prepended so we don't have
388400
// a variation of this method that allows specifying whether to prepend the root container.
389401
diagnostics.check(
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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.core.persistence.resolver;
20+
21+
import static org.junit.jupiter.api.Assertions.assertThrows;
22+
import static org.mockito.Mockito.mock;
23+
import static org.mockito.Mockito.when;
24+
25+
import org.apache.polaris.core.PolarisDefaultDiagServiceImpl;
26+
import org.apache.polaris.core.PolarisDiagnostics;
27+
import org.apache.polaris.core.auth.PolarisPrincipal;
28+
import org.apache.polaris.core.context.RealmContext;
29+
import org.apache.polaris.core.entity.PolarisEntityType;
30+
import org.junit.jupiter.api.Test;
31+
32+
class PolarisResolutionManifestTest {
33+
34+
@Test
35+
void accessingResultsBeforeResolveAllFailsFast() {
36+
PolarisDiagnostics diagnostics = new PolarisDefaultDiagServiceImpl();
37+
RealmContext realmContext = () -> "test-realm";
38+
PolarisPrincipal principal = mock(PolarisPrincipal.class);
39+
40+
Resolver resolver = mock(Resolver.class);
41+
ResolverFactory resolverFactory = mock(ResolverFactory.class);
42+
when(resolverFactory.createResolver(principal, "test-catalog")).thenReturn(resolver);
43+
44+
PolarisResolutionManifest manifest =
45+
new PolarisResolutionManifest(
46+
diagnostics, realmContext, resolverFactory, principal, "test-catalog");
47+
48+
assertThrows(NullPointerException.class, () -> manifest.getResolvedPath("key"));
49+
assertThrows(NullPointerException.class, () -> manifest.getResolvedReferenceCatalogEntity());
50+
assertThrows(NullPointerException.class, () -> manifest.getLeafSubType("key"));
51+
assertThrows(
52+
NullPointerException.class,
53+
() -> manifest.getResolvedTopLevelEntity("catalog", PolarisEntityType.CATALOG));
54+
}
55+
}

0 commit comments

Comments
 (0)