Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • fit-connect/sdk-java
1 result
Show changes
Commits on Source (7)
Showing
with 1142 additions and 400 deletions
package de.fitko.fitconnect.api.config;
import de.fitko.fitconnect.api.exceptions.InitializationException;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Map;
import java.util.stream.Collectors;
@Data
@Builder
......@@ -15,24 +17,35 @@ public class ApplicationConfig {
@Builder.Default
private String httpProxyHost = "";
@Builder.Default
private Integer httpProxyPort = 0;
@Builder.Default
@Builder.Default
private Integer requestTimeoutInSeconds = 30;
private String metadataSchemaPath;
private String privateSigningKeyPath;
@Builder.Default
private String metadataSchemaPath = "";
@Builder.Default
private String privateSigningKeyPath = "";
private SenderConfig senderConfig;
private SubscriberConfig subscriberConfig;
private Map<EnvironmentName, Environment> environments;
private EnvironmentName activeEnvironment;
private ResourcePaths resourcePaths;
public Environment getEnvironmentByName(final EnvironmentName environmentName) {
return environments.get(environmentName);
if (environments.containsKey(environmentName)) {
return environments.get(environmentName);
} else {
throw new InitializationException("No environment with name '" + environmentName.getName() + "' found. Available environments are: " + getAvailableEnvironmentNames());
}
}
public Environment getCurrentEnvironment() {
......@@ -70,5 +83,12 @@ public class ApplicationConfig {
private String getSubmissionBaseUrl() {
return getCurrentEnvironment().getSubmissionBaseUrl();
}
private String getAvailableEnvironmentNames() {
return environments.keySet()
.stream()
.map(EnvironmentName::getName)
.collect(Collectors.joining(" | "));
}
}
......@@ -7,15 +7,12 @@ import de.fitko.fitconnect.api.domain.model.metadata.attachment.Attachment;
import de.fitko.fitconnect.api.domain.model.metadata.attachment.AttachmentWithData;
import de.fitko.fitconnect.api.domain.model.metadata.attachment.signature.Hash__1;
import de.fitko.fitconnect.api.domain.model.metadata.data.Data;
import de.fitko.fitconnect.api.domain.model.metadata.data.MimeType;
import de.fitko.fitconnect.api.domain.model.submission.Submission;
import de.fitko.fitconnect.api.domain.model.submission.SubmissionForPickup;
import de.fitko.fitconnect.api.domain.validation.ValidationResult;
import de.fitko.fitconnect.api.exceptions.*;
import de.fitko.fitconnect.api.services.Subscriber;
import lombok.Builder;
import lombok.Getter;
import lombok.ToString;
import de.fitko.fitconnect.client.model.ReceivedSubmission;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -244,12 +241,4 @@ public final class SubscriberClient {
}
}
@Getter
@Builder
@ToString
public static class ReceivedSubmission {
String data;
MimeType mimeType;
List<AttachmentWithData> attachments;
}
}
......@@ -3,6 +3,7 @@ package de.fitko.fitconnect.client.cmd;
import com.beust.jcommander.JCommander;
import com.beust.jcommander.ParameterException;
import de.fitko.fitconnect.api.domain.model.metadata.attachment.AttachmentWithData;
import de.fitko.fitconnect.client.model.ReceivedSubmission;
import de.fitko.fitconnect.client.SenderClient;
import de.fitko.fitconnect.client.SubscriberClient;
import de.fitko.fitconnect.client.cmd.commands.ListAllSubmissionsCommand;
......@@ -17,6 +18,7 @@ import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.stream.Collectors;
import static de.fitko.fitconnect.client.cmd.util.AttachmentDataType.JSON;
......@@ -32,10 +34,10 @@ public class CommandLineClient {
private final JCommander jc;
private final SenderClient.WithDestination senderClient;
private final SenderClient.Start senderClient;
private final SubscriberClient.RequestSubmission subscriberClient;
public CommandLineClient(final SenderClient.WithDestination senderClient,
public CommandLineClient(final SenderClient.Start senderClient,
final SubscriberClient.RequestSubmission subscriberClient) {
this.sendSubmissionCommand = new SendSubmissionCommand();
......@@ -108,17 +110,32 @@ public class CommandLineClient {
private void sendSubmission(final SendSubmissionCommand sendSubmissionCommand) {
LOGGER.info("Sending new submission to destination {}", sendSubmissionCommand.destinationId);
final var client = senderClient
.withDestination(sendSubmissionCommand.destinationId)
.withServiceType(sendSubmissionCommand.serviceName, sendSubmissionCommand.leikaKey)
.withAttachments(sendSubmissionCommand.attachments.stream().map(File::new).collect(Collectors.toList()));
final List<File> files = sendSubmissionCommand.attachments.stream().map(File::new).collect(Collectors.toList());
if (sendSubmissionCommand.dataType == JSON) {
client.withJsonData(sendSubmissionCommand.data).submit();
sendWithJsonData(sendSubmissionCommand, files);
} else if (sendSubmissionCommand.dataType == XML) {
client.withXmlData(sendSubmissionCommand.data).submit();
sendWithXmlData(sendSubmissionCommand, files);
}
}
private void sendWithXmlData(final SendSubmissionCommand sendSubmissionCommand, final List<File> files) {
senderClient.newSubmission()
.withAttachments(files)
.withXmlData(sendSubmissionCommand.data)
.withDestination(sendSubmissionCommand.destinationId)
.withServiceType(sendSubmissionCommand.serviceName, sendSubmissionCommand.leikaKey)
.submit();
}
private void sendWithJsonData(final SendSubmissionCommand sendSubmissionCommand, final List<File> files) {
senderClient.newSubmission()
.withAttachments(files)
.withJsonData(sendSubmissionCommand.data)
.withDestination(sendSubmissionCommand.destinationId)
.withServiceType(sendSubmissionCommand.serviceName, sendSubmissionCommand.leikaKey)
.submit();
}
private String getTargetFolderPath(final ListOneSubmissionCommand listOneSubmissionCommand) {
if (listOneSubmissionCommand.targetFolder != null) {
return listOneSubmissionCommand.targetFolder + "/" + listOneSubmissionCommand.submissionId;
......@@ -127,7 +144,7 @@ public class CommandLineClient {
}
}
private void writeData(final SubscriberClient.ReceivedSubmission submissionData, final String dataDirPath) throws IOException {
private void writeData(final ReceivedSubmission submissionData, final String dataDirPath) throws IOException {
LOGGER.info("Creating data directory for submission in {}", dataDirPath);
Files.createDirectories(Path.of(dataDirPath));
......
......@@ -58,7 +58,7 @@ public final class ClientFactory {
*
* @return the sender client
*/
public static SenderClient.WithDestination senderClient() {
public static SenderClient.Start senderClient() {
final ApplicationConfig config = loadConfig();
return senderClient(config);
}
......@@ -68,7 +68,7 @@ public final class ClientFactory {
*
* @return the sender client
*/
public static SenderClient.WithDestination senderClient(final ApplicationConfig config) {
public static SenderClient.Start senderClient(final ApplicationConfig config) {
LOGGER.info(SENDER_BANNER);
LOGGER.info("Initializing sender client ...");
final Sender sender = getSender(config);
......
package de.fitko.fitconnect.client.model;
import lombok.Builder;
import lombok.Getter;
import lombok.With;
import java.io.File;
import java.util.UUID;
@With
@Getter
@Builder
public class AttachmentPayload {
private File file;
private byte[] rawData;
private String hashedData;
private String encryptedData;
private String mimeType;
private UUID attachmentId;
}
package de.fitko.fitconnect.client.model;
import de.fitko.fitconnect.api.domain.model.metadata.data.MimeType;
import lombok.Builder;
import lombok.Getter;
import lombok.With;
import java.net.URI;
@With
@Getter
@Builder
public class DataPayload {
private byte[] rawData;
private String hashedData;
private String encryptedData;
private MimeType mimeType;
private URI schemaUri;
}
package de.fitko.fitconnect.client.model;
import de.fitko.fitconnect.api.domain.model.metadata.attachment.AttachmentWithData;
import de.fitko.fitconnect.api.domain.model.metadata.data.MimeType;
import lombok.Builder;
import lombok.Getter;
import lombok.ToString;
import java.util.List;
@Getter
@Builder
@ToString
public class ReceivedSubmission {
private String data;
private MimeType mimeType;
private List<AttachmentWithData> attachments;
}
package de.fitko.fitconnect.client.model;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class ServiceTypePayload {
private String name;
private String description;
private String leikaKey;
}
package de.fitko.fitconnect.client.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.With;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
@Data
@With
@AllArgsConstructor
@NoArgsConstructor
public class SubmissionPayload {
private UUID destinationId;
private DataPayload data;
private String encryptedMetadata;
private ServiceTypePayload serviceTypePayLoad;
// Optional - default empty List
private List<AttachmentPayload> attachments = Collections.emptyList();
private List<String> encryptedAttachments = Collections.emptyList();
}
package de.fitko.fitconnect.client.strategies;
import de.fitko.fitconnect.api.domain.model.submission.CreateSubmission;
import de.fitko.fitconnect.api.domain.model.submission.SubmissionForPickup;
import de.fitko.fitconnect.api.domain.model.submission.SubmitSubmission;
import de.fitko.fitconnect.api.exceptions.RestApiException;
import de.fitko.fitconnect.api.exceptions.SubmissionNotCreatedException;
import de.fitko.fitconnect.api.services.Sender;
import de.fitko.fitconnect.client.model.AttachmentPayload;
import de.fitko.fitconnect.client.model.SubmissionPayload;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import static de.fitko.fitconnect.client.util.SubmissionUtil.buildSubmissionToAnnounce;
import static de.fitko.fitconnect.client.util.SubmissionUtil.buildSubmitSubmission;
public class SendEncryptedSubmissionStrategy implements SubmitStrategy {
private static final Logger LOGGER = LoggerFactory.getLogger(SendEncryptedSubmissionStrategy.class);
private final Sender sender;
public SendEncryptedSubmissionStrategy(final Sender sender) {
this.sender = sender;
}
@Override
public Optional<SubmitSubmission> send(final SubmissionPayload submissionPayload) {
if (!hasValidPayload(submissionPayload)) {
return Optional.empty();
}
try {
final UUID submissionId = announceNewSubmission(submissionPayload);
final SubmitSubmission submission = buildSubmitSubmission(submissionPayload, submissionId);
uploadAttachments(submissionPayload.getAttachments(), submissionId);
sender.sendSubmission(submission);
LOGGER.info("SUCCESSFULLY HANDED IN SUBMISSION !");
return Optional.of(submission);
} catch (final RestApiException e) {
LOGGER.error("Sending submission failed", e);
} catch (final SubmissionNotCreatedException e) {
LOGGER.error("Failed to announce new submission", e);
}
return Optional.empty();
}
private UUID announceNewSubmission(final SubmissionPayload submissionPayload) {
final CreateSubmission submissionToAnnounce = buildSubmissionToAnnounce(submissionPayload);
final SubmissionForPickup announcedSubmission = sender.createSubmission(submissionToAnnounce);
return announcedSubmission.getSubmissionId();
}
private void uploadAttachments(final List<AttachmentPayload> attachmentPayloads, final UUID submissionId) {
if (attachmentPayloads.isEmpty()) {
LOGGER.info("No attachments to upload");
} else {
LOGGER.info("Uploading {} attachment(s)", attachmentPayloads.size());
}
for (final AttachmentPayload payload : attachmentPayloads) {
sender.uploadAttachment(submissionId, payload.getAttachmentId(), payload.getEncryptedData());
}
}
@Override
public boolean hasValidPayload(final SubmissionPayload submissionPayload) {
if (submissionPayload.getData().getEncryptedData() == null) {
LOGGER.error("Data is mandatory, but was null.");
return false;
} else if (submissionPayload.getEncryptedMetadata() == null) {
LOGGER.error("Metadata is mandatory, but was null.");
return false;
} else if (submissionPayload.getServiceTypePayLoad().getName() == null) {
LOGGER.error("Service type name is mandatory, but was null.");
return false;
} else if (submissionPayload.getServiceTypePayLoad().getLeikaKey() == null) {
LOGGER.error("Service type identifier is mandatory, but was null.");
return false;
} else if (submissionPayload.getDestinationId() == null) {
LOGGER.error("DestinationId is mandatory, but was null.");
return false;
} else {
return true;
}
}
}
package de.fitko.fitconnect.client.strategies;
import com.nimbusds.jose.jwk.RSAKey;
import de.fitko.fitconnect.api.config.Environment;
import de.fitko.fitconnect.api.domain.model.destination.Destination;
import de.fitko.fitconnect.api.domain.model.destination.DestinationService;
import de.fitko.fitconnect.api.domain.model.metadata.Metadata;
import de.fitko.fitconnect.api.domain.model.metadata.PublicServiceType;
import de.fitko.fitconnect.api.domain.model.metadata.attachment.Attachment;
import de.fitko.fitconnect.api.domain.model.metadata.data.Data;
import de.fitko.fitconnect.api.domain.model.metadata.data.MimeType;
import de.fitko.fitconnect.api.domain.model.metadata.data.SubmissionSchema;
import de.fitko.fitconnect.api.domain.model.submission.CreateSubmission;
import de.fitko.fitconnect.api.domain.model.submission.ServiceType;
import de.fitko.fitconnect.api.domain.model.submission.SubmissionForPickup;
import de.fitko.fitconnect.api.domain.model.submission.SubmitSubmission;
import de.fitko.fitconnect.api.domain.validation.ValidationResult;
import de.fitko.fitconnect.api.exceptions.*;
import de.fitko.fitconnect.api.services.Sender;
import de.fitko.fitconnect.client.model.AttachmentPayload;
import de.fitko.fitconnect.client.model.DataPayload;
import de.fitko.fitconnect.client.model.ServiceTypePayload;
import de.fitko.fitconnect.client.model.SubmissionPayload;
import de.fitko.fitconnect.client.util.SubmissionUtil;
import org.apache.tika.Tika;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collectors;
public class SendNewSubmissionStrategy implements SubmitStrategy {
private static final Logger LOGGER = LoggerFactory.getLogger(SendNewSubmissionStrategy.class);
private final Sender sender;
private final String metadataSchema;
private final Environment environment;
public SendNewSubmissionStrategy(final Sender sender, final String metadataSchema, final Environment environment) {
this.sender = sender;
this.metadataSchema = metadataSchema;
this.environment = environment;
}
@Override
public Optional<SubmitSubmission> send(final SubmissionPayload submissionPayload) {
if (!hasValidPayload(submissionPayload)) return Optional.empty();
final UUID destinationId = submissionPayload.getDestinationId();
final ServiceTypePayload serviceTypePayLoad = submissionPayload.getServiceTypePayLoad();
final DataPayload userDataPayload = submissionPayload.getData();
final List<AttachmentPayload> attachments = submissionPayload.getAttachments();
try {
/** Get encryption key for destination **/
final Destination destination = sender.getDestination(destinationId);
final RSAKey encryptionKey = sender.getEncryptionKeyForDestination(destinationId, destination.getEncryptionKid());
final ValidationResult validationResult = sender.validatePublicKey(encryptionKey);
if (validationResult.hasError()) {
LOGGER.warn("The public key is not valid, {}", validationResult.getError().getMessage());
if (!environment.isSilentKeyValidation()) {
return Optional.empty();
}
}
/** Create new submission and announce attachments **/
final List<AttachmentPayload> encryptedAttachments = encryptAndHashAttachments(encryptionKey, attachments);
final CreateSubmission newSubmission = buildSubmissionToAnnounce(destinationId, serviceTypePayLoad, encryptedAttachments);
final SubmissionForPickup announcedSubmission = sender.createSubmission(newSubmission);
final UUID submissionId = announcedSubmission.getSubmissionId();
uploadAttachments(encryptedAttachments, submissionId);
/** Create attachment metadata including hashes **/
final List<Attachment> attachmentMetadata = SubmissionUtil.toAttachmentMetadata(encryptedAttachments);
/** Build encrypted data payload from user data**/
LOGGER.info("Adding data payload with mime-type {} to submission", userDataPayload.getMimeType());
final DataPayload encryptedDataPayload = encryptDataPayload(userDataPayload, destination, encryptionKey);
/** Set encrypted metadata with data payload and attachments **/
final Data dataToSend = SubmissionUtil.buildData(encryptedDataPayload);
final PublicServiceType publicServiceType = SubmissionUtil.buildPublicServiceType(serviceTypePayLoad);
final Metadata metadata = SubmissionUtil.buildMetadata(attachmentMetadata, dataToSend, publicServiceType);
final ValidationResult validatedMetadata = sender.validateMetadata(metadata, metadataSchema);
if (validatedMetadata.hasError()) {
LOGGER.error("Metadata does not match schema", validatedMetadata.getError());
sender.rejectSubmission(submissionId, destinationId, announcedSubmission.getCaseId());
return Optional.empty();
}
/** Prepare submit submission with announced submission id **/
final SubmitSubmission submission = new SubmitSubmission();
submission.setSubmissionId(submissionId);
submission.setEncryptedData(encryptedDataPayload.getEncryptedData());
submission.setEncryptedMetadata(sender.encryptObject(encryptionKey, metadata));
/** Submit submission **/
sender.sendSubmission(submission);
LOGGER.info("SUCCESSFULLY HANDED IN SUBMISSION !");
return Optional.of(submission);
} catch (final EncryptionException e) {
LOGGER.error("Encrypting submission failed", e);
} catch (final RestApiException e) {
LOGGER.error("Sending submission failed", e);
} catch (final SchemaNotFoundException e) {
LOGGER.error("Required schema to send valid submission not found", e);
} catch (final SubmissionNotCreatedException e) {
LOGGER.error("Failed to announce new submission", e);
} catch (final KeyNotRetrievedException e) {
LOGGER.error("Getting encryption key for destination {} failed", destinationId, e);
} catch (final AttachmentCreationException e) {
LOGGER.error("Reading file failed. Attachment will not be created.", e);
}
return Optional.empty();
}
@Override
public boolean hasValidPayload(final SubmissionPayload submissionPayload) {
if (submissionPayload.getData().getRawData() == null) {
LOGGER.error("Data is mandatory, but was null.");
return false;
} else if (submissionPayload.getServiceTypePayLoad().getName() == null) {
LOGGER.error("Service type name is mandatory, but was null.");
return false;
} else if (submissionPayload.getServiceTypePayLoad().getLeikaKey() == null) {
LOGGER.error("Service type identifier is mandatory, but was null.");
return false;
} else if (submissionPayload.getDestinationId() == null) {
LOGGER.error("DestinationId is mandatory, but was null.");
return false;
} else {
return true;
}
}
private DataPayload encryptDataPayload(final DataPayload dataPayload, final Destination destination, final RSAKey encryptionKey) {
final List<SubmissionSchema> submissionSchemas = getSubmissionSchemasFromDestination(destination);
final Optional<URI> schemaUriForMimeType = getSchemaUriForMimeType(submissionSchemas, dataPayload.getMimeType());
if (schemaUriForMimeType.isEmpty()) {
throw new SchemaNotFoundException("No data schema for mime-type " + dataPayload.getMimeType() + " found, please check the allowed type for destination");
}
final String hashedData = sender.createHash(dataPayload.getRawData());
final String encryptedData = sender.encryptBytes(encryptionKey, dataPayload.getRawData());
return dataPayload.withSchemaUri(schemaUriForMimeType.get())
.withEncryptedData(encryptedData)
.withHashedData(hashedData);
}
private List<SubmissionSchema> getSubmissionSchemasFromDestination(final Destination destination) {
return destination.getServices().stream()
.map(DestinationService::getSubmissionSchemas)
.flatMap(Collection::stream)
.collect(Collectors.toList());
}
private Optional<URI> getSchemaUriForMimeType(final List<SubmissionSchema> submissionSchemas, final MimeType mimeType) {
return submissionSchemas.stream()
.filter(schema -> schema.getMimeType().equals(mimeType))
.map(SubmissionSchema::getSchemaUri)
.findFirst();
}
private void uploadAttachments(final List<AttachmentPayload> attachmentPayloads, final UUID submissionId) {
if (attachmentPayloads.isEmpty()) {
LOGGER.info("No attachments to upload");
} else {
LOGGER.info("Uploading {} attachment(s)", attachmentPayloads.size());
}
for (final AttachmentPayload payload : attachmentPayloads) {
sender.uploadAttachment(submissionId, payload.getAttachmentId(), payload.getEncryptedData());
}
}
private CreateSubmission buildSubmissionToAnnounce(final UUID destinationId, final ServiceTypePayload serviceTypePayLoad, final List<AttachmentPayload> encryptedAttachments) {
final ServiceType serviceType = SubmissionUtil.buildServiceType(serviceTypePayLoad);
final List<UUID> attachmentIdsToAnnounce = SubmissionUtil.toAttachmentIds(encryptedAttachments);
return SubmissionUtil.createSubmission(destinationId, serviceType, attachmentIdsToAnnounce);
}
private List<AttachmentPayload> encryptAndHashAttachments(final RSAKey encryptionKey, final List<AttachmentPayload> attachments) {
return attachments.stream()
.filter(Objects::nonNull)
.map(this::readRawData)
.map(this::hashBytes)
.map(payload -> encryptBytes(encryptionKey, payload))
.map(this::setMimeType)
.collect(Collectors.toList());
}
private AttachmentPayload readRawData(final AttachmentPayload attachmentPayload) {
final File file = attachmentPayload.getFile();
try {
final byte[] rawData = Files.readAllBytes(Paths.get(file.getPath()));
return attachmentPayload.withRawData(rawData);
} catch (final IOException e) {
throw new AttachmentCreationException("Attachment '" + file.getAbsolutePath() + "' could not be read ", e);
}
}
private AttachmentPayload encryptBytes(final RSAKey encryptionKey, final AttachmentPayload attachmentPayload) {
final String encryptedAttachment = sender.encryptBytes(encryptionKey, attachmentPayload.getRawData());
return attachmentPayload.withEncryptedData(encryptedAttachment);
}
private AttachmentPayload hashBytes(final AttachmentPayload attachmentPayload) {
final String hashedBytes = sender.createHash(attachmentPayload.getRawData());
return attachmentPayload.withHashedData(hashedBytes);
}
private AttachmentPayload setMimeType(final AttachmentPayload attachmentPayload) {
final File file = attachmentPayload.getFile();
String mimeType;
try {
final Tika mimeTypeGuesser = new Tika();
mimeType = mimeTypeGuesser.detect(file);
} catch (final IOException e) {
mimeType = URLConnection.guessContentTypeFromName(file.getName());
}
LOGGER.info("Detected attachment mime-type {}", mimeType);
return attachmentPayload.withMimeType(mimeType);
}
}
package de.fitko.fitconnect.client.strategies;
import de.fitko.fitconnect.api.domain.model.submission.SubmitSubmission;
import de.fitko.fitconnect.client.model.SubmissionPayload;
import java.util.Optional;
/**
* Provides different strategies for assembling, announcing and handing in a new submission.
*/
public interface SubmitStrategy {
/**
* Send a submission based on specific assumptions on how the submission is assembled.
*
* @param submissionPayload all necessary data for creating and submitting a submission
*
* @return {@link SubmitSubmission}, empty if a validation error or technical error occurred.
*/
Optional<SubmitSubmission> send(SubmissionPayload submissionPayload);
/**
* Validate the payload to be sufficient for submission.
*
* @param submissionPayload payload of all data needed to create a submission
*
* @return true if all checks apply, false if data is missing
*/
boolean hasValidPayload(SubmissionPayload submissionPayload);
}
package de.fitko.fitconnect.client.util;
import de.fitko.fitconnect.api.domain.model.metadata.ContentStructure;
import de.fitko.fitconnect.api.domain.model.metadata.Metadata;
import de.fitko.fitconnect.api.domain.model.metadata.PublicServiceType;
import de.fitko.fitconnect.api.domain.model.metadata.attachment.Attachment;
import de.fitko.fitconnect.api.domain.model.metadata.attachment.Purpose;
import de.fitko.fitconnect.api.domain.model.metadata.attachment.signature.AttachmentSignatureType;
import de.fitko.fitconnect.api.domain.model.metadata.attachment.signature.Hash__1;
import de.fitko.fitconnect.api.domain.model.metadata.data.Data;
import de.fitko.fitconnect.api.domain.model.metadata.data.DataSignatureType;
import de.fitko.fitconnect.api.domain.model.metadata.data.Hash;
import de.fitko.fitconnect.api.domain.model.metadata.data.SubmissionSchema;
import de.fitko.fitconnect.api.domain.model.submission.CreateSubmission;
import de.fitko.fitconnect.api.domain.model.submission.ServiceType;
import de.fitko.fitconnect.api.domain.model.submission.SubmitSubmission;
import de.fitko.fitconnect.client.model.AttachmentPayload;
import de.fitko.fitconnect.client.model.DataPayload;
import de.fitko.fitconnect.client.model.ServiceTypePayload;
import de.fitko.fitconnect.client.model.SubmissionPayload;
import de.fitko.fitconnect.core.util.Strings;
import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.Function;
import java.util.stream.Collectors;
public final class SubmissionUtil {
public static CreateSubmission createSubmission(final UUID destinationId, final ServiceType serviceType, final List<UUID> attachmentIdsToAnnounce) {
return CreateSubmission.builder()
.destinationId(destinationId)
.announcedAttachments(attachmentIdsToAnnounce)
.serviceType(serviceType)
.build();
}
public static ServiceType buildServiceType(final ServiceTypePayload serviceTypePayload) {
final var serviceType = new ServiceType();
serviceType.setName(serviceTypePayload.getName());
serviceType.setIdentifier(serviceTypePayload.getLeikaKey());
if (!Strings.isNullOrEmpty(serviceTypePayload.getDescription())) {
serviceType.setDescription(serviceTypePayload.getDescription());
}
return serviceType;
}
public static PublicServiceType buildPublicServiceType(final ServiceTypePayload serviceTypePayload) {
final var publicServiceType = new PublicServiceType();
publicServiceType.setIdentifier(serviceTypePayload.getLeikaKey());
publicServiceType.setName(serviceTypePayload.getName());
if (serviceTypePayload.getDescription() != null) {
publicServiceType.setDescription(serviceTypePayload.getDescription());
}
return publicServiceType;
}
public static Data buildData(final DataPayload dataPayload) {
final var hash = new Hash();
hash.setContent(dataPayload.getHashedData());
hash.setDataSignatureType(DataSignatureType.SHA_512);
final var submissionSchema = new SubmissionSchema();
submissionSchema.setMimeType(dataPayload.getMimeType());
submissionSchema.setSchemaUri(dataPayload.getSchemaUri());
final var data = new Data();
data.setSubmissionSchema(submissionSchema);
data.setHash(hash);
return data;
}
public static Metadata buildMetadata(final List<Attachment> attachments, final Data data, final PublicServiceType publicServiceType) {
final var contentStructure = new ContentStructure();
contentStructure.setAttachments(attachments);
contentStructure.setData(data);
final var metadata = new Metadata();
metadata.setContentStructure(contentStructure);
metadata.setPublicServiceType(publicServiceType);
return metadata;
}
public static CreateSubmission buildSubmissionToAnnounce(final SubmissionPayload submissionPayload) {
final ServiceType serviceType = buildServiceType(submissionPayload.getServiceTypePayLoad());
final List<UUID> attachmentIds = toAttachmentIds(submissionPayload.getAttachments());
return createSubmission(submissionPayload.getDestinationId(), serviceType, attachmentIds);
}
public static SubmitSubmission buildSubmitSubmission(final SubmissionPayload submissionPayload, final UUID submissionId) {
final SubmitSubmission submission = new SubmitSubmission();
submission.setSubmissionId(submissionId);
submission.setEncryptedData(submissionPayload.getData().getEncryptedData());
submission.setEncryptedMetadata(submissionPayload.getEncryptedMetadata());
return submission;
}
public static Attachment toHashedAttachment(final AttachmentPayload attachmentPayload) {
final var attachment = new Attachment();
attachment.setAttachmentId(attachmentPayload.getAttachmentId());
attachment.setPurpose(Purpose.ATTACHMENT);
attachment.setFilename(attachmentPayload.getFile().getName());
attachment.setMimeType(attachmentPayload.getMimeType());
final var hash = new Hash__1();
hash.setContent(attachmentPayload.getHashedData());
hash.setAttachmentSignatureType(AttachmentSignatureType.SHA_512);
attachment.setHash(hash);
return attachment;
}
public static List<UUID> toAttachmentIds(final List<AttachmentPayload> attachmentPayloads) {
return attachmentPayloads.stream()
.map(AttachmentPayload::getAttachmentId)
.collect(Collectors.toList());
}
public static List<Attachment> toAttachmentMetadata(final List<AttachmentPayload> attachmentPayloads) {
return attachmentPayloads.stream()
.map(SubmissionUtil::toHashedAttachment)
.collect(Collectors.toList());
}
public static Function<Map.Entry<UUID, String>, AttachmentPayload> getEncryptedAttachmentPayload() {
return attachment -> AttachmentPayload.builder()
.encryptedData(attachment.getValue())
.attachmentId(attachment.getKey())
.build();
}
public static Function<File, AttachmentPayload> getFileAttachmentPayload(final UUID attachmentId) {
return file -> AttachmentPayload.builder()
.file(file)
.attachmentId(attachmentId)
.build();
}
}
package de.fitko.fitconnect.client;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.nimbusds.jose.jwk.RSAKey;
import de.fitko.fitconnect.api.config.*;
import de.fitko.fitconnect.api.domain.model.metadata.Metadata;
import de.fitko.fitconnect.api.domain.model.metadata.PublicServiceType;
import de.fitko.fitconnect.api.domain.model.metadata.attachment.Attachment;
import de.fitko.fitconnect.api.domain.model.metadata.data.Data;
import de.fitko.fitconnect.api.domain.model.metadata.data.MimeType;
import de.fitko.fitconnect.api.domain.model.submission.SubmissionForPickup;
import de.fitko.fitconnect.api.services.crypto.CryptoService;
import de.fitko.fitconnect.client.factory.ClientFactory;
import de.fitko.fitconnect.client.model.AttachmentPayload;
import de.fitko.fitconnect.client.model.DataPayload;
import de.fitko.fitconnect.client.model.ReceivedSubmission;
import de.fitko.fitconnect.client.model.ServiceTypePayload;
import de.fitko.fitconnect.client.util.SubmissionUtil;
import de.fitko.fitconnect.core.crypto.HashService;
import de.fitko.fitconnect.core.crypto.JWECryptoService;
import org.apache.tika.mime.MimeTypes;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;
......@@ -33,16 +54,17 @@ class ClientIntegrationTest {
final ApplicationConfig config = getConfigWithCredentialsFromGitlab(testEnv);
final var sentSubmission = ClientFactory.senderClient(config)
.withDestination(UUID.fromString(System.getenv("TEST_DESTINATION_ID")))
.withServiceType("Test Service", "urn:de:fim:leika:leistung:99400048079000")
.newSubmission()
.withAttachment(new File("src/test/resources/attachment.txt"))
.withJsonData("{ data: 'Beispiel Fachdaten' }")
.withDestination(UUID.fromString(System.getenv("TEST_DESTINATION_ID")))
.withServiceType("Test Service", "urn:de:fim:leika:leistung:99400048079000")
.submit();
assertTrue(sentSubmission.isPresent());
// When
final Optional<SubscriberClient.ReceivedSubmission> receivedSubmission =
final Optional<ReceivedSubmission> receivedSubmission =
ClientFactory.subscriberClient(config)
.requestSubmission(sentSubmission.get().getSubmissionId());
......@@ -53,6 +75,79 @@ class ClientIntegrationTest {
assertThat(new String(receivedSubmission.get().getAttachments().get(0).getDecryptedData()), is("Test attachment"));
}
@Test
@EnabledIfEnvironmentVariable(named = "TEST_DESTINATION_ID", matches = ".*")
void testSendAndConfirmCycleWithEncryptedData() throws ParseException, IOException {
// Given
final UUID destinationId = UUID.fromString(System.getenv("TEST_DESTINATION_ID"));
final var testEnv = new Environment(authBaseUrl, submissionBaseUrl, true);
final ApplicationConfig config = getConfigWithCredentialsFromGitlab(testEnv);
final CryptoService cryptoService = new JWECryptoService(new HashService());
final SenderClient.Start client = ClientFactory.senderClient(config);
final Optional<String> publicKey = client.getPublicKey(destinationId);
assertTrue(publicKey.isPresent());
final RSAKey encryptionKey = RSAKey.parse(publicKey.get());
final String jsonData = "{ data: 'Beispiel Fachdaten' }";
final File attachmentFile = new File("src/test/resources/attachment.txt");
final String attachmentData = Files.readString(attachmentFile.toPath());
final String encryptedData = cryptoService.encryptString(encryptionKey, jsonData);
final String encryptedAttachment = cryptoService.encryptString(encryptionKey, attachmentData);
final DataPayload dataPayload = DataPayload.builder()
.encryptedData(encryptedData)
.mimeType(MimeType.APPLICATION_JSON)
.schemaUri(URI.create("https://schema.fitko.de/fim/s00000000009_1.0.0.schema.json"))
.hashedData(cryptoService.hashBytes(jsonData.getBytes(StandardCharsets.UTF_8)))
.build();
final AttachmentPayload attachmentPayload = AttachmentPayload.builder()
.encryptedData(encryptedAttachment)
.file(attachmentFile)
.mimeType(MimeTypes.PLAIN_TEXT)
.attachmentId(UUID.randomUUID())
.hashedData(cryptoService.hashBytes(attachmentData.getBytes(StandardCharsets.UTF_8)))
.build();
final ServiceTypePayload serviceTypePayload = ServiceTypePayload.builder()
.name("Test Service")
.leikaKey("urn:de:fim:leika:leistung:99400048079000")
.build();
final Data data = SubmissionUtil.buildData(dataPayload);
final PublicServiceType publicServiceType = SubmissionUtil.buildPublicServiceType(serviceTypePayload);
final List<Attachment> attachmentMetadata = SubmissionUtil.toAttachmentMetadata(List.of(attachmentPayload));
final Metadata metadata = SubmissionUtil.buildMetadata(attachmentMetadata, data, publicServiceType);
final String encryptedMetadata = cryptoService.encryptBytes(encryptionKey, new ObjectMapper().writeValueAsBytes(metadata));
// When
final var sentSubmission = client
.newSubmissionWithEncryptedData()
.withEncryptedAttachment(attachmentPayload.getAttachmentId(), attachmentPayload.getEncryptedData())
.withEncryptedJsonData(encryptedData)
.withEncryptedMetadata(encryptedMetadata)
.withDestination(destinationId)
.withServiceType("Test Service", "urn:de:fim:leika:leistung:99400048079000")
.submit();
assertTrue(sentSubmission.isPresent());
final Optional<ReceivedSubmission> receivedSubmission =
ClientFactory.subscriberClient(config)
.requestSubmission(sentSubmission.get().getSubmissionId());
// Then
assertTrue(receivedSubmission.isPresent());
assertThat(receivedSubmission.get().getData(), is(jsonData));
assertThat(receivedSubmission.get().getMimeType().toString(), is("application/json"));
assertThat(new String(receivedSubmission.get().getAttachments().get(0).getDecryptedData()), is("Test attachment"));
}
@Test
@EnabledIfEnvironmentVariable(named = "TEST_DESTINATION_ID", matches = ".*")
void testListSubmissions() {
......@@ -68,16 +163,16 @@ class ClientIntegrationTest {
final String leikaKey = "urn:de:fim:leika:leistung:99400048079000";
final String serviceName = "Test Service";
final var submissionOne = senderClient
final var submissionOne = senderClient.newSubmission()
.withJsonData("{ data: 'Beispiel Fachdaten 1' }")
.withDestination(destinationId)
.withServiceType(serviceName, leikaKey)
.withJsonData("{ data: 'Beispiel Fachdaten 1' }")
.submit();
final var submissionTwo = senderClient
final var submissionTwo = senderClient.newSubmission()
.withJsonData("{ data: 'Beispiel Fachdaten 2' }")
.withDestination(destinationId)
.withServiceType(serviceName, leikaKey)
.withJsonData("{ data: 'Beispiel Fachdaten 2' }")
.submit();
assertTrue(submissionOne.isPresent());
......@@ -107,11 +202,11 @@ class ClientIntegrationTest {
final ApplicationConfig config = getConfigWithCredentialsFromGitlab("PROD", prodEnv);
// When
final var sentSubmission = ClientFactory.senderClient(config)
.withDestination(UUID.fromString(System.getenv("TEST_DESTINATION_ID")))
.withServiceType("Test Service", "urn:de:fim:leika:leistung:99400048079000")
final var sentSubmission = ClientFactory.senderClient(config).newSubmission()
.withAttachment(new File("src/test/resources/attachment.txt"))
.withJsonData("{ data: 'Beispiel Fachdaten' }")
.withDestination(UUID.fromString(System.getenv("TEST_DESTINATION_ID")))
.withServiceType("Test Service", "urn:de:fim:leika:leistung:99400048079000")
.submit();
// Then
......
......@@ -32,7 +32,7 @@ import static org.mockito.Mockito.when;
public class SenderClientTest {
private Sender senderMock;
private SenderClient.WithDestination underTest;
private SenderClient.Start underTest;
private final LogCaptor logs = new LogCaptor();
......@@ -65,10 +65,11 @@ public class SenderClientTest {
// When
final var submission = underTest
.withDestination(destinationId)
.withServiceType("Service", "de:fitco:test:key")
.newSubmission()
.withAttachment(new File("src/test/resources/attachment.txt"))
.withJsonData("{}")
.withDestination(destinationId)
.withServiceType("Service", "de:fitco:test:key")
.submit();
// Then
......@@ -98,11 +99,11 @@ public class SenderClientTest {
when(senderMock.validateMetadata(any(), any())).thenReturn(ValidationResult.ok());
// When
final var submission = underTest
.withDestination(destinationId)
.withServiceType("Service", "de:fitco:test:key")
final var submission = underTest.newSubmission()
.withAttachment(new File("src/test/resources/attachment.txt"))
.withXmlData("<xml><test>data</test></xml>")
.withDestination(destinationId)
.withServiceType("Service", "de:fitco:test:key")
.submit();
// Then
......@@ -120,11 +121,11 @@ public class SenderClientTest {
final File file2 = new File("src/test/resources/pdf_attachment_with_no_extension");
// When
final var submission = underTest
.withDestination(destinationId)
.withServiceType("name", "test:key")
final var submission = underTest.newSubmission()
.withAttachments(List.of(file1, file2))
.withJsonData("{}")
.withDestination(destinationId)
.withServiceType("name", "test:key")
.submit();
// Then
......@@ -141,10 +142,10 @@ public class SenderClientTest {
final UUID destinationId = setupTestMocks();
// When
final var submission = underTest
final var submission = underTest.newSubmission()
.withJsonData(null)
.withDestination(destinationId)
.withServiceType("name", "test:key")
.withJsonData(null)
.submit();
// Then
......@@ -159,10 +160,10 @@ public class SenderClientTest {
setupTestMocks();
// When
final var submission = underTest
final var submission = underTest.newSubmission()
.withJsonData("{}")
.withDestination(null)
.withServiceType("name", "test:key")
.withJsonData("{}")
.submit();
// Then
......@@ -187,10 +188,10 @@ public class SenderClientTest {
when(senderMock.getEncryptionKeyForDestination(any(), any())).thenReturn(publicKey);
// When
final var submission = underTest
final var submission = underTest.newSubmission()
.withJsonData("{}")
.withDestination(destinationId)
.withServiceType("Service", "de:fitco:test:key")
.withJsonData("{}")
.submit();
// Then
......@@ -205,10 +206,10 @@ public class SenderClientTest {
final var destinationId = setupTestMocks();
// When
final var submission = underTest
final var submission = underTest.newSubmission()
.withJsonData("{}")
.withDestination(destinationId)
.withServiceType(null, "leika:key")
.withJsonData("{}")
.submit();
// Then
......@@ -217,16 +218,16 @@ public class SenderClientTest {
}
@Test
void testWithOptionalServiceTypeIdentifier() throws Exception {
void testWithMissingServiceTypeIdentifier() throws Exception {
// Given
final var destinationId = setupTestMocks();
// When
final var submission = underTest
final var submission = underTest.newSubmission()
.withJsonData("{}")
.withDestination(destinationId)
.withServiceType("Name", null)
.withJsonData("{}")
.submit();
// Then
......@@ -241,10 +242,10 @@ public class SenderClientTest {
final var destinationId = setupTestMocks();
// When
final var submission = underTest
final var submission = underTest.newSubmission()
.withJsonData("{}")
.withDestination(destinationId)
.withServiceType("Name", null, "leika:key")
.withJsonData("{}")
.submit();
// Then
......@@ -258,11 +259,11 @@ public class SenderClientTest {
final UUID destinationId = setupTestMocks();
// When
final var submission = underTest
.withDestination(destinationId)
.withServiceType("name", "test:key")
final var submission = underTest.newSubmission()
.withAttachments(List.of())
.withJsonData("{}")
.withDestination(destinationId)
.withServiceType("name", "test:key")
.submit();
// Then
......@@ -277,11 +278,11 @@ public class SenderClientTest {
final UUID destinationId = setupTestMocks();
// When
final var submission = underTest
.withDestination(destinationId)
.withServiceType("name", "test:key")
final var submission = underTest.newSubmission()
.withAttachment(null)
.withJsonData("{}")
.withDestination(destinationId)
.withServiceType("name", "test:key")
.submit();
// Then
......@@ -296,11 +297,11 @@ public class SenderClientTest {
final UUID destinationId = setupTestMocks();
// When
final var submission = underTest
.withDestination(destinationId)
.withServiceType("name", "test:key")
final var submission = underTest.newSubmission()
.withAttachment(new File("/non/existing/path"))
.withJsonData("{}")
.withDestination(destinationId)
.withServiceType("name", "test:key")
.submit();
// Then
......@@ -316,10 +317,10 @@ public class SenderClientTest {
when(senderMock.validatePublicKey(any())).thenReturn(ValidationResult.error(new Exception()));
// When
final var submission = underTest
final var submission = underTest.newSubmission()
.withJsonData("{}")
.withDestination(destinationId)
.withServiceType("name", "test:key")
.withJsonData("{}")
.submit();
// Then
......@@ -335,10 +336,10 @@ public class SenderClientTest {
when(senderMock.encryptBytes(any(),any())).thenThrow(new EncryptionException("Encryption failed"));
// When
final var submission = underTest
final var submission = underTest.newSubmission()
.withJsonData("{}")
.withDestination(destinationId)
.withServiceType("name", "test:key")
.withJsonData("{}")
.submit();
// Then
......@@ -354,10 +355,10 @@ public class SenderClientTest {
when(senderMock.createSubmission(any())).thenThrow(new SubmissionNotCreatedException("Announcing submission failed"));
// When
final var submission = underTest
final var submission = underTest.newSubmission()
.withJsonData("{}")
.withDestination(destinationId)
.withServiceType("name", "test:key")
.withJsonData("{}")
.submit();
// Then
......@@ -374,10 +375,10 @@ public class SenderClientTest {
when(senderMock.getDestination(any())).thenThrow(new RestApiException("Loading destination failed"));
// When
final Optional<SubmitSubmission> submission = underTest
final Optional<SubmitSubmission> submission = underTest.newSubmission()
.withJsonData("{}")
.withDestination(destinationId)
.withServiceType("name", "test:key")
.withJsonData("{}")
.submit();
assertTrue(submission.isEmpty());
......@@ -393,16 +394,55 @@ public class SenderClientTest {
when(senderMock.getEncryptionKeyForDestination(any(), any())).thenThrow(new KeyNotRetrievedException("Getting encryption key failed"));
// When
final Optional<SubmitSubmission> submission = underTest
final Optional<SubmitSubmission> submission = underTest.newSubmission()
.withJsonData("{}")
.withDestination(destinationId)
.withServiceType("name", "test:key")
.withJsonData("{}")
.submit();
assertTrue(submission.isEmpty());
logs.assertContains("Getting encryption key for destination "+ destinationId+" failed");
}
@Test
void testSendSubmissionWithEncryptedData() throws Exception {
// Given
final var destinationId = setupTestMocks();
// When
final Optional<SubmitSubmission> submission = underTest.newSubmissionWithEncryptedData()
.withEncryptedAttachments(Map.of(UUID.randomUUID(),"@tt@chm$nt"))
.withEncryptedJsonData("$ncrypt$d d@t@")
.withEncryptedMetadata("$ncrypt$d m$t@d@t@")
.withDestination(destinationId)
.withServiceType("name", "test:key")
.submit();
assertTrue(submission.isPresent());
logs.assertContains("SUCCESSFULLY HANDED IN SUBMISSION");
}
@Test
void testPublicEncryptionKeyRetrieval() throws Exception {
// Given
final var destinationId = UUID.randomUUID();
final var destination = getDestination(destinationId);
final RSAKey publicKey = generateRsaKey(4096).toPublicJWK();
when(senderMock.getDestination(any())).thenReturn(destination);
when(senderMock.validatePublicKey(any())).thenReturn(ValidationResult.ok());
when(senderMock.getEncryptionKeyForDestination(any(), any())).thenReturn(publicKey);
// When
final Optional<String> encryptionKey = underTest.getPublicKey(destinationId);
assertTrue(encryptionKey.isPresent());
assertThat(encryptionKey.get(), equalTo(publicKey.toJSONString()));
}
@Test
void testFailOnInvalidMetadata() throws Exception {
......@@ -411,10 +451,10 @@ public class SenderClientTest {
when(senderMock.validateMetadata(any(), any())).thenReturn(ValidationResult.error(new ValidationException("invalid metadata")));
// When
final Optional<SubmitSubmission> submission = underTest
final Optional<SubmitSubmission> submission = underTest.newSubmission()
.withJsonData("{}")
.withDestination(destinationId)
.withServiceType("name", "test:key")
.withJsonData("{}")
.submit();
assertTrue(submission.isEmpty());
......
package de.fitko.fitconnect.client.cmd;
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.core.AppenderBase;
import de.fitko.fitconnect.api.domain.model.metadata.attachment.Attachment;
import de.fitko.fitconnect.api.domain.model.metadata.attachment.AttachmentWithData;
import de.fitko.fitconnect.api.domain.model.metadata.data.MimeType;
......@@ -9,7 +7,7 @@ import de.fitko.fitconnect.api.domain.model.submission.SubmissionForPickup;
import de.fitko.fitconnect.api.domain.model.submission.SubmitSubmission;
import de.fitko.fitconnect.client.SenderClient;
import de.fitko.fitconnect.client.SubscriberClient;
import de.fitko.fitconnect.client.SubscriberClient.ReceivedSubmission;
import de.fitko.fitconnect.client.model.ReceivedSubmission;
import de.fitko.fitconnect.client.testutil.LogCaptor;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
......@@ -31,11 +29,11 @@ class CommandLineClientTest {
private final LogCaptor logs = new LogCaptor();
ByteArrayOutputStream sysoutCaptor = new ByteArrayOutputStream();
private final ByteArrayOutputStream sysoutCaptor = new ByteArrayOutputStream();
CommandLineClient underTest;
SenderClient.ClientBuilder senderClientMock;
SubscriberClient.ClientBuilder subscriberClientMock;
private CommandLineClient underTest;
private SenderClient.ClientBuilder senderClientMock;
private SubscriberClient.ClientBuilder subscriberClientMock;
@BeforeEach
void setUp() {
......@@ -120,6 +118,7 @@ class CommandLineClientTest {
when(senderClientMock.withAttachments(any())).thenReturn(senderClientMock);
when(senderClientMock.withJsonData(any())).thenReturn(senderClientMock);
when(senderClientMock.submit()).thenReturn(Optional.of(expectedSubmission));
when(senderClientMock.newSubmission()).thenReturn(senderClientMock);
// When
underTest.run("send",
......
......@@ -3,6 +3,7 @@ package de.fitko.fitconnect.client.factory;
import de.fitko.fitconnect.api.config.ApplicationConfig;
import de.fitko.fitconnect.api.config.Environment;
import de.fitko.fitconnect.api.config.SenderConfig;
import de.fitko.fitconnect.api.exceptions.InitializationException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
......@@ -13,16 +14,31 @@ import java.nio.file.Path;
import java.util.Objects;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.jupiter.api.Assertions.assertNotNull;
class ApplicationConfigLoaderTest {
@Test
void testLoadMissingConfigFile(){
void testLoadMissingConfigFile() {
Assertions.assertThrows(IOException.class, () -> ApplicationConfigLoader.loadConfig(Path.of("/no/path")));
}
@Test
void testEnvironmentNotAvailable() throws IOException {
// Given
final String testConfigYaml = getResourceAsString("test-config-with-missing-env.yml");
final ApplicationConfig config = ApplicationConfigLoader.loadConfig(testConfigYaml);
//When
final InitializationException exception = Assertions.assertThrowsExactly(InitializationException.class, () -> config.getCurrentEnvironment());
//Then
assertThat(exception.getMessage(), containsString("Available environments are: prod | staging | dev | testing | local"));
}
@Test
void testLoadTestConfigFromString() throws IOException {
......
# Proxy config for http api calls
httpProxyHost: ""
httpProxyPort: 0
requestTimeoutInSeconds: 30
# Name/key of the used environment (from environments config below)
activeEnvironment: foo
# Path that references the metadata schema
metadataSchemaPath: "client/src/test/java/resources/metadata_schema.json"
# Path that references the signing key file
privateSigningKeyPath: "client/src/test/java/resources/private_test_signing_key.json"
senderConfig:
clientId: "1"
clientSecret: "123"
subscriberConfig:
clientId: "2"
clientSecret: "456"
# Path that references the private key file
privateDecryptionKeyPath: "client/src/test/java/resources/private_decryption_test_key.json"
securityEventTokenSchemaPath: ""
# Configured environments for all api-urls
environments:
prod:
authBaseUrl: "https://auth-prod.fit-connect.fitko.dev"
submissionBaseUrl: "https://submission-api-prod.fit-connect.fitko.dev"
silentKeyValidation: false
staging:
authBaseUrl: "https://auth-prod.fit-connect.fitko.dev"
submissionBaseUrl: "https://submission-api-prod.fit-connect.fitko.dev"
silentKeyValidation: false
dev:
authBaseUrl: "https://auth-testing.fit-connect.fitko.dev"
submissionBaseUrl: "https://submission-api-testing.fit-connect.fitko.dev"
silentKeyValidation: true
testing:
authBaseUrl: "https://auth-test.fit-connect.fitko.dev"
submissionBaseUrl: "https://submission-api-testing.fit-connect.fitko.dev"
silentKeyValidation: true
local:
authBaseUrl: "https://auth-test.fit-connect.fitko.dev"
submissionBaseUrl: "https://submission-api-testing.fit-connect.fitko.dev"
silentKeyValidation: true
# REST Endpoints for FIT-Connect resources
resourcePaths:
authTokenPath: "/token"
destinationPath: "/v1/destinations/{destinationId}"
destinationKeyPath: "/v1/destinations/{destinationId}/keys/{kid}"
eventLogPath: "/v1/cases/{caseId}/events"
submissionPath: "/v1/submissions/{submissionId}"
submissionsPath: "/v1/submissions"
submissionAttachmentPath: "/v1/submissions/{submissionId}/attachments/{attachmentId}"
\ No newline at end of file
......@@ -3,15 +3,15 @@ httpProxyHost: ""
httpProxyPort: 0
requestTimeoutInSeconds: 30
# Name/key of the used environment
# Name/key of the used environment (from environments config below)
activeEnvironment: dev
# Path that references the signing key file
privateSigningKeyPath: "client/src/test/java/resources/private_test_signing_key.json"
# Path that references the metadata schema
metadataSchemaPath: "client/src/test/java/resources/metadata_schema.json"
# Path that references the signing key file
privateSigningKeyPath: "client/src/test/java/resources/private_test_signing_key.json"
senderConfig:
clientId: "1"
clientSecret: "123"
......