Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for supplying a version timestamp to the 'map-sid' function #55

Merged
merged 5 commits into from
Sep 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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