diff --git a/src/main/java/de/ozgcloud/xta/test/app/config/XTAServer.java b/src/main/java/de/ozgcloud/xta/test/app/config/XTAServer.java
index f5fd91b9978836dc5d771de05e2941b235a17cba..4c06a8691745b70ba435305031f5f47f18755e91 100644
--- a/src/main/java/de/ozgcloud/xta/test/app/config/XTAServer.java
+++ b/src/main/java/de/ozgcloud/xta/test/app/config/XTAServer.java
@@ -1,19 +1,17 @@
 package de.ozgcloud.xta.test.app.config;
 
+import genv3.de.xoev.transport.xta.x211.ManagementPortType;
+import genv3.de.xoev.transport.xta.x211.MsgBoxPortType;
+import genv3.de.xoev.transport.xta.x211.SendPortType;
 import jakarta.xml.ws.Endpoint;
 import jakarta.xml.ws.soap.SOAPBinding;
-
+import lombok.RequiredArgsConstructor;
+import lombok.extern.log4j.Log4j2;
 import org.apache.cxf.bus.spring.SpringBus;
 import org.apache.cxf.jaxws.EndpointImpl;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
-import genv3.de.xoev.transport.xta.x211.ManagementPortType;
-import genv3.de.xoev.transport.xta.x211.MsgBoxPortType;
-import genv3.de.xoev.transport.xta.x211.SendPortType;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.log4j.Log4j2;
-
 @Configuration
 @Log4j2
 @RequiredArgsConstructor
diff --git a/src/main/java/de/ozgcloud/xta/test/app/data/XtaTransportReportRepository.java b/src/main/java/de/ozgcloud/xta/test/app/data/XtaTransportReportRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..4d86cd3bac5b110a98246c7caeb34bc37db19869
--- /dev/null
+++ b/src/main/java/de/ozgcloud/xta/test/app/data/XtaTransportReportRepository.java
@@ -0,0 +1,52 @@
+package de.ozgcloud.xta.test.app.data;
+
+import java.time.ZonedDateTime;
+import java.util.HashMap;
+import java.util.Optional;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+
+import de.ozgcloud.xta.test.app.model.XtaMessageMetaData;
+import de.ozgcloud.xta.test.app.model.XtaTransportReport;
+
+@Component
+@RequiredArgsConstructor
+public class XtaTransportReportRepository {
+	private final HashMap<String, XtaMessageMetaData> messageIdTomessageMetaData = new HashMap<>();
+	private final HashMap<String, XtaTransportReport.MessageStatus> messageIdToStatus = new HashMap<>();
+
+	public boolean add(XtaMessageMetaData messageMetaData) {
+		if (messageIdTomessageMetaData.containsKey(messageMetaData.messageId())) {
+			return false;
+		}
+		messageIdTomessageMetaData.put(messageMetaData.messageId(), messageMetaData);
+		messageIdToStatus.put(messageMetaData.messageId(), XtaTransportReport.MessageStatus.OFFEN);
+		return true;
+	}
+
+	public boolean setClosedStatus(String messageId) {
+		if (!messageIdToStatus.containsKey(messageId)) {
+			return false;
+		}
+
+		messageIdToStatus.put(messageId, XtaTransportReport.MessageStatus.GRUEN);
+		return true;
+
+	}
+
+	public Optional<XtaTransportReport> get(String messageId) {
+		if (messageIdTomessageMetaData.containsKey(messageId)) {
+			return Optional.of(XtaTransportReport.builder()
+					.messageMetaData(messageIdTomessageMetaData.get(messageId))
+					.status(messageIdToStatus.get(messageId))
+					.reportTime(getNow())
+					.build());
+		}
+		return Optional.empty();
+	}
+
+	private ZonedDateTime getNow() {
+		return ZonedDateTime.now();
+	}
+}
diff --git a/src/main/java/de/ozgcloud/xta/test/app/mapper/ExceptionMapper.java b/src/main/java/de/ozgcloud/xta/test/app/mapper/ExceptionMapper.java
index e9aa8168c7ea74260b386fec92bb0c45fcde91c8..34f1fb2b318e8d40bfbd6bb34b3f31c90ac77105 100644
--- a/src/main/java/de/ozgcloud/xta/test/app/mapper/ExceptionMapper.java
+++ b/src/main/java/de/ozgcloud/xta/test/app/mapper/ExceptionMapper.java
@@ -26,9 +26,10 @@ public interface ExceptionMapper {
 	String ERROR_CODE_MESSAGE_ID_UNKNOWN = "9070";
 	String ERROR_CODE_MESSAGE_ID_UNKNOWN_DESCRIPTION = "MessageID für den Account nicht bekannt";
 
-	default InvalidMessageIDException createInvalidMessageIDException(String message) {
+	default InvalidMessageIDException createInvalidMessageIDException(String messageId, String clientIdentifierValue) {
 		return new InvalidMessageIDException(
-				message,
+				"No message with messageID \"%s\" available for identifier \"%s\"."
+						.formatted(messageId, clientIdentifierValue),
 				mapInvalidMessageIDExceptionType(ERROR_CODE_MESSAGE_ID_UNKNOWN, ERROR_CODE_MESSAGE_ID_UNKNOWN_DESCRIPTION)
 		);
 	}
diff --git a/src/main/java/de/ozgcloud/xta/test/app/mapper/RequestMapper.java b/src/main/java/de/ozgcloud/xta/test/app/mapper/RequestMapper.java
index b8c7ff6a103d896ff8b295fe34e9313ad929ccd5..2aef8550f2c785f6765d5d8c802f060754bbc803 100644
--- a/src/main/java/de/ozgcloud/xta/test/app/mapper/RequestMapper.java
+++ b/src/main/java/de/ozgcloud/xta/test/app/mapper/RequestMapper.java
@@ -6,20 +6,15 @@ import java.io.IOException;
 
 import jakarta.activation.DataHandler;
 
+import org.apache.cxf.ws.addressing.AttributedURIType;
 import org.mapstruct.Mapper;
 import org.mapstruct.Mapping;
 import org.mapstruct.Named;
 import org.mapstruct.ReportingPolicy;
 
 import de.ozgcloud.xta.test.app.exception.TechnicalException;
-import de.ozgcloud.xta.test.app.model.XtaCloseRequest;
-import de.ozgcloud.xta.test.app.model.XtaFile;
-import de.ozgcloud.xta.test.app.model.XtaGetMessageRequest;
-import de.ozgcloud.xta.test.app.model.XtaIdentifier;
-import de.ozgcloud.xta.test.app.model.XtaLookupServiceRequest;
-import de.ozgcloud.xta.test.app.model.XtaMessage;
-import de.ozgcloud.xta.test.app.model.XtaMessageMetaData;
-import de.ozgcloud.xta.test.app.model.XtaMessageMetaDataListingRequest;
+import de.ozgcloud.xta.test.app.model.*;
+
 import genv3.de.xoev.transport.xta.x211.ContentType;
 import genv3.de.xoev.transport.xta.x211.GenericContentContainer;
 import genv3.de.xoev.transport.xta.x211.LookupServiceRequest;
@@ -99,4 +94,8 @@ public interface RequestMapper {
 	@Mapping(target = "readerIdentifier", source = "lookupServiceRequest.lookupServiceRequestList.first.lookupService.reader.identifier")
 	@Mapping(target = "authorIdentifier", source = "authorIdentifier.identifier")
 	XtaLookupServiceRequest mapXtaLookupServiceRequest(LookupServiceRequest lookupServiceRequest, PartyType authorIdentifier);
+
+	@Mapping(target = "messageId", source = "messageId.value")
+	@Mapping(target = "clientIdentifier", source = "authorIdentifier.identifier")
+	XtaGetTransportReportRequest mapXtaGetTransportReportRequest(AttributedURIType messageId, PartyType authorIdentifier);
 }
diff --git a/src/main/java/de/ozgcloud/xta/test/app/mapper/ResponseMapper.java b/src/main/java/de/ozgcloud/xta/test/app/mapper/ResponseMapper.java
index 44b84a51228f55e941a15002a6490afffc2567df..d3456fc16bdcc21ccb9de892a712266bb919efd2 100644
--- a/src/main/java/de/ozgcloud/xta/test/app/mapper/ResponseMapper.java
+++ b/src/main/java/de/ozgcloud/xta/test/app/mapper/ResponseMapper.java
@@ -2,35 +2,17 @@ package de.ozgcloud.xta.test.app.mapper;
 
 import java.io.File;
 import java.math.BigInteger;
-import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
+import java.time.ZonedDateTime;
+import java.util.GregorianCalendar;
 import java.util.List;
-
 import javax.xml.datatype.DatatypeFactory;
 import javax.xml.datatype.XMLGregorianCalendar;
 
-import jakarta.activation.DataHandler;
-import jakarta.activation.FileDataSource;
-
-import org.apache.cxf.ws.addressing.AttributedURIType;
-import org.mapstruct.Condition;
-import org.mapstruct.Mapper;
-import org.mapstruct.Mapping;
-import org.mapstruct.Named;
-import org.mapstruct.ReportingPolicy;
-import org.mapstruct.SourcePropertyName;
-import org.mapstruct.TargetPropertyName;
-
-import de.ozgcloud.xta.test.app.model.XtaFile;
-import de.ozgcloud.xta.test.app.model.XtaIdentifier;
-import de.ozgcloud.xta.test.app.model.XtaLookupServiceRequest;
-import de.ozgcloud.xta.test.app.model.XtaMessage;
-import de.ozgcloud.xta.test.app.model.XtaMessageMetaData;
-import de.ozgcloud.xta.test.app.model.XtaMessageMetaDataListing;
 import genv3.de.xoev.transport.xta.x211.ContentType;
 import genv3.de.xoev.transport.xta.x211.GenericContentContainer;
 import genv3.de.xoev.transport.xta.x211.LookupServiceResponse;
 import genv3.de.xoev.transport.xta.x211.LookupServiceResultType;
+import genv3.de.xoev.transport.xta.x211.TransportReport;
 import genv3.eu.osci.ws.x2008.x05.transport.MsgBoxResponseType;
 import genv3.eu.osci.ws.x2008.x05.transport.MsgStatusListType;
 import genv3.eu.osci.ws.x2014.x10.transport.DeliveryAttributesType;
@@ -38,7 +20,13 @@ import genv3.eu.osci.ws.x2014.x10.transport.KeyCodeType;
 import genv3.eu.osci.ws.x2014.x10.transport.MessageMetaData;
 import genv3.eu.osci.ws.x2014.x10.transport.PartyIdentifierType;
 import genv3.eu.osci.ws.x2014.x10.transport.QualifierType;
+import jakarta.activation.DataHandler;
+import jakarta.activation.FileDataSource;
 import lombok.SneakyThrows;
+import org.apache.cxf.ws.addressing.AttributedURIType;
+import org.mapstruct.*;
+
+import de.ozgcloud.xta.test.app.model.*;
 
 @Mapper(
 		unmappedTargetPolicy = ReportingPolicy.ERROR,
@@ -65,7 +53,7 @@ public interface ResponseMapper {
 	@Mapping(target = "destinations.reader.identifier", source = "readerIdentifier")
 	@Mapping(target = "msgSize", source = "messageSize")
 	@Mapping(target = "testMsg", ignore = true)
-	@Mapping(target = "deliveryAttributes", expression = "java( createDefaultDeliveryAttributes(createNowXmlGregorianCalendarFromLocalDateTime()) )")
+	@Mapping(target = "deliveryAttributes", expression = "java( createDefaultDeliveryAttributes(createNowXmlGregorianCalendar()) )")
 	@Mapping(target = "messageProperties", ignore = true)
 	MessageMetaData mapMessageMetaData(XtaMessageMetaData xtaMessageMetaData);
 
@@ -127,9 +115,14 @@ public interface ResponseMapper {
 	DeliveryAttributesType createDefaultDeliveryAttributes(XMLGregorianCalendar timestamp);
 
 	@SneakyThrows
-	default XMLGregorianCalendar createNowXmlGregorianCalendarFromLocalDateTime() {
-		var isoTimeString = DateTimeFormatter.ISO_DATE_TIME.format(LocalDateTime.now());
-		return DatatypeFactory.newInstance().newXMLGregorianCalendar(isoTimeString);
+	default XMLGregorianCalendar createNowXmlGregorianCalendar() {
+		return mapXmlGregorianCalendarFromZonedDateTime(ZonedDateTime.now());
+	}
+
+	@SneakyThrows
+	default XMLGregorianCalendar mapXmlGregorianCalendarFromZonedDateTime(ZonedDateTime zonedDateTime) {
+		GregorianCalendar gregorianCalendar = GregorianCalendar.from(zonedDateTime);
+		return DatatypeFactory.newInstance().newXMLGregorianCalendar(gregorianCalendar);
 	}
 
 	@Mapping(target = "itemsPending", expression = "java( BigInteger.ZERO )")
@@ -177,6 +170,14 @@ public interface ResponseMapper {
 	@Mapping(target = "lookupServiceResultList.lookupServiceResult", expression = "java( List.of( mapLookupServiceResultType(xtaLookupServiceRequest) ) )")
 	LookupServiceResponse mapLookupServiceResponse(XtaLookupServiceRequest xtaLookupServiceRequest);
 
+	@Mapping(target = "messageMetaData", source = "messageMetaData")
+	@Mapping(target = "reportTime", source = "reportTime")
+	@Mapping(target = "XTAServerIdentity", constant = "xta-test-server")
+	@Mapping(target = "messageStatus.status", expression = "java( BigInteger.valueOf(xtaTransportReport.status().ordinal()) )")
+	@Mapping(target = "additionalReports", ignore = true)
+	@Mapping(target = "signature", ignore = true)
+	TransportReport mapTransportReport(XtaTransportReport xtaTransportReport);
+
 	@Mapping(target = "otherAttributes", ignore = true)
 	AttributedURIType mapCreateMessageIdResponse(String value);
 }
diff --git a/src/main/java/de/ozgcloud/xta/test/app/model/XtaCloseRequest.java b/src/main/java/de/ozgcloud/xta/test/app/model/XtaCloseRequest.java
index d6d2ac2b43b6d109fc81c4781543c3557b98359b..53a97270b32723105bef8e423b1a60865890f291 100644
--- a/src/main/java/de/ozgcloud/xta/test/app/model/XtaCloseRequest.java
+++ b/src/main/java/de/ozgcloud/xta/test/app/model/XtaCloseRequest.java
@@ -3,7 +3,6 @@ package de.ozgcloud.xta.test.app.model;
 import static de.ozgcloud.xta.test.app.validation.ValidXtaId.*;
 
 import jakarta.validation.Valid;
-import jakarta.validation.constraints.NotBlank;
 import jakarta.validation.constraints.NotNull;
 
 import de.ozgcloud.xta.test.app.validation.ValidXtaId;
diff --git a/src/main/java/de/ozgcloud/xta/test/app/model/XtaGetMessageRequest.java b/src/main/java/de/ozgcloud/xta/test/app/model/XtaGetMessageRequest.java
index 443a9c61edb79faefd74efeea7800f88ee07a14c..83674654f68c581f363265b3c8a5244b12431b2c 100644
--- a/src/main/java/de/ozgcloud/xta/test/app/model/XtaGetMessageRequest.java
+++ b/src/main/java/de/ozgcloud/xta/test/app/model/XtaGetMessageRequest.java
@@ -3,7 +3,6 @@ package de.ozgcloud.xta.test.app.model;
 import static de.ozgcloud.xta.test.app.validation.ValidXtaId.*;
 
 import jakarta.validation.Valid;
-import jakarta.validation.constraints.NotBlank;
 import jakarta.validation.constraints.NotNull;
 
 import de.ozgcloud.xta.test.app.validation.ValidXtaId;
diff --git a/src/main/java/de/ozgcloud/xta/test/app/model/XtaGetTransportReportRequest.java b/src/main/java/de/ozgcloud/xta/test/app/model/XtaGetTransportReportRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..0e0a5f14235c760054e067fc78dab7618f08003f
--- /dev/null
+++ b/src/main/java/de/ozgcloud/xta/test/app/model/XtaGetTransportReportRequest.java
@@ -0,0 +1,16 @@
+package de.ozgcloud.xta.test.app.model;
+
+import static de.ozgcloud.xta.test.app.validation.ValidXtaId.*;
+
+		import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotNull;
+
+import de.ozgcloud.xta.test.app.validation.ValidXtaId;
+import lombok.Builder;
+
+@Builder
+public record XtaGetTransportReportRequest (
+		@ValidXtaId(namespace = MESSAGE_ID_NAMESPACE) String messageId,
+		@NotNull @Valid XtaIdentifier clientIdentifier
+) {
+}
diff --git a/src/main/java/de/ozgcloud/xta/test/app/model/XtaMessageMetaDataListingRequest.java b/src/main/java/de/ozgcloud/xta/test/app/model/XtaMessageMetaDataListingRequest.java
index c19441db3217c06ae165f976cf914d3af69b1622..d505196951dabca2f1aac8f3a7a50c85914a69a3 100644
--- a/src/main/java/de/ozgcloud/xta/test/app/model/XtaMessageMetaDataListingRequest.java
+++ b/src/main/java/de/ozgcloud/xta/test/app/model/XtaMessageMetaDataListingRequest.java
@@ -1,7 +1,6 @@
 package de.ozgcloud.xta.test.app.model;
 
 import jakarta.validation.Valid;
-import jakarta.validation.constraints.NotBlank;
 import jakarta.validation.constraints.NotNull;
 import jakarta.validation.constraints.Positive;
 
diff --git a/src/main/java/de/ozgcloud/xta/test/app/model/XtaTransportReport.java b/src/main/java/de/ozgcloud/xta/test/app/model/XtaTransportReport.java
new file mode 100644
index 0000000000000000000000000000000000000000..af9d76a2be7a71baa43241117f563c7adcc82a98
--- /dev/null
+++ b/src/main/java/de/ozgcloud/xta/test/app/model/XtaTransportReport.java
@@ -0,0 +1,21 @@
+package de.ozgcloud.xta.test.app.model;
+
+import java.time.ZonedDateTime;
+
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotNull;
+import lombok.Builder;
+
+@Builder
+public record XtaTransportReport(
+		@Valid XtaMessageMetaData messageMetaData,
+		@NotNull ZonedDateTime reportTime,
+		@NotNull MessageStatus status) {
+
+	public enum MessageStatus {
+		OFFEN,
+		GRUEN,
+		GELB,
+		ROT
+	}
+}
diff --git a/src/main/java/de/ozgcloud/xta/test/app/server/ManagementPortImpl.java b/src/main/java/de/ozgcloud/xta/test/app/server/ManagementPortImpl.java
index d47d13465fa68e0f1db6e523a19a77e27e847b5a..acc98e4750f308351f10c254b979b21a058e8e89 100644
--- a/src/main/java/de/ozgcloud/xta/test/app/server/ManagementPortImpl.java
+++ b/src/main/java/de/ozgcloud/xta/test/app/server/ManagementPortImpl.java
@@ -7,6 +7,7 @@ import org.apache.cxf.annotations.SchemaValidation;
 import org.apache.cxf.ws.addressing.AttributedURIType;
 import org.springframework.stereotype.Component;
 
+import de.ozgcloud.xta.test.app.mapper.ExceptionMapper;
 import de.ozgcloud.xta.test.app.mapper.RequestMapper;
 import de.ozgcloud.xta.test.app.mapper.ResponseMapper;
 import de.ozgcloud.xta.test.app.service.XtaMessageService;
@@ -17,7 +18,6 @@ import genv3.de.xoev.transport.xta.x211.LookupServiceRequest;
 import genv3.de.xoev.transport.xta.x211.ManagementPortType;
 import genv3.de.xoev.transport.xta.x211.ParameterIsNotValidException;
 import genv3.de.xoev.transport.xta.x211.PermissionDeniedException;
-import genv3.de.xoev.transport.xta.x211.TransportReport;
 import genv3.de.xoev.transport.xta.x211.XTAWSTechnicalProblemException;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.log4j.Log4j2;
@@ -29,6 +29,7 @@ import lombok.extern.log4j.Log4j2;
 @Log4j2
 public class ManagementPortImpl implements ManagementPortType {
 
+	private final ExceptionMapper exceptionMapper;
 	private final ResponseMapper responseMapper;
 	private final RequestMapper requestMapper;
 	private final RequestValidator requestValidator;
@@ -107,11 +108,13 @@ public class ManagementPortImpl implements ManagementPortType {
 			final genv3.eu.osci.ws.x2014.x10.transport.PartyType authorIdentifier)
 			throws XTAWSTechnicalProblemException, InvalidMessageIDException, PermissionDeniedException {
 		log.info("Executing operation getTransportReport");
-		TransportReport transportReport = new TransportReport();
+		var request = requestMapper.mapXtaGetTransportReportRequest(messageID, authorIdentifier);
+		requestValidator.validate(request);
 
-		// TODO implement
+		var xtaTransportReport = xtaMessageService.getTransportReport(request)
+				.orElseThrow(() -> exceptionMapper.createInvalidMessageIDException(request.messageId(), request.clientIdentifier().value()));
 
-		return transportReport;
+		return responseMapper.mapTransportReport(xtaTransportReport);
 	}
 
 }
diff --git a/src/main/java/de/ozgcloud/xta/test/app/server/MsgBoxPortImpl.java b/src/main/java/de/ozgcloud/xta/test/app/server/MsgBoxPortImpl.java
index 6e43533453efffd463ccef3c380f5d33b2136fc3..dc89cb2e3ee9b6407cfb37e201fb9807d590c22e 100644
--- a/src/main/java/de/ozgcloud/xta/test/app/server/MsgBoxPortImpl.java
+++ b/src/main/java/de/ozgcloud/xta/test/app/server/MsgBoxPortImpl.java
@@ -50,7 +50,7 @@ public class MsgBoxPortImpl implements MsgBoxPortType {
 		requestValidator.validate(request);
 
 		var message = messageService.getMessage(request)
-				.orElseThrow(() -> createInvalidMessageIdException(request.messageId(), request.clientIdentifier().value()));
+				.orElseThrow(() -> exceptionMapper.createInvalidMessageIDException(request.messageId(), request.clientIdentifier().value()));
 
 		messageMetaData.value = responseMapper.mapMessageMetaData(message.metaData());
 		fetchResponseHeader.value = responseMapper.mapMsgBoxResponseTypeFromRequestId(
@@ -131,14 +131,8 @@ public class MsgBoxPortImpl implements MsgBoxPortType {
 		requestValidator.validate(request);
 
 		if (!messageService.closeMessage(request)) {
-			throw createInvalidMessageIdException(request.messageId(), request.clientIdentifier().value());
+			throw exceptionMapper.createInvalidMessageIDException(request.messageId(), request.clientIdentifier().value());
 		}
 	}
 
-	private InvalidMessageIDException createInvalidMessageIdException(String messageId, String clientIdentifierValue) {
-		return exceptionMapper.createInvalidMessageIDException(
-				"No message with messageID \"%s\" available for identifier \"%s\"."
-						.formatted(messageId, clientIdentifierValue));
-	}
-
 }
diff --git a/src/main/java/de/ozgcloud/xta/test/app/service/XtaMessageService.java b/src/main/java/de/ozgcloud/xta/test/app/service/XtaMessageService.java
index 79864e4fce2136fb06d23e29f0a2796991b32553..2d663d603bd703c2cad6b1a5f5f604711ad17fd0 100644
--- a/src/main/java/de/ozgcloud/xta/test/app/service/XtaMessageService.java
+++ b/src/main/java/de/ozgcloud/xta/test/app/service/XtaMessageService.java
@@ -9,24 +9,25 @@ import org.springframework.core.env.Environment;
 import org.springframework.stereotype.Service;
 
 import de.ozgcloud.xta.test.app.data.XtaMessageRepository;
-import de.ozgcloud.xta.test.app.model.XtaCloseRequest;
-import de.ozgcloud.xta.test.app.model.XtaGetMessageRequest;
-import de.ozgcloud.xta.test.app.model.XtaMessage;
-import de.ozgcloud.xta.test.app.model.XtaMessageMetaData;
-import de.ozgcloud.xta.test.app.model.XtaMessageMetaDataListing;
-import de.ozgcloud.xta.test.app.model.XtaMessageMetaDataListingRequest;
+import de.ozgcloud.xta.test.app.data.XtaTransportReportRepository;
+import de.ozgcloud.xta.test.app.model.*;
+
 import lombok.RequiredArgsConstructor;
 
 @Service
 @RequiredArgsConstructor
 public class XtaMessageService {
 	private final XtaMessageRepository messageRepository;
+	private final XtaTransportReportRepository transportReportRepository;
 
 	private final Environment environment;
 
 	public boolean sendMessage(XtaMessage message) {
-		messageRepository.save(message);
-		return true;
+		if (transportReportRepository.add(message.metaData())) {
+			messageRepository.save(message);
+			return true;
+		}
+		return false;
 	}
 
 	public XtaMessageMetaDataListing getStatusList(XtaMessageMetaDataListingRequest listingRequest) {
@@ -50,15 +51,30 @@ public class XtaMessageService {
 	}
 
 	Predicate<XtaMessage> isAuthorOrReaderOfMessage(String clientIdentifierValue) {
-		return m -> m.metaData().readerIdentifier().value().equals(clientIdentifierValue)
-				|| m.metaData().authorIdentifier().value().equals(clientIdentifierValue);
+		return m -> isAuthorOrReaderOfMessageMetadata(clientIdentifierValue).test(m.metaData());
 	}
 
 	public boolean closeMessage(XtaCloseRequest request) {
-		return messageRepository.deleteByMessageIdAndReaderIdentifierValue(
+		var isDeleted = messageRepository.deleteByMessageIdAndReaderIdentifierValue(
 				request.messageId(),
 				request.clientIdentifier().value()
 		);
+		var isClosed = transportReportRepository.setClosedStatus(request.messageId());
+		return isDeleted && isClosed;
+	}
+
+	public Optional<XtaTransportReport> getTransportReport(XtaGetTransportReportRequest request) {
+		return transportReportRepository.get(request.messageId())
+				.filter(isAuthorOrReaderOfTransportReport(request.clientIdentifier().value()));
+	}
+
+	Predicate<XtaTransportReport> isAuthorOrReaderOfTransportReport(String clientIdentifierValue) {
+		return tr -> isAuthorOrReaderOfMessageMetadata(clientIdentifierValue).test(tr.messageMetaData());
+	}
+
+	Predicate<XtaMessageMetaData> isAuthorOrReaderOfMessageMetadata(String clientIdentifierValue) {
+		return m -> m.readerIdentifier().value().equals(clientIdentifierValue)
+				|| m.authorIdentifier().value().equals(clientIdentifierValue);
 	}
 
 	public String createMessageId() {
diff --git a/src/test/java/de/ozgcloud/xta/test/app/data/XtaTransportReportRepositoryTest.java b/src/test/java/de/ozgcloud/xta/test/app/data/XtaTransportReportRepositoryTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..2eb7701f1d7d575d2eb266a8897e1aeaf9e89210
--- /dev/null
+++ b/src/test/java/de/ozgcloud/xta/test/app/data/XtaTransportReportRepositoryTest.java
@@ -0,0 +1,115 @@
+package de.ozgcloud.xta.test.app.data;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.mockito.Spy;
+
+import de.ozgcloud.xta.test.app.factory.XtaMessageMetaDataTestFactory;
+import de.ozgcloud.xta.test.app.model.XtaMessageMetaData;
+import de.ozgcloud.xta.test.app.model.XtaTransportReport;
+
+public class XtaTransportReportRepositoryTest {
+	@Spy
+	private XtaTransportReportRepository repository;
+
+	private final XtaMessageMetaData messageMetaData = XtaMessageMetaDataTestFactory.create();
+
+	@Nested
+	class Add{
+		@Test
+		void shouldReturnTrue() {
+			var result = repository.add(messageMetaData);
+
+			assertThat(result).isTrue();
+		}
+
+		@Test
+		void shouldReturnFalseForDuplicateMessageId() {
+			repository.add(messageMetaData);
+			var result = repository.add(messageMetaData);
+
+			assertThat(result).isFalse();
+		}
+
+	}
+
+	@Nested
+	class Get {
+		@Nested
+		class WithExistingMessageId {
+			@Test
+			void shouldReturnReport() {
+				repository.add(messageMetaData);
+
+				var result = repository.get(messageMetaData.messageId());
+
+				assertThat(result).isPresent();
+				assertThat(result.get().messageMetaData()).isEqualTo(messageMetaData);
+			}
+
+			@Test
+			void shouldSetReportTime() {
+				repository.add(messageMetaData);
+
+				var result = repository.get(messageMetaData.messageId());
+
+				assertThat(result).isPresent();
+				assertThat(result.get().reportTime()).isNotNull();
+			}
+
+			@Test
+			void shouldSetStatusOffen() {
+				repository.add(messageMetaData);
+
+				var result = repository.get(messageMetaData.messageId());
+
+				assertThat(result).isPresent();
+				assertThat(result.get().status()).isEqualTo(XtaTransportReport.MessageStatus.OFFEN);
+			}
+		}
+
+		@Nested
+		class WithMissingMessageId {
+			@Test
+			void shouldReturnEmpty() {
+				var result = repository.get(messageMetaData.messageId());
+
+				assertThat(result).isEmpty();
+			}
+		}
+
+	}
+
+	@Nested
+	class SetClosedStatus {
+		@Test
+		void shouldSetClosedStatus() {
+			repository.add(messageMetaData);
+
+			repository.setClosedStatus(messageMetaData.messageId());
+			var report = repository.get(messageMetaData.messageId());
+
+			assertThat(report).isPresent();
+			assertThat(report.get().status()).isEqualTo(XtaTransportReport.MessageStatus.GRUEN);
+		}
+
+		@Test
+		void shouldReturnTrueOnSuccess() {
+			repository.add(messageMetaData);
+
+			var result = repository.setClosedStatus(messageMetaData.messageId());
+
+			assertThat(result).isTrue();
+		}
+
+		@Test
+		void shouldReturnFalseOnMissingMessageId() {
+			var result = repository.setClosedStatus(messageMetaData.messageId());
+
+			assertThat(result).isFalse();
+		}
+
+	}
+}
diff --git a/src/test/java/de/ozgcloud/xta/test/app/mapper/ExceptionMapperTest.java b/src/test/java/de/ozgcloud/xta/test/app/mapper/ExceptionMapperTest.java
index 4279ef93590c87f083ba661fcd70e6287c2ff46b..8155892407ee3e270170ca020b48b52adcb04031 100644
--- a/src/test/java/de/ozgcloud/xta/test/app/mapper/ExceptionMapperTest.java
+++ b/src/test/java/de/ozgcloud/xta/test/app/mapper/ExceptionMapperTest.java
@@ -19,14 +19,15 @@ class ExceptionMapperTest {
 	@DisplayName("create invalid message id exception")
 	@Nested
 	class TestCreateInvalidMessageIdException {
-		private final String exceptionMessage = "test message";
+		private static final String MESSAGE_ID = "messageid:test";
+		private static final String IDENTIFIER = "Author";
 
-		@DisplayName("should map message")
+		@DisplayName("should map message id and identifier to message")
 		@Test
 		void shouldMapMessage() {
 			var result = createException();
 
-			assertThat(result.getMessage()).isEqualTo(exceptionMessage);
+			assertThat(result.getMessage()).isEqualTo("No message with messageID \"messageid:test\" available for identifier \"Author\".");
 		}
 
 		@DisplayName("should map error code")
@@ -39,9 +40,8 @@ class ExceptionMapperTest {
 		}
 
 		private InvalidMessageIDException createException() {
-			return mapper.createInvalidMessageIDException(exceptionMessage);
+			return mapper.createInvalidMessageIDException(MESSAGE_ID, IDENTIFIER);
 		}
-
 	}
 
 	@DisplayName("create technical problem exception")
diff --git a/src/test/java/de/ozgcloud/xta/test/app/mapper/RequestMapperTest.java b/src/test/java/de/ozgcloud/xta/test/app/mapper/RequestMapperTest.java
index 0e6128c38f8ef5ffe70927050d5bb0715c4c8c3b..8cbd627c415bc7b8111ab3483f6afa33df9034d9 100644
--- a/src/test/java/de/ozgcloud/xta/test/app/mapper/RequestMapperTest.java
+++ b/src/test/java/de/ozgcloud/xta/test/app/mapper/RequestMapperTest.java
@@ -26,12 +26,8 @@ import de.ozgcloud.xta.test.app.factory.MsgBoxFetchRequestTestFactory;
 import de.ozgcloud.xta.test.app.factory.MsgBoxStatusListRequestTypeTestFactory;
 import de.ozgcloud.xta.test.app.factory.PartyTypeTestFactory;
 import de.ozgcloud.xta.test.app.factory.QualifierTypeBusinessScenarioTestFactory;
-import de.ozgcloud.xta.test.app.model.XtaCloseRequest;
-import de.ozgcloud.xta.test.app.model.XtaFile;
-import de.ozgcloud.xta.test.app.model.XtaGetMessageRequest;
-import de.ozgcloud.xta.test.app.model.XtaIdentifier;
-import de.ozgcloud.xta.test.app.model.XtaLookupServiceRequest;
-import de.ozgcloud.xta.test.app.model.XtaMessageMetaDataListingRequest;
+import de.ozgcloud.xta.test.app.model.*;
+
 import genv3.de.xoev.transport.xta.x211.ContentType;
 import genv3.de.xoev.transport.xta.x211.GenericContentContainer;
 import genv3.eu.osci.ws.x2008.x05.transport.MsgBoxFetchRequest;
@@ -325,4 +321,32 @@ public class RequestMapperTest {
 		}
 	}
 
+	@DisplayName("map xta get transport report request")
+	@Nested
+	class TestMapXtaGetTransportReportRequest {
+		public static final String MESSAGE_ID = "urn:de:xta:messageid:1";
+
+		@DisplayName("should map message id")
+		@Test
+		void shouldMapMessageId() {
+			var result = doMapping();
+
+			assertThat(result.messageId()).isEqualTo(MESSAGE_ID);
+		}
+
+		@DisplayName("should map client identifier")
+		@Test
+		void shouldMapReaderIdentifier() {
+			var result = doMapping();
+
+			assertThat(result.clientIdentifier())
+					.usingRecursiveComparison()
+					.isEqualTo(READER_IDENTIFIER);
+		}
+
+		private XtaGetTransportReportRequest doMapping() {
+			return mapper.mapXtaGetTransportReportRequest(AttributedURITypeTestFactory.create(MESSAGE_ID),
+					PartyTypeTestFactory.create());
+		}
+	}
 }
diff --git a/src/test/java/de/ozgcloud/xta/test/app/mapper/ResponseMapperTest.java b/src/test/java/de/ozgcloud/xta/test/app/mapper/ResponseMapperTest.java
index fee8821f41034c3b4506724114dfcecec86e94b7..4a2a5709f3ede5baa3d9a6d3fdae46d1c4887fae 100644
--- a/src/test/java/de/ozgcloud/xta/test/app/mapper/ResponseMapperTest.java
+++ b/src/test/java/de/ozgcloud/xta/test/app/mapper/ResponseMapperTest.java
@@ -1,20 +1,32 @@
 package de.ozgcloud.xta.test.app.mapper;
 
-import static de.ozgcloud.xta.test.app.factory.MessageMetaDataTestFactory.*;
-import static de.ozgcloud.xta.test.app.factory.PartyIdentifierTypeTestFactory.*;
-import static de.ozgcloud.xta.test.app.factory.XtaLookupServiceRequestTestFactory.*;
+import static de.ozgcloud.xta.test.app.factory.MessageMetaDataTestFactory.MESSAGE_SIZE;
+import static de.ozgcloud.xta.test.app.factory.PartyIdentifierTypeTestFactory.READER_PARTY_IDENTIFIER;
+import static de.ozgcloud.xta.test.app.factory.XtaLookupServiceRequestTestFactory.LOOKUP_SERVICE_SERVICE;
 import static de.ozgcloud.xta.test.app.factory.XtaMessageMetaDataTestFactory.*;
 import static de.ozgcloud.xta.test.app.mapper.ResponseMapper.*;
-import static org.assertj.core.api.Assertions.*;
+import static org.assertj.core.api.Assertions.assertThat;
 
 import java.math.BigInteger;
 import java.nio.charset.StandardCharsets;
+import java.time.ZonedDateTime;
 import java.util.List;
 
+import genv3.de.xoev.transport.xta.x211.ContentType;
+import genv3.de.xoev.transport.xta.x211.LookupServiceResponse;
+import genv3.de.xoev.transport.xta.x211.LookupServiceResultType;
+import genv3.de.xoev.transport.xta.x211.TransportReport;
+import genv3.eu.osci.ws.x2008.x05.transport.MsgStatusListType;
+import genv3.eu.osci.ws.x2014.x10.transport.DeliveryAttributesType;
+import genv3.eu.osci.ws.x2014.x10.transport.MessageMetaData;
+import genv3.eu.osci.ws.x2014.x10.transport.QualifierType;
+import lombok.SneakyThrows;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.DisplayName;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.EnumSource;
 import org.mapstruct.factory.Mappers;
 
 import de.ozgcloud.xta.test.app.factory.XtaFileTestFactory;
@@ -22,15 +34,9 @@ import de.ozgcloud.xta.test.app.factory.XtaLookupServiceRequestTestFactory;
 import de.ozgcloud.xta.test.app.factory.XtaMessageMetaDataTestFactory;
 import de.ozgcloud.xta.test.app.factory.XtaMessageTestFactory;
 import de.ozgcloud.xta.test.app.model.XtaFile;
+import de.ozgcloud.xta.test.app.model.XtaMessageMetaData;
 import de.ozgcloud.xta.test.app.model.XtaMessageMetaDataListing;
-import genv3.de.xoev.transport.xta.x211.ContentType;
-import genv3.de.xoev.transport.xta.x211.LookupServiceResponse;
-import genv3.de.xoev.transport.xta.x211.LookupServiceResultType;
-import genv3.eu.osci.ws.x2008.x05.transport.MsgStatusListType;
-import genv3.eu.osci.ws.x2014.x10.transport.DeliveryAttributesType;
-import genv3.eu.osci.ws.x2014.x10.transport.MessageMetaData;
-import genv3.eu.osci.ws.x2014.x10.transport.QualifierType;
-import lombok.SneakyThrows;
+import de.ozgcloud.xta.test.app.model.XtaTransportReport;
 
 public class ResponseMapperTest {
 
@@ -481,4 +487,81 @@ public class ResponseMapperTest {
 		}
 	}
 
+	@DisplayName("map transport report")
+	@Nested
+	class TestMapTransportReport {
+		private XtaMessageMetaData xtaMessageMetaData;
+		private ZonedDateTime reportTime;
+
+		@BeforeEach
+		void beforeEach() {
+			xtaMessageMetaData = XtaMessageMetaDataTestFactory.create();
+			reportTime = ZonedDateTime.now();
+		}
+
+		@DisplayName("should map message meta data")
+		@Test
+		void shouldMapMessageMetaData() {
+			var result = doMapping();
+
+			assertThat(result.getMessageMetaData().getMsgIdentification().getMessageID().getValue()).isEqualTo(xtaMessageMetaData.messageId());
+		}
+
+		@DisplayName("should map message status")
+		@ParameterizedTest
+		@EnumSource(XtaTransportReport.MessageStatus.class)
+		void shouldMapMessageStatus(XtaTransportReport.MessageStatus status) {
+			var result = doMapping(status);
+
+			assertThat(result.getMessageStatus().getStatus()).isEqualTo(status.ordinal());
+		}
+
+		@DisplayName("should map report time")
+		@Test
+		void shouldMapReportTime() {
+			var result = doMapping();
+
+			assertThat(result.getReportTime()).isEqualTo(mapper.mapXmlGregorianCalendarFromZonedDateTime(reportTime));
+		}
+
+		@DisplayName("should set server identity")
+		@Test
+		void shouldSetServerIdentity() {
+			var result = doMapping();
+
+			assertThat(result.getXTAServerIdentity()).isEqualTo("xta-test-server");
+		}
+
+		private TransportReport doMapping() {
+			return doMapping(XtaTransportReport.MessageStatus.GRUEN);
+		}
+
+		private TransportReport doMapping(XtaTransportReport.MessageStatus status) {
+			return mapper.mapTransportReport(XtaTransportReport.builder()
+					.messageMetaData(xtaMessageMetaData)
+					.status(status)
+					.reportTime(reportTime)
+					.build());
+		}
+	}
+
+	@DisplayName("map XmlGregorianCalendar from LocalDateTime")
+	@Nested
+	class TestMapXmlGregorianCalendarFromLocalDateTime {
+		private ZonedDateTime zonedDateTime;
+		private static final String ISO_TIME_STRING = "2007-12-03T10:15:30.000Z";
+
+		@BeforeEach
+		void beforeEach() {
+			zonedDateTime = ZonedDateTime.parse(ISO_TIME_STRING);
+		}
+
+		@DisplayName("should map xml gregorian calendar from zoned date time")
+		@Test
+		void shouldMapXmlGregorianCalendarFromLocalDateTime() {
+			var result = mapper.mapXmlGregorianCalendarFromZonedDateTime(zonedDateTime);
+
+			assertThat(result.toXMLFormat()).isEqualTo(ISO_TIME_STRING);
+		}
+	}
 }
diff --git a/src/test/java/de/ozgcloud/xta/test/app/server/ManagementPortImplTest.java b/src/test/java/de/ozgcloud/xta/test/app/server/ManagementPortImplTest.java
index 65741330a0c51de32724284959fe827644b8bdce..2f0e112ffe30240a5b6a23943e0b3d7253a835a4 100644
--- a/src/test/java/de/ozgcloud/xta/test/app/server/ManagementPortImplTest.java
+++ b/src/test/java/de/ozgcloud/xta/test/app/server/ManagementPortImplTest.java
@@ -1,9 +1,18 @@
 package de.ozgcloud.xta.test.app.server;
 
-import static de.ozgcloud.xta.test.app.factory.MessageMetaDataTestFactory.*;
-import static org.assertj.core.api.Assertions.*;
+import static de.ozgcloud.xta.test.app.factory.MessageMetaDataTestFactory.MESSAGE_ID;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.mockito.Mockito.*;
 
+import java.util.Optional;
+
+import genv3.de.xoev.transport.xta.x211.InvalidMessageIDException;
+import genv3.de.xoev.transport.xta.x211.LookupServiceRequest;
+import genv3.de.xoev.transport.xta.x211.LookupServiceResponse;
+import genv3.de.xoev.transport.xta.x211.TransportReport;
+import genv3.eu.osci.ws.x2014.x10.transport.PartyType;
+import lombok.SneakyThrows;
 import org.apache.cxf.ws.addressing.AttributedURIType;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.DisplayName;
@@ -12,15 +21,15 @@ import org.junit.jupiter.api.Test;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 
+import de.ozgcloud.xta.test.app.factory.XtaMessageMetaDataTestFactory;
+import de.ozgcloud.xta.test.app.mapper.ExceptionMapper;
 import de.ozgcloud.xta.test.app.mapper.RequestMapper;
 import de.ozgcloud.xta.test.app.mapper.ResponseMapper;
+import de.ozgcloud.xta.test.app.model.XtaGetTransportReportRequest;
 import de.ozgcloud.xta.test.app.model.XtaLookupServiceRequest;
+import de.ozgcloud.xta.test.app.model.XtaTransportReport;
 import de.ozgcloud.xta.test.app.service.XtaMessageService;
 import de.ozgcloud.xta.test.app.validation.RequestValidator;
-import genv3.de.xoev.transport.xta.x211.LookupServiceRequest;
-import genv3.de.xoev.transport.xta.x211.LookupServiceResponse;
-import genv3.eu.osci.ws.x2014.x10.transport.PartyType;
-import lombok.SneakyThrows;
 
 public class ManagementPortImplTest {
 
@@ -30,6 +39,8 @@ public class ManagementPortImplTest {
 	@Mock
 	private XtaMessageService xtaMessageService;
 	@Mock
+	private ExceptionMapper exceptionMapper;
+	@Mock
 	private ResponseMapper responseMapper;
 	@Mock
 	private RequestMapper requestMapper;
@@ -113,4 +124,71 @@ public class ManagementPortImplTest {
 			assertThat(result).isEqualTo(response);
 		}
 	}
+
+	@DisplayName("get transport report")
+	@Nested
+	class TestGetTransportReport {
+		private static final String MESSAGE_ID = "urn:de:xta:messageid:1";
+
+		@Mock
+		private AttributedURIType messageId;
+		@Mock
+		private PartyType authorIdentifier;
+		@Mock
+		private XtaTransportReport xtaTransportReport;
+		@Mock
+		private TransportReport transportReport;
+
+		private XtaGetTransportReportRequest request;
+
+		@BeforeEach
+		void beforeEach() {
+			request = XtaGetTransportReportRequest.builder()
+					.messageId(MESSAGE_ID)
+					.clientIdentifier(XtaMessageMetaDataTestFactory.READER_IDENTIFIER)
+					.build();
+
+			when(requestMapper.mapXtaGetTransportReportRequest(messageId, authorIdentifier)).thenReturn(request);
+		}
+
+		@DisplayName("with valid request")
+		@Nested
+		class TestWithValidRequest {
+			@BeforeEach
+			void beforeEach() {
+				when(xtaMessageService.getTransportReport(request)).thenReturn(Optional.of(xtaTransportReport));
+				when(responseMapper.mapTransportReport(xtaTransportReport)).thenReturn(transportReport);
+			}
+
+			@DisplayName("should return")
+			@Test
+			void shouldReturn() {
+				var result = getTransportReport();
+
+				assertThat(result).isEqualTo(transportReport);
+			}
+		}
+
+		@DisplayName("with Invalid message id")
+		@Nested
+		class TestWithInvalidMessageId {
+			@Mock
+			private InvalidMessageIDException exception;
+
+			@DisplayName("should throw exception")
+			@Test
+			void shouldThrowException() {
+				when(xtaMessageService.getTransportReport(request)).thenReturn(Optional.empty());
+				when(exceptionMapper.createInvalidMessageIDException(any(), any())).thenReturn(exception);
+
+				assertThatThrownBy(TestGetTransportReport.this::getTransportReport)
+						.isEqualTo(exception);
+			}
+		}
+
+		@SneakyThrows
+		private TransportReport getTransportReport() {
+			return managementPortImpl.getTransportReport(messageId, authorIdentifier);
+		}
+	}
 }
\ No newline at end of file
diff --git a/src/test/java/de/ozgcloud/xta/test/app/server/MsgBoxPortImplTest.java b/src/test/java/de/ozgcloud/xta/test/app/server/MsgBoxPortImplTest.java
index 0caf89774c2e0e9a35b69acc1517a8c57ef27b8e..ad1dd9aca9e3c1e0896e3105519b9c3596e0f876 100644
--- a/src/test/java/de/ozgcloud/xta/test/app/server/MsgBoxPortImplTest.java
+++ b/src/test/java/de/ozgcloud/xta/test/app/server/MsgBoxPortImplTest.java
@@ -143,7 +143,7 @@ public class MsgBoxPortImplTest {
 			@Test
 			void shouldThrowException() {
 				when(xtaMessageService.getMessage(request)).thenReturn(Optional.empty());
-				when(exceptionMapper.createInvalidMessageIDException(any())).thenReturn(exception);
+				when(exceptionMapper.createInvalidMessageIDException(any(), any())).thenReturn(exception);
 
 				assertThatThrownBy(TestGetMessage.this::getMessage)
 						.isEqualTo(exception);
@@ -308,7 +308,7 @@ public class MsgBoxPortImplTest {
 			@Test
 			void shouldThrowException() {
 				when(xtaMessageService.closeMessage(request)).thenReturn(false);
-				when(exceptionMapper.createInvalidMessageIDException(any())).thenReturn(exception);
+				when(exceptionMapper.createInvalidMessageIDException(any(), any())).thenReturn(exception);
 
 				assertThatThrownBy(TestClose.this::close)
 						.isEqualTo(exception);
diff --git a/src/test/java/de/ozgcloud/xta/test/app/service/XtaMessageServiceTest.java b/src/test/java/de/ozgcloud/xta/test/app/service/XtaMessageServiceTest.java
index 6723c0e40c5cb749249d82aa4f8062f4e82511ba..ff75022fd71553d543e318141972ab35824ba3a6 100644
--- a/src/test/java/de/ozgcloud/xta/test/app/service/XtaMessageServiceTest.java
+++ b/src/test/java/de/ozgcloud/xta/test/app/service/XtaMessageServiceTest.java
@@ -23,17 +23,18 @@ import org.mockito.Spy;
 import org.springframework.core.env.Environment;
 
 import de.ozgcloud.xta.test.app.data.XtaMessageRepository;
+import de.ozgcloud.xta.test.app.data.XtaTransportReportRepository;
 import de.ozgcloud.xta.test.app.factory.XtaCloseRequestTestFactory;
+import de.ozgcloud.xta.test.app.factory.XtaMessageMetaDataTestFactory;
 import de.ozgcloud.xta.test.app.factory.XtaMessageTestFactory;
-import de.ozgcloud.xta.test.app.model.XtaGetMessageRequest;
-import de.ozgcloud.xta.test.app.model.XtaMessage;
-import de.ozgcloud.xta.test.app.model.XtaMessageMetaDataListing;
-import de.ozgcloud.xta.test.app.model.XtaMessageMetaDataListingRequest;
+import de.ozgcloud.xta.test.app.model.*;
 
 public class XtaMessageServiceTest {
 	@Mock
 	private XtaMessageRepository messageRepository;
 	@Mock
+	private XtaTransportReportRepository transportReportRepository;
+	@Mock
 	private Environment environment;
 
 	@Spy
@@ -50,8 +51,18 @@ public class XtaMessageServiceTest {
 			message = XtaMessageTestFactory.create(MESSAGE_ID);
 		}
 
+		@Test
+		void shouldSaveTransportReport() {
+			message = XtaMessageTestFactory.create(MESSAGE_ID);
+
+			service.sendMessage(message);
+
+			verify(transportReportRepository).add(message.metaData());
+		}
+
 		@Test
 		void shouldSaveMessage() {
+			when(transportReportRepository.add(message.metaData())).thenReturn(true);
 			message = XtaMessageTestFactory.create(MESSAGE_ID);
 
 			service.sendMessage(message);
@@ -153,13 +164,40 @@ public class XtaMessageServiceTest {
 	@DisplayName("is author or reader of message")
 	@Nested
 	class TestIsAuthorOrReaderOfMessage {
+		@Test
+		void shouldUseIsAuthorOrReaderOfMessageMetaData() {
+			var message = XtaMessageTestFactory.create(MESSAGE_ID_1);
+
+			service.isAuthorOrReaderOfMessage(READER_IDENTIFIER.value()).test(message);
+
+			verify(service).isAuthorOrReaderOfMessageMetadata(READER_IDENTIFIER.value());
+		}
+	}
 
+	@DisplayName("is author or reader of transport report")
+	@Nested
+	class TestIsAuthorOrReaderOfTransportReport {
+		@Test
+		void shouldUseIsAuthorOrReaderOfMessageMetaData() {
+			var transportReport = XtaTransportReport.builder()
+					.messageMetaData(XtaMessageMetaDataTestFactory.create(MESSAGE_ID_1))
+					.build();
+
+			service.isAuthorOrReaderOfTransportReport(READER_IDENTIFIER.value()).test(transportReport);
+
+			verify(service).isAuthorOrReaderOfMessageMetadata(READER_IDENTIFIER.value());
+		}
+	}
+
+	@DisplayName("is author or reader of message metadata")
+	@Nested
+	class TestIsAuthorOrReaderOfMessageMetaData {
 		@DisplayName("should return true if reader identifier value matches")
 		@Test
 		void shouldReturnTrueIfReaderIdentifierValueMatches() {
-			var message = XtaMessageTestFactory.create(MESSAGE_ID_1);
+			var messageMetaData = XtaMessageMetaDataTestFactory.create(MESSAGE_ID_1);
 
-			var result = service.isAuthorOrReaderOfMessage(READER_IDENTIFIER.value()).test(message);
+			var result = service.isAuthorOrReaderOfMessageMetadata(READER_IDENTIFIER.value()).test(messageMetaData);
 
 			assertThat(result).isTrue();
 		}
@@ -167,9 +205,9 @@ public class XtaMessageServiceTest {
 		@DisplayName("should return true if author identifier value matches")
 		@Test
 		void shouldReturnTrueIfAuthorIdentifierValueMatches() {
-			var message = XtaMessageTestFactory.create(MESSAGE_ID_1);
+			var messageMetaData = XtaMessageMetaDataTestFactory.create(MESSAGE_ID_1);
 
-			var result = service.isAuthorOrReaderOfMessage(AUTHOR_IDENTIFIER.value()).test(message);
+			var result = service.isAuthorOrReaderOfMessageMetadata(AUTHOR_IDENTIFIER.value()).test(messageMetaData);
 
 			assertThat(result).isTrue();
 		}
@@ -177,9 +215,9 @@ public class XtaMessageServiceTest {
 		@DisplayName("should return false if neither reader nor author identifier value matches")
 		@Test
 		void shouldReturnFalseIfNeitherReaderNorAuthorIdentifierValueMatches() {
-			var message = XtaMessageTestFactory.create(MESSAGE_ID_1);
+			var messageMetaData = XtaMessageMetaDataTestFactory.create(MESSAGE_ID_1);
 
-			var result = service.isAuthorOrReaderOfMessage("unknown").test(message);
+			var result = service.isAuthorOrReaderOfMessageMetadata("unknown").test(messageMetaData);
 
 			assertThat(result).isFalse();
 		}
@@ -197,11 +235,66 @@ public class XtaMessageServiceTest {
 			when(messageRepository.deleteByMessageIdAndReaderIdentifierValue(
 					request.messageId(), request.clientIdentifier().value())
 			).thenReturn(deleted);
+			when(transportReportRepository.setClosedStatus(request.messageId())).thenReturn(deleted);
 
 			boolean result = service.closeMessage(request);
 
 			assertThat(result).isEqualTo(deleted);
+		}
 
+		@DisplayName("should set transport status to closed")
+		@Test
+		void shouldSetTransportReportClosedStatus() {
+			var request = XtaCloseRequestTestFactory.create();
+
+			service.closeMessage(request);
+
+			verify(transportReportRepository).setClosedStatus(request.messageId());
+		}
+	}
+
+	@Nested
+	class TestGetTransportReport {
+		private static final XtaGetTransportReportRequest GET_TRANSPORT_REPORT_REQUEST = XtaGetTransportReportRequest.builder()
+				.messageId(MESSAGE_ID_1)
+				.clientIdentifier(READER_IDENTIFIER)
+				.build();
+		private static final Predicate<XtaTransportReport> IS_AUTHOR_OR_READER = m -> true;
+		private static final Predicate<XtaTransportReport> IS_NOT_AUTHOR_OR_READER = m -> false;
+
+		@Mock
+		XtaTransportReport report;
+
+		@DisplayName("should return")
+		@Test
+		void shouldReturn() {
+			when(transportReportRepository.get(MESSAGE_ID_1)).thenReturn(Optional.of(report));
+			doReturn(IS_AUTHOR_OR_READER).when(service).isAuthorOrReaderOfTransportReport(READER_IDENTIFIER.value());
+
+			var result = service.getTransportReport(GET_TRANSPORT_REPORT_REQUEST);
+
+			assertThat(result).contains(report);
+		}
+
+		@DisplayName("should return empty if message id not found")
+		@Test
+		void shouldReturnEmptyIfMessageIdNotFound() {
+			when(transportReportRepository.get(MESSAGE_ID_1)).thenReturn(Optional.empty());
+
+			var result = service.getTransportReport(GET_TRANSPORT_REPORT_REQUEST);
+
+			assertThat(result).isEmpty();
+		}
+
+		@DisplayName("should return empty if not author or reader")
+		@Test
+		void shouldReturnEmptyIfNotAuthorOrReader() {
+			when(transportReportRepository.get(MESSAGE_ID_1)).thenReturn(Optional.of(report));
+			doReturn(IS_NOT_AUTHOR_OR_READER).when(service).isAuthorOrReaderOfTransportReport(READER_IDENTIFIER.value());
+
+			var result = service.getTransportReport(GET_TRANSPORT_REPORT_REQUEST);
+
+			assertThat(result).isEmpty();
 		}
 	}