Skip to content

Commit b8324eb

Browse files
authored
fix: provide fallback partition for single partition context runtimes (#5396)
1 parent 339312c commit b8324eb

File tree

8 files changed

+118
-62
lines changed

8 files changed

+118
-62
lines changed

core/common/boot/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ plugins {
1919

2020
dependencies {
2121
api(project(":spi:common:boot-spi"))
22+
api(project(":spi:common:participant-context-single-spi"))
2223

2324
implementation(project(":core:common:lib:boot-lib"))
2425

core/common/boot/src/main/java/org/eclipse/edc/boot/BootServicesExtension.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
import org.eclipse.edc.boot.health.HealthCheckServiceImpl;
1919
import org.eclipse.edc.boot.system.ExtensionLoader;
2020
import org.eclipse.edc.boot.vault.InMemoryVault;
21+
import org.eclipse.edc.participantcontext.single.spi.SingleParticipantContextSupplier;
2122
import org.eclipse.edc.runtime.metamodel.annotation.Extension;
23+
import org.eclipse.edc.runtime.metamodel.annotation.Inject;
2224
import org.eclipse.edc.runtime.metamodel.annotation.Provider;
2325
import org.eclipse.edc.runtime.metamodel.annotation.Setting;
2426
import org.eclipse.edc.spi.security.Vault;
@@ -43,6 +45,9 @@ public class BootServicesExtension implements ServiceExtension {
4345
@Setting(description = "Configures this component's ID. This should be a unique, stable and deterministic identifier.", defaultValue = "<random UUID>")
4446
public static final String COMPONENT_ID = "edc.component.id";
4547

48+
@Inject(required = false)
49+
private SingleParticipantContextSupplier singleParticipantContextSupplier;
50+
4651
private HealthCheckServiceImpl healthCheckService;
4752

4853
@Override
@@ -55,7 +60,6 @@ public void initialize(ServiceExtensionContext context) {
5560
healthCheckService = new HealthCheckServiceImpl();
5661
}
5762

58-
5963
@Provider
6064
public Clock clock() {
6165
return Clock.systemUTC();
@@ -84,7 +88,7 @@ public ExecutorInstrumentation defaultInstrumentation() {
8488
@Provider(isDefault = true)
8589
public Vault createInmemVault(ServiceExtensionContext context) {
8690
context.getMonitor().warning("Using the InMemoryVault is not suitable for production scenarios and should be replaced with an actual Vault!");
87-
return new InMemoryVault(context.getMonitor());
91+
return new InMemoryVault(context.getMonitor(), singleParticipantContextSupplier);
8892
}
8993

9094
@Provider

core/common/edr-store-core/src/test/java/org/eclipse/edc/edr/store/EndpointDataReferenceStoreImplTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
public class EndpointDataReferenceStoreImplTest extends EndpointDataReferenceStoreTestBase {
2929

3030
private final InMemoryEndpointDataReferenceEntryIndex store = new InMemoryEndpointDataReferenceEntryIndex(CriterionOperatorRegistryImpl.ofDefaults());
31-
private final VaultEndpointDataReferenceCache cache = new VaultEndpointDataReferenceCache(new InMemoryVault(mock()), "", new ObjectMapper());
31+
private final VaultEndpointDataReferenceCache cache = new VaultEndpointDataReferenceCache(new InMemoryVault(mock(), null), "", new ObjectMapper());
3232
private final EndpointDataReferenceStoreImpl endpointDataReferenceService = new EndpointDataReferenceStoreImpl(store, cache, new NoopTransactionContext());
3333

3434
@Override

core/common/edr-store-core/src/test/java/org/eclipse/edc/edr/store/defaults/VaultEndpointDataReferenceCacheTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
public class VaultEndpointDataReferenceCacheTest extends EndpointDataReferenceCacheTestBase {
2525

26-
private final VaultEndpointDataReferenceCache cache = new VaultEndpointDataReferenceCache(new InMemoryVault(mock()), "", new ObjectMapper());
26+
private final VaultEndpointDataReferenceCache cache = new VaultEndpointDataReferenceCache(new InMemoryVault(mock(), null), "", new ObjectMapper());
2727

2828
@Override
2929
protected EndpointDataReferenceCache getCache() {

core/common/lib/boot-lib/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ plugins {
1919
}
2020

2121
dependencies {
22-
2322
api(project(":spi:common:boot-spi"))
23+
api(project(":spi:common:connector-participant-context-spi"))
2424

2525
testImplementation(libs.awaitility)
2626
}

core/common/lib/boot-lib/src/main/java/org/eclipse/edc/boot/vault/InMemoryVault.java

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,43 +14,51 @@
1414

1515
package org.eclipse.edc.boot.vault;
1616

17+
import org.eclipse.edc.participantcontext.spi.service.ParticipantContextSupplier;
18+
import org.eclipse.edc.participantcontext.spi.types.ParticipantContext;
1719
import org.eclipse.edc.spi.monitor.Monitor;
1820
import org.eclipse.edc.spi.result.Result;
21+
import org.eclipse.edc.spi.result.ServiceResult;
1922
import org.eclipse.edc.spi.security.Vault;
23+
import org.jetbrains.annotations.NotNull;
2024
import org.jetbrains.annotations.Nullable;
2125

2226
import java.util.Map;
27+
import java.util.Optional;
2328
import java.util.concurrent.ConcurrentHashMap;
29+
import java.util.function.Supplier;
2430

2531
import static java.util.Optional.ofNullable;
2632

2733
public class InMemoryVault implements Vault {
2834
private static final String DEFAULT_PARTITION = "default";
2935
private final Map<String, Map<String, String>> secrets = new ConcurrentHashMap<>();
3036
private final Monitor monitor;
37+
private final ParticipantContextSupplier participantContextSupplier;
3138

32-
public InMemoryVault(Monitor monitor) {
39+
public InMemoryVault(Monitor monitor, ParticipantContextSupplier participantContextSupplier) {
3340
this.monitor = monitor;
41+
this.participantContextSupplier = participantContextSupplier;
3442
}
3543

3644
@Override
3745
public @Nullable String resolveSecret(String key) {
38-
return resolveSecret(DEFAULT_PARTITION, key);
46+
return resolveSecret(getPartition(), key);
3947
}
4048

4149
@Override
4250
public Result<Void> storeSecret(String key, String value) {
43-
return storeSecret(DEFAULT_PARTITION, key, value);
51+
return storeSecret(getPartition(), key, value);
4452
}
4553

4654
@Override
4755
public Result<Void> deleteSecret(String key) {
48-
return deleteSecret(DEFAULT_PARTITION, key);
56+
return deleteSecret(getPartition(), key);
4957
}
5058

5159
@Override
5260
public @Nullable String resolveSecret(String vaultPartition, String s) {
53-
vaultPartition = ofNullable(vaultPartition).orElse(DEFAULT_PARTITION);
61+
vaultPartition = ofNullable(vaultPartition).orElse(getPartition());
5462

5563
monitor.debug("Resolving secret " + s);
5664
if (s == null) {
@@ -62,7 +70,7 @@ public Result<Void> deleteSecret(String key) {
6270

6371
@Override
6472
public Result<Void> storeSecret(String vaultPartition, String s, String s1) {
65-
vaultPartition = ofNullable(vaultPartition).orElse(DEFAULT_PARTITION);
73+
vaultPartition = ofNullable(vaultPartition).orElse(getPartition());
6674
monitor.debug("Storing secret " + s);
6775

6876
var partition = secrets.computeIfAbsent(vaultPartition, k -> new ConcurrentHashMap<>());
@@ -72,7 +80,7 @@ public Result<Void> storeSecret(String vaultPartition, String s, String s1) {
7280

7381
@Override
7482
public Result<Void> deleteSecret(String vaultPartition, String s) {
75-
vaultPartition = ofNullable(vaultPartition).orElse(DEFAULT_PARTITION);
83+
vaultPartition = ofNullable(vaultPartition).orElse(getPartition());
7684
monitor.debug("Deleting secret " + s);
7785

7886
var result = ofNullable(secrets.get(vaultPartition)).map(map -> map.remove(s)).orElse(null);
@@ -81,4 +89,10 @@ public Result<Void> deleteSecret(String vaultPartition, String s) {
8189
Result.failure("Secret with key " + s + " does not exist") :
8290
Result.success();
8391
}
92+
93+
private @NotNull String getPartition() {
94+
return Optional.ofNullable(participantContextSupplier)
95+
.map(Supplier::get).filter(ServiceResult::succeeded).map(ServiceResult::getContent)
96+
.map(ParticipantContext::getParticipantContextId).orElse(DEFAULT_PARTITION);
97+
}
8498
}

core/common/lib/boot-lib/src/test/java/org/eclipse/edc/boot/vault/InMemoryVaultTest.java

Lines changed: 86 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -14,72 +14,109 @@
1414

1515
package org.eclipse.edc.boot.vault;
1616

17+
import org.eclipse.edc.participantcontext.spi.service.ParticipantContextSupplier;
18+
import org.eclipse.edc.participantcontext.spi.types.ParticipantContext;
1719
import org.eclipse.edc.spi.monitor.Monitor;
18-
import org.junit.jupiter.api.BeforeEach;
20+
import org.eclipse.edc.spi.result.ServiceResult;
21+
import org.junit.jupiter.api.Nested;
1922
import org.junit.jupiter.api.Test;
2023

2124
import static org.assertj.core.api.Assertions.assertThat;
2225
import static org.mockito.Mockito.mock;
2326

2427
class InMemoryVaultTest {
2528

26-
private InMemoryVault vault;
29+
@Nested
30+
class NoParticipantContextSupplier {
31+
private final InMemoryVault vault = new InMemoryVault(mock(Monitor.class), null);
2732

28-
@BeforeEach
29-
void setUp() {
30-
vault = new InMemoryVault(mock(Monitor.class));
31-
}
33+
@Test
34+
void resolveSecret() {
35+
assertThat(vault.resolveSecret("key")).isNull();
36+
vault.storeSecret("key", "secret");
37+
assertThat(vault.resolveSecret("key")).isEqualTo("secret");
38+
}
3239

33-
@Test
34-
void resolveSecret() {
35-
assertThat(vault.resolveSecret("key")).isNull();
36-
vault.storeSecret("key", "secret");
37-
assertThat(vault.resolveSecret("key")).isEqualTo("secret");
38-
}
40+
@Test
41+
void resolveSecret_partitioned() {
42+
assertThat(vault.resolveSecret("key")).isNull();
43+
vault.storeSecret("partition", "key", "secret");
44+
assertThat(vault.resolveSecret("partition", "key")).isEqualTo("secret");
45+
assertThat(vault.resolveSecret("another", "key")).isNull();
46+
}
3947

40-
@Test
41-
void resolveSecret_partitioned() {
42-
assertThat(vault.resolveSecret("key")).isNull();
43-
vault.storeSecret("partition", "key", "secret");
44-
assertThat(vault.resolveSecret("partition", "key")).isEqualTo("secret");
45-
assertThat(vault.resolveSecret("another", "key")).isNull();
46-
}
48+
@Test
49+
void storeSecret() {
50+
assertThat(vault.storeSecret("key", "value1").succeeded()).isTrue();
51+
assertThat(vault.resolveSecret("key")).isEqualTo("value1");
52+
assertThat(vault.storeSecret("key", "value2").succeeded()).isTrue();
53+
assertThat(vault.resolveSecret("key")).isEqualTo("value2");
54+
}
4755

48-
@Test
49-
void storeSecret() {
50-
assertThat(vault.storeSecret("key", "value1").succeeded()).isTrue();
51-
assertThat(vault.resolveSecret("key")).isEqualTo("value1");
52-
assertThat(vault.storeSecret("key", "value2").succeeded()).isTrue();
53-
assertThat(vault.resolveSecret("key")).isEqualTo("value2");
54-
}
56+
@Test
57+
void storeSecret_partitioned() {
58+
assertThat(vault.storeSecret("partition", "key", "value1").succeeded()).isTrue();
59+
assertThat(vault.resolveSecret("partition", "key")).isEqualTo("value1");
60+
assertThat(vault.storeSecret("partition", "key", "value2").succeeded()).isTrue();
61+
assertThat(vault.resolveSecret("partition", "key")).isEqualTo("value2");
5562

56-
@Test
57-
void storeSecret_partitioned() {
58-
assertThat(vault.storeSecret("partition", "key", "value1").succeeded()).isTrue();
59-
assertThat(vault.resolveSecret("partition", "key")).isEqualTo("value1");
60-
assertThat(vault.storeSecret("partition", "key", "value2").succeeded()).isTrue();
61-
assertThat(vault.resolveSecret("partition", "key")).isEqualTo("value2");
63+
assertThat(vault.storeSecret("partition", "key", "value2").succeeded()).isTrue();
64+
}
6265

63-
assertThat(vault.storeSecret("partition", "key", "value2").succeeded()).isTrue();
64-
}
66+
@Test
67+
void deleteSecret() {
68+
assertThat(vault.deleteSecret("key").succeeded()).isFalse();
69+
assertThat(vault.storeSecret("key", "value1").succeeded()).isTrue();
70+
assertThat(vault.deleteSecret("key").succeeded()).isTrue();
71+
assertThat(vault.resolveSecret("key")).isNull();
72+
73+
}
6574

66-
@Test
67-
void deleteSecret() {
68-
assertThat(vault.deleteSecret("key").succeeded()).isFalse();
69-
assertThat(vault.storeSecret("key", "value1").succeeded()).isTrue();
70-
assertThat(vault.deleteSecret("key").succeeded()).isTrue();
71-
assertThat(vault.resolveSecret("key")).isNull();
75+
@Test
76+
void deleteSecret_partitioned() {
77+
assertThat(vault.deleteSecret("partition", "key").succeeded()).isFalse();
78+
assertThat(vault.storeSecret("partition", "key", "value1").succeeded()).isTrue();
79+
assertThat(vault.deleteSecret("partition", "key").succeeded()).isTrue();
80+
assertThat(vault.resolveSecret("partition", "key")).isNull();
7281

82+
assertThat(vault.storeSecret("partition", "key", "value1").succeeded()).isTrue();
83+
assertThat(vault.deleteSecret("another", "key").succeeded()).isFalse();
84+
}
7385
}
7486

75-
@Test
76-
void deleteSecret_partitioned() {
77-
assertThat(vault.deleteSecret("partition", "key").succeeded()).isFalse();
78-
assertThat(vault.storeSecret("partition", "key", "value1").succeeded()).isTrue();
79-
assertThat(vault.deleteSecret("partition", "key").succeeded()).isTrue();
80-
assertThat(vault.resolveSecret("partition", "key")).isNull();
87+
@Nested
88+
class WithParticipantContextSupplier {
89+
private final ParticipantContextSupplier participantContextSupplier = () -> ServiceResult.success(
90+
ParticipantContext.Builder.newInstance().participantContextId("participantContextId").identity("identity").build()
91+
);
92+
private final InMemoryVault vault = new InMemoryVault(mock(Monitor.class), participantContextSupplier);
93+
94+
@Test
95+
void shouldResolveFromParticipantContextIdPartition() {
96+
vault.storeSecret("participantContextId", "key", "secret");
8197

82-
assertThat(vault.storeSecret("partition", "key", "value1").succeeded()).isTrue();
83-
assertThat(vault.deleteSecret("another", "key").succeeded()).isFalse();
98+
var resolved = vault.resolveSecret("key");
99+
100+
assertThat(resolved).isEqualTo("secret");
101+
}
102+
103+
@Test
104+
void shouldStoreOnTheParticipantContextIdPartition() {
105+
vault.storeSecret("key", "secret");
106+
107+
var resolved = vault.resolveSecret("participantContextId", "key");
108+
assertThat(resolved).isEqualTo("secret");
109+
}
110+
111+
@Test
112+
void shouldDeleteFromTheParticipantContextIdPartition() {
113+
vault.storeSecret("participantContextId", "key", "secret");
114+
115+
var result = vault.deleteSecret("key");
116+
117+
assertThat(result.succeeded());
118+
assertThat(vault.resolveSecret("participantContextId", "key")).isNull();
119+
}
84120
}
85-
}
121+
122+
}

extensions/common/sql/sql-pool/sql-pool-apache-commons/src/test/java/org/eclipse/edc/sql/pool/commons/CommonsConnectionPoolServiceExtensionTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class CommonsConnectionPoolServiceExtensionTest {
6565
@BeforeEach
6666
void setUp(ServiceExtensionContext context) {
6767
context.registerService(DataSourceRegistry.class, dataSourceRegistry);
68-
context.registerService(Vault.class, new InMemoryVault(mock()));
68+
context.registerService(Vault.class, new InMemoryVault(mock(), null));
6969
context.registerService(ConnectionFactory.class, connectionFactory);
7070
}
7171

0 commit comments

Comments
 (0)