Skip to content

Commit

Permalink
Add support for supplying a version timestamp to the 'map-sid' functi…
Browse files Browse the repository at this point in the history
…on (#55)

* Initial setup for version timestamp

* Initialize empty config map

* Use SID service to validate versionTimestamp

* Use the dapla-dlp-pseudo-core release version

---------

Co-authored-by: Michael Moen Allport <[email protected]>
  • Loading branch information
bjornandre and mallport authored Sep 5, 2023
1 parent f48f941 commit 4dd9856
Show file tree
Hide file tree
Showing 10 changed files with 89 additions and 5 deletions.
1 change: 1 addition & 0 deletions conf/application-local.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,5 @@ app-roles:
- [email protected]
- [email protected]
- [email protected]
- [email protected]

2 changes: 1 addition & 1 deletion doc/requests/examples-sid.http
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Content-Type: application/json
{
"name": "fnr",
"pattern": "**/fnr",
"func": "map-sid(keyId=papis-key-1)"
"func": "map-sid(keyId=papis-key-1,versionTimestamp=2023_04_25-12_35_40_649511)"
}
]
}
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@
<dependency>
<groupId>no.ssb.dapla.dlp.pseudo</groupId>
<artifactId>dapla-dlp-pseudo-core</artifactId>
<version>1.2.3</version>
<version>1.2.4</version>
</dependency>
<dependency>
<groupId>no.ssb.avro.convert.core</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,8 @@ public Publisher<Map<String, SidInfo>> lookupFnr(List<String> fnrList, Optional<
);
}

@Override
public Publisher<VersionInfo> getSnapshots() {
return sidClient.snapshots();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ public Publisher<Map<String, SidInfo>> lookupFnr(List<String> fnrList, Optional<
);
}

@Override
public Publisher<VersionInfo> getSnapshots() {
return Publishers.just(VersionInfo.builder().build());
}

public static class NoSidMappingFoundException extends RuntimeException {
public NoSidMappingFoundException(String message) {
Expand Down
7 changes: 5 additions & 2 deletions src/main/java/no/ssb/dlp/pseudo/service/sid/SidClient.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package no.ssb.dlp.pseudo.service.sid;

import io.micronaut.http.annotation.Body;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.annotation.Post;
import io.micronaut.http.client.annotation.Client;
import io.micronaut.scheduling.TaskExecutors;
import io.micronaut.scheduling.annotation.ExecuteOn;
import org.reactivestreams.Publisher;

import java.util.Map;

@Client(id="sid-service")
@IdTokenFilterMatcher()
public interface SidClient {
Expand All @@ -21,4 +20,8 @@ public interface SidClient {
@ExecuteOn(TaskExecutors.IO)
Publisher<MultiSidResponse> lookup(@Body MultiSidRequest multiSidRequest);

@Get( "/sid/snapshots")
@ExecuteOn(TaskExecutors.IO)
Publisher<VersionInfo> snapshots();

}
19 changes: 18 additions & 1 deletion src/main/java/no/ssb/dlp/pseudo/service/sid/SidMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@
import io.micronaut.http.HttpStatus;
import io.micronaut.http.client.exceptions.HttpClientResponseException;
import lombok.extern.slf4j.Slf4j;
import no.ssb.dapla.dlp.pseudo.func.map.MapFuncConfig;
import no.ssb.dapla.dlp.pseudo.func.map.Mapper;
import no.ssb.dlp.pseudo.service.Application;
import org.reactivestreams.Publisher;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
Expand All @@ -32,6 +34,7 @@ public class SidMapper implements Mapper {
private final SidService sidService;
private static final int DEFAULT_PARTITION_SIZE = 50000;
private final int partitionSize;
private Map<String, Object> config = Collections.emptyMap();

public SidMapper() {
sidService = Application.getContext().getBean(SidService.class);
Expand Down Expand Up @@ -59,7 +62,8 @@ public Object map(Object data) {
for (List<String> bulkFnr: Lists.partition(List.copyOf(fnrs), partitionSize)) {
log.info("Execute SID-mapping bulk request");
final ObservableSubscriber<Map<String, SidInfo>> subscriber = ObservableSubscriber.subscribe(
sidService.lookupFnr(bulkFnr, Optional.ofNullable(null)));
sidService.lookupFnr(bulkFnr, Optional.ofNullable(
String.valueOf(this.config.getOrDefault(MapFuncConfig.Param.VERSION_TIMESTAMP, null)))));
for (String f: bulkFnr) {
bulkRequest.put(f, subscriber);
}
Expand All @@ -85,6 +89,19 @@ public Object map(Object data) {
}
}

@Override
public void setConfig(Map<String, Object> config) {
if (config.containsKey(MapFuncConfig.Param.VERSION_TIMESTAMP)) {
VersionInfo snapshots = ObservableSubscriber.subscribe(this.sidService.getSnapshots()).awaitResult()
.orElseThrow(() -> new RuntimeException("SID service did not respond"));
if (!snapshots.getItems().contains(config.get(MapFuncConfig.Param.VERSION_TIMESTAMP).toString())) {
throw new RuntimeException(String.format("Invalid version timestamp. Valid versions are: %s",
String.join(", ", snapshots.getItems())));
}
}
this.config = config;
}

@Override
public Object restore(Object mapped) {
return mapped;
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/no/ssb/dlp/pseudo/service/sid/SidService.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ public interface SidService {

Publisher<SidInfo> lookupSnr(String fnr, Optional<String> snapshot);
Publisher<Map<String, SidInfo>> lookupFnr(List<String> fnrList, Optional<String> snapshot);

Publisher<VersionInfo> getSnapshots();
}
14 changes: 14 additions & 0 deletions src/main/java/no/ssb/dlp/pseudo/service/sid/VersionInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package no.ssb.dlp.pseudo.service.sid;

import lombok.Builder;
import lombok.Data;
import lombok.extern.jackson.Jacksonized;

import java.util.List;

@Data
@Builder
@Jacksonized
public class VersionInfo {
private final List<String> items;
}
39 changes: 39 additions & 0 deletions src/test/java/no/ssb/dlp/pseudo/service/sid/SidMapperTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@
import no.ssb.dapla.dlp.pseudo.func.map.Mapper;
import no.ssb.dlp.pseudo.service.Application;
import org.apache.groovy.util.Maps;
import org.junit.Assert;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import javax.inject.Inject;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.ServiceLoader;

Expand Down Expand Up @@ -45,6 +48,42 @@ public void testInvokeMapperFunc() {
}
}

@Test
public void testMapValidVersion() {
when(sidService.lookupFnr(anyList(), any(Optional.class))).thenReturn(Publishers.just(
Maps.of("11854898347", new SidInfo.SidInfoBuilder().snr("0001ha3").build()))
);
when(sidService.getSnapshots()).thenReturn(Publishers.just(
VersionInfo.builder().items(List.of("12345")).build()
));
try (var application = mockStatic(Application.class)) {
application.when(Application::getContext).thenReturn(context);
Mapper mapper = ServiceLoader.load(Mapper.class).findFirst().orElseThrow(() ->
new RuntimeException("SidMapper class not found"));
mapper.setConfig(Map.of("versionTimestamp", "12345"));
mapper.init("11854898347");
Object mappedSid = mapper.map("11854898347");
verify(sidService, times(1)).getSnapshots();
verify(sidService, times(1)).lookupFnr(anyList(), any(Optional.class));
Assertions.assertEquals("0001ha3", mappedSid);
}
}
@Test
public void testMapInvValidVersion() {
when(sidService.getSnapshots()).thenReturn(Publishers.just(
VersionInfo.builder().items(List.of("12345")).build()
));
try (var application = mockStatic(Application.class)) {
application.when(Application::getContext).thenReturn(context);
Mapper mapper = ServiceLoader.load(Mapper.class).findFirst().orElseThrow(() ->
new RuntimeException("SidMapper class not found"));
Exception exception = Assert.assertThrows(RuntimeException.class, () -> {
mapper.setConfig(Map.of("versionTimestamp", "1234567"));
});
Assertions.assertEquals("Invalid version timestamp. Valid versions are: 12345", exception.getMessage());
}
}

@MockBean(SidService.class)
SidService sidService() {
return mock(SidService.class);
Expand Down

0 comments on commit 4dd9856

Please sign in to comment.