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

Fix #248: Add support for tagging imported photos #250

Merged
merged 1 commit into from
Oct 1, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import lombok.Builder;
import lombok.extern.jackson.Jacksonized;

import java.util.Map;

/**
* Photo import model class.
*
Expand All @@ -32,6 +34,7 @@ public record PhotoImportDto(
String userId,
String photoDataType,
String photoType,
String photoData
String photoData,
Map<String, Object> attributes

) { }
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@
*/
package com.wultra.security.userdatastore.client.model.request;

import com.wultra.security.userdatastore.client.model.validation.constraints.Base64;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.Builder;
import lombok.extern.jackson.Jacksonized;

import java.util.Map;

/**
* Request class for import of photos.
*
Expand All @@ -39,6 +40,7 @@ public record EmbeddedPhotoImportRequest(
@NotBlank @Size(max = 32)
String photoType,
@NotBlank
String photoData
String photoData,
Map<String, Object> attributes

) { }
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import lombok.extern.jackson.Jacksonized;

import java.util.List;
import java.util.Map;

/**
* Request class for importing photos from CSV files.
Expand All @@ -33,6 +34,7 @@
public record PhotosImportCsvRequest(

@Valid
List<String> importPaths
List<String> importPaths,
Map<String, Object> attributes

) { }
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public PhotoImportDto toPhotoImport(final EmbeddedPhotoImportRequest photo) {
.photoDataType(photo.photoDataType())
.photoType(photo.photoType())
.photoData(photo.photoData())
.attributes(photo.attributes())
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,21 +67,21 @@ public List<PhotoImportResultDto> importPhotos(final List<PhotoImportDto> photos
return photos.stream().map(this::importPhoto).toList();
}

public void importPhotosCsv(final List<String> csvPaths) {
csvPaths.forEach(this::importCsv);
public void importPhotosCsv(final List<String> csvPaths, final Map<String, Object> attributes) {
csvPaths.forEach(path -> importCsv(path, attributes));
}

private void importCsv(final String csvPath) {
private void importCsv(final String csvPath, Map<String, Object> attributes) {
final FetchResult result = fetchFromPath(csvPath);
if (result.error == null) {
final List<List<String>> parsedData = parseCsv(result.data);
if (parsedData != null) {
parsedData.forEach(this::importCsvRow);
parsedData.forEach(data -> importCsvRow(data, attributes));
}
}
}

private void importCsvRow(final List<String> csvRow) {
private void importCsvRow(final List<String> csvRow, final Map<String, Object> attributes) {
if (csvRow.size() != 4) {
logger.warn("Invalid CSV import format");
return;
Expand All @@ -91,6 +91,7 @@ private void importCsvRow(final List<String> csvRow) {
.photoDataType(csvRow.get(1))
.photoType(csvRow.get(2))
.photoData(csvRow.get(3))
.attributes(attributes)
.build();
importPhoto(photo);
}
Expand All @@ -113,7 +114,7 @@ private PhotoImportResultDto importPhoto(final PhotoImportDto photo) {
persistImportResult(handleError(photo.userId(), photo.photoType(), result.error));
}

return createNewPhoto(photo.userId(), photo.photoType(), result.importPath, result.data);
return createNewPhoto(photo.userId(), photo.photoType(), result.importPath, result.data, photo.attributes());
}

public static List<List<String>> parseCsv(byte[] csvData) {
Expand All @@ -136,7 +137,7 @@ public static List<List<String>> parseCsv(byte[] csvData) {
return parsedData;
}

private PhotoImportResultDto createNewPhoto(final String userId, final String photoType, final String importPath, final byte[] photoBase64) {
private PhotoImportResultDto createNewPhoto(final String userId, final String photoType, final String importPath, final byte[] photoBase64, final Map<String, Object> attributes) {
final EmbeddedPhotoCreateRequest photoCreateRequest = EmbeddedPhotoCreateRequest.builder()
.photoType(photoType)
.photoData(new String(photoBase64, StandardCharsets.UTF_8))
Expand All @@ -146,6 +147,7 @@ private PhotoImportResultDto createNewPhoto(final String userId, final String ph
.documentType("data")
.dataType("image_base64")
.documentData("{}")
.attributes(attributes)
.photos(Collections.singletonList(photoCreateRequest))
.build();
final DocumentCreateResponse response = documentService.createDocument(documentCreateRequest);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ public PhotosImportResponse importPhotos(PhotosImportRequest requestObject) {
@Transactional
@Async
public void importPhotosCsv(PhotosImportCsvRequest requestObject) {
photoImportService.importPhotosCsv(requestObject.importPaths());
photoImportService.importPhotosCsv(requestObject.importPaths(), requestObject.attributes());
}

private void audit(final String message, final String userId, final String documentId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ void testPhotoImportBase64Inline() throws Exception {
.photoDataType("base64_inline")
.photoType("person")
.photoData(PHOTO_BASE_64)
.attributes(Map.of("tag", "test"))
.build();
PhotosImportRequest importRequest = PhotosImportRequest.builder()
.photos(Collections.singletonList(photoImportRequest))
Expand All @@ -165,6 +166,7 @@ void testPhotoImportFileBase64() throws Exception {
.photoDataType("base64")
.photoType("person")
.photoData(tempFile.toAbsolutePath().toString())
.attributes(Map.of("tag", "test"))
.build();
PhotosImportRequest importRequest = PhotosImportRequest.builder()
.photos(Collections.singletonList(photoImportRequest))
Expand All @@ -183,6 +185,7 @@ void testPhotoImportFileRaw() throws Exception {
.photoDataType("raw")
.photoType("person")
.photoData(tempFile.toAbsolutePath().toString())
.attributes(Map.of("tag", "test"))
.build();
PhotosImportRequest importRequest = PhotosImportRequest.builder()
.photos(Collections.singletonList(photoImportRequest))
Expand All @@ -198,6 +201,7 @@ void testPhotoImportUrl() throws Exception {
.photoDataType("raw")
.photoType("person")
.photoData("http://localhost:" + serverPort + "/user-data-store/swagger-ui/favicon-32x32.png")
.attributes(Map.of("tag", "test"))
.build();
PhotosImportRequest importRequest = PhotosImportRequest.builder()
.photos(Collections.singletonList(photoImportRequest))
Expand All @@ -213,6 +217,7 @@ void testPhotoImportCsvBase64Inline() throws Exception {
"\n" + "user_test_b64i_456,base64_inline,person," + PHOTO_BASE_64);
PhotosImportCsvRequest importRequest = PhotosImportCsvRequest.builder()
.importPaths(Collections.singletonList(tempFile.toAbsolutePath().toString()))
.attributes(Map.of("tag", "test"))
.build();
restClient.importPhotosCsv(importRequest);
verifyImportCsv(Arrays.asList("user_test_b64i_123", "user_test_b64i_456"), PHOTO_BASE_64);
Expand All @@ -229,6 +234,7 @@ void testPhotoImportCsvBase64() throws Exception {
"\n" + "user_test_b64_456,base64,person," + photo2.toAbsolutePath());
PhotosImportCsvRequest importRequest = PhotosImportCsvRequest.builder()
.importPaths(Collections.singletonList(tempFile.toAbsolutePath().toString()))
.attributes(Map.of("tag", "test"))
.build();
restClient.importPhotosCsv(importRequest);
verifyImportCsv(Arrays.asList("user_test_b64_123", "user_test_b64_456"), PHOTO_BASE_64);
Expand All @@ -245,6 +251,7 @@ void testPhotoImportCsvRaw() throws Exception {
"\n" + "user_test_raw_456,raw,person," + photo2.toAbsolutePath());
PhotosImportCsvRequest importRequest = PhotosImportCsvRequest.builder()
.importPaths(Collections.singletonList(tempFile.toAbsolutePath().toString()))
.attributes(Map.of("tag", "test"))
.build();
restClient.importPhotosCsv(importRequest);
verifyImportCsv(Arrays.asList("user_test_raw_123", "user_test_raw_456"), PHOTO_BASE_64);
Expand All @@ -256,6 +263,7 @@ void testPhotoImportCsvUrl() throws Exception {
Files.writeString(tempFile, "user_test_url,raw,person,http://localhost:" + serverPort + "/user-data-store/swagger-ui/favicon-32x32.png");
PhotosImportCsvRequest importRequest = PhotosImportCsvRequest.builder()
.importPaths(Collections.singletonList(tempFile.toAbsolutePath().toString()))
.attributes(Map.of("tag", "test"))
.build();
restClient.importPhotosCsv(importRequest);
verifyImportCsv(List.of("user_test_url"), PHOTO2_BASE_64);
Expand All @@ -274,6 +282,7 @@ void largeImageImportCsvRawTest() throws Exception {
Files.writeString(tempFile, "user_large_image_test,raw,person," + photoFile.toAbsolutePath());
PhotosImportCsvRequest importRequest = PhotosImportCsvRequest.builder()
.importPaths(Collections.singletonList(tempFile.toAbsolutePath().toString()))
.attributes(Map.of("tag", "test"))
.build();
restClient.importPhotosCsv(importRequest);
verifyImportCsv(List.of("user_large_image_test"), imageBase64);
Expand All @@ -299,6 +308,7 @@ void largeImagesImportCsvBase64InlineTest() throws Exception {
}
PhotosImportCsvRequest importRequest = PhotosImportCsvRequest.builder()
.importPaths(Collections.singletonList(tempFile.toAbsolutePath().toString()))
.attributes(Map.of("tag", "test"))
.build();
restClient.importPhotosCsv(importRequest);
userIds.forEach(userId -> verifyImportCsv(List.of(userId), images.get(userId)));
Expand All @@ -324,6 +334,8 @@ private void verifyImportResponse(PhotosImportResponse response, String expected
assertNotNull(result.photoId());
assertTrue(result.imported());
assertNull(result.error());
DocumentResponse documentResponse = restClient.fetchDocuments("alice", result.documentId());
assertEquals(Map.of("tag", "test"), documentResponse.documents().get(0).attributes());
PhotoResponse photoResponse = restClient.fetchPhotos("alice", result.documentId());
assertEquals(1, photoResponse.photos().size());
PhotoDto photo = photoResponse.photos().get(0);
Expand All @@ -347,6 +359,7 @@ private void verifyImportCsv(List<String> userIds, String expectedPhotoBase64) {

private void verifyImportCsv(String userId, String expectedPhotoBase64) throws UserDataStoreClientException {
DocumentResponse documentResponse = restClient.fetchDocuments(userId, null);
assertEquals(Map.of("tag", "test"), documentResponse.documents().get(0).attributes());
PhotoResponse photoResponse = restClient.fetchPhotos(userId, documentResponse.documents().get(0).id());
assertEquals(1, photoResponse.photos().size());
PhotoDto photo = photoResponse.photos().get(0);
Expand Down