Skip to content

Commit

Permalink
Feature/download orthophoto results (#225)
Browse files Browse the repository at this point in the history
  • Loading branch information
saschadoemer authored Aug 14, 2024
1 parent 8ff0060 commit 3fdf7d6
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 12 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@
</dependencies>

<build>
<finalName>application</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
Expand All @@ -182,7 +183,6 @@
<configuration>
<mainClass>de.app.fivegla.Application</mainClass>
<jvmArguments>-Dspring.application.admin.enabled=true</jvmArguments>
<finalName>application</finalName>
</configuration>
</plugin>
<plugin>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,4 +253,42 @@ public ResponseEntity<? extends Response> calculateCombinedImage(@PathVariable S
.build());
}

@Operation(
operationId = "images.download-combined-image",
description = "Downloads the combined image for the given transaction id.",
tags = BaseMappings.IMAGE_PROCESSING
)
@ApiResponse(
responseCode = "200",
description = "The combined image was found and returned.",
content = @Content(
mediaType = "application/zip",
schema = @Schema(implementation = byte[].class)
)
)
@ApiResponse(
responseCode = "400",
description = "The request is invalid.",
content = @Content(
mediaType = MediaType.APPLICATION_JSON_VALUE,
schema = @Schema(implementation = Response.class)
)
)
@GetMapping(value = "/{transactionId}/combined-image", produces = "application/zip")
public ResponseEntity<byte[]> downloadCombinedImage(@PathVariable String transactionId, Principal principal) {
var tenant = validateTenant(tenantService, principal);
var headers = new HttpHeaders();
headers.setCacheControl(CacheControl.noCache().getHeaderValue());
var orthophoto = orthophotoIntegrationService.getOrthophoto(tenant, transactionId);
AtomicReference<ResponseEntity<byte[]>> responseEntity = new AtomicReference<>(ResponseEntity.notFound().build());
orthophoto.ifPresent(
image -> {
var resultFileAsZip = orthophoto.get();
headers.setContentLength(resultFileAsZip.length);
responseEntity.set(ResponseEntity.ok().headers(headers).body(resultFileAsZip));
}
);
return responseEntity.get();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ public class ImageProcessingFiwareIntegrationServiceWrapper {
/**
* Create a new drone device measurement in FIWARE.
*
* @param image the image to create the measurement for
* @param image the image to create the measurement for
* @param transactionId the transaction id
*/
public void createDroneDeviceMeasurement(Tenant tenant, Group group, String droneId, Image image) {
public void createDroneDeviceMeasurement(Tenant tenant, Group group, String droneId, Image image, String transactionId) {
var deviceMeasurement = new MicaSenseImage(
tenant.getFiwarePrefix() + droneId,
EntityType.MICASENSE_IMAGE.getKey(),
Expand All @@ -40,7 +41,7 @@ public void createDroneDeviceMeasurement(Tenant tenant, Group group, String dron
new TextAttribute(image.getTransactionId()),
new TextAttribute(image.getChannel().name()),
new TextAttribute(image.getBase64encodedImage()),
new TextAttribute(imagePathBaseUrl + image.getFullFilename(tenant)),
new TextAttribute(imagePathBaseUrl + image.getFullFilename(tenant, transactionId)),
new TextAttribute(image.getMeasuredAt().toString()),
image.getLatitude(),
image.getLongitude());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public String processImage(Tenant tenant, Group group, String transactionId, Str
image.setBase64encodedImage(base64Image);
var micaSenseImage = imageRepository.save(image);
log.debug("Image with oid {} added to the application data.", micaSenseImage.getOid());
fiwareIntegrationServiceWrapper.createDroneDeviceMeasurement(tenant, group, droneId, micaSenseImage);
fiwareIntegrationServiceWrapper.createDroneDeviceMeasurement(tenant, group, droneId, micaSenseImage, transactionId);
persistentStorageIntegrationService.storeImage(transactionId, micaSenseImage);
return micaSenseImage.getOid();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import de.app.fivegla.api.ErrorMessage;
import de.app.fivegla.api.exceptions.BusinessException;
import de.app.fivegla.integration.imageprocessing.dto.TriggerOrthophotoProcessingResponse;
import de.app.fivegla.persistence.entity.Tenant;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
Expand All @@ -15,12 +16,15 @@
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.util.Optional;

@Slf4j
@Service
@RequiredArgsConstructor
public class OrthophotoIntegrationService {

private final RestTemplate restTemplate;
private final PersistentStorageIntegrationService persistentStorageIntegrationService;

@Value("${app.orthophoto.api-url}")
private String orthophotoProcessingApi;
Expand Down Expand Up @@ -72,4 +76,16 @@ public String triggerOrthophotoProcessing(String transactionId) {
.build());
}
}

/**
* Retrieves the orthophoto file for a given transaction ID.
*
* @param tenant The tenant for which the orthophoto file is requested.
* @param transactionId The ID of the transaction for which the orthophoto file is requested.
* @return An optional with the byte array representation of the orthophoto file if it exists,
* or an empty optional if the orthophoto file does not exist.
*/
public Optional<byte[]> getOrthophoto(Tenant tenant, String transactionId) {
return persistentStorageIntegrationService.getResultFile(tenant, transactionId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@
import de.app.fivegla.api.ErrorMessage;
import de.app.fivegla.api.exceptions.BusinessException;
import de.app.fivegla.persistence.entity.Image;
import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import de.app.fivegla.persistence.entity.Tenant;
import io.minio.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.ByteArrayInputStream;
import java.util.Optional;

@Slf4j
@Service
Expand Down Expand Up @@ -50,7 +49,7 @@ public void storeImage(String transactionId, Image image) {
var imageAsRawData = image.getImageAsRawData();
client.putObject(PutObjectArgs.builder()
.bucket(preConfiguredBucketName)
.object(image.getFullFilename(image.getTenant()))
.object(image.getFullFilename(image.getTenant(), transactionId))
.stream(new ByteArrayInputStream(imageAsRawData), imageAsRawData.length, -1)
.build());
} catch (Exception e) {
Expand All @@ -66,5 +65,34 @@ private MinioClient.Builder minioClientBuilder() {
.credentials(accessKey, secretKey);
}

/**
* Retrieves the result file from the S3 storage for the specified tenant and transaction ID.
*
* @param tenant The tenant associated with the result file.
* @param transactionId The transaction ID of the result file.
* @return An Optional containing the byte array of the result file if it exists, or an empty Optional if the result file does not exist or an error occurs.
*/
public Optional<byte[]> getResultFile(Tenant tenant, String transactionId) {
try (var client = minioClientBuilder()
.build()) {
var getObjectArgs = GetObjectArgs.builder()
.bucket(preConfiguredBucketName)
.object(getFileNameForResultFile(tenant, transactionId))
.build();
var getObjectResponse = client.getObject(getObjectArgs);
if (getObjectResponse != null) {
return Optional.of(getObjectResponse.readAllBytes());
} else {
return Optional.empty();
}
} catch (Exception e) {
log.error("Could not get result file from S3.", e);
return Optional.empty();
}
}

private String getFileNameForResultFile(Tenant tenant, String transactionId) {
return tenant.getTenantId() + "/" + transactionId + "/result.zip";
}
}

4 changes: 2 additions & 2 deletions src/main/java/de/app/fivegla/persistence/entity/Image.java
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public byte[] getImageAsRawData() {
*
* @return the name of the image
*/
public String getFullFilename(Tenant tenant) {
return tenant.getTenantId() + "/" + droneId + "/" + channel.name() + "/" + measuredAt.toInstant().getEpochSecond() + ".tiff";
public String getFullFilename(Tenant tenant, String transactionId) {
return tenant.getTenantId() + "/" + transactionId + "/" + droneId + "_" + channel.name() + "_" + measuredAt.toInstant().getEpochSecond() + ".tiff";
}
}

0 comments on commit 3fdf7d6

Please sign in to comment.