diff --git a/document-manager-server/src/main/java/de/ozgcloud/document/DocumentManagerConfiguration.java b/document-manager-server/src/main/java/de/ozgcloud/document/DocumentManagerConfiguration.java
index 8470d4db36c833c248901b269f1fd1e18a86c40f..3dfcad69044e784b0cb7accb5e8f19c8125d95ec 100644
--- a/document-manager-server/src/main/java/de/ozgcloud/document/DocumentManagerConfiguration.java
+++ b/document-manager-server/src/main/java/de/ozgcloud/document/DocumentManagerConfiguration.java
@@ -40,8 +40,9 @@ import net.devh.boot.grpc.client.inject.GrpcClient;
 @Configuration
 public class DocumentManagerConfiguration {
 
-	private static final String GRPC_USER_MANAGER_NAME = "user-manager";
-	private static final String GRPC_COMMAND_MANAGER_NAME = "command-manager";
+	public static final String GRPC_USER_MANAGER_NAME = "user-manager";
+	public static final String GRPC_COMMAND_MANAGER_NAME = "command-manager";
+	public static final String GRPC_VORGANG_MANAGER_NAME = "vorgang-manager";
 
 	public static final String COMMAND_SERVICE_NAME = "document_OzgCloudCommandService";
 	public static final String USER_PROFILE_SERVICE_NAME = "document_OzgCloudUserProfileService";
diff --git a/document-manager-server/src/main/java/de/ozgcloud/document/bescheid/binaryfile/BinaryFileRemoteService.java b/document-manager-server/src/main/java/de/ozgcloud/document/bescheid/binaryfile/BinaryFileRemoteService.java
index 4ef6b761f7de2e7751311d815fddb04ae1f3c12c..12c75d382c407e5445fdad47149ea64354ae438f 100644
--- a/document-manager-server/src/main/java/de/ozgcloud/document/bescheid/binaryfile/BinaryFileRemoteService.java
+++ b/document-manager-server/src/main/java/de/ozgcloud/document/bescheid/binaryfile/BinaryFileRemoteService.java
@@ -15,18 +15,17 @@ import org.springframework.stereotype.Service;
 
 import com.google.protobuf.ByteString;
 
-import de.ozgcloud.document.DocumentManagerConfiguration;
-import de.ozgcloud.document.bescheid.BescheidCallContextAttachingInterceptor;
-import de.ozgcloud.document.bescheid.BescheidResponse;
 import de.ozgcloud.common.binaryfile.FileId;
 import de.ozgcloud.common.binaryfile.GrpcFileUploadUtils;
 import de.ozgcloud.common.binaryfile.GrpcFileUploadUtils.FileSender;
 import de.ozgcloud.common.errorhandling.TechnicalException;
+import de.ozgcloud.document.DocumentManagerConfiguration;
+import de.ozgcloud.document.bescheid.BescheidCallContextAttachingInterceptor;
+import de.ozgcloud.document.bescheid.BescheidResponse;
 import de.ozgcloud.vorgang.grpc.binaryFile.BinaryFileServiceGrpc.BinaryFileServiceStub;
 import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileMetaData;
 import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileRequest;
 import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileResponse;
-import de.ozgcloud.vorgang.grpc.command.GrpcCallContext;
 import io.grpc.stub.CallStreamObserver;
 import io.grpc.stub.StreamObserver;
 import lombok.NonNull;
@@ -37,10 +36,9 @@ import net.devh.boot.grpc.client.inject.GrpcClient;
 @RequiredArgsConstructor
 class BinaryFileRemoteService {
 
-	private static final String CALL_CONTEXT_CLIENT = "bescheid-manager";
-	private static final String VORGANG_ATTACHMENT_FIELD = "bescheid";
+	static final String VORGANG_ATTACHMENT_FIELD = "bescheid";
 
-	@GrpcClient("vorgang-manager")
+	@GrpcClient(DocumentManagerConfiguration.GRPC_VORGANG_MANAGER_NAME)
 	private final BinaryFileServiceStub binaryFileRemoteStub;
 	@Qualifier(DocumentManagerConfiguration.CALL_CONTEXT_CLIENT_INTERCEPTOR_NAME)
 	private final BescheidCallContextAttachingInterceptor callContextInterceptor;
@@ -58,7 +56,7 @@ class BinaryFileRemoteService {
 		}
 	}
 
-	private InputStream openFile(File file) {
+	InputStream openFile(File file) {
 		try {
 			return new FileInputStream(file);
 		} catch (FileNotFoundException e) {
@@ -66,11 +64,9 @@ class BinaryFileRemoteService {
 		}
 	}
 
-	private GrpcUploadBinaryFileRequest buildMetaDataRequest(BescheidResponse bescheid) {
+	GrpcUploadBinaryFileRequest buildMetaDataRequest(BescheidResponse bescheid) {
 		return GrpcUploadBinaryFileRequest.newBuilder()
 				.setMetadata(GrpcUploadBinaryFileMetaData.newBuilder()
-						// TODO remove context - check why needed!
-						.setContext(GrpcCallContext.newBuilder().setClient(CALL_CONTEXT_CLIENT).build())
 						.setVorgangId(bescheid.getVorgangId().toString())
 						.setField(VORGANG_ATTACHMENT_FIELD)
 						.setContentType(bescheid.getContentType())
@@ -80,11 +76,11 @@ class BinaryFileRemoteService {
 				.build();
 	}
 
-	private GrpcUploadBinaryFileRequest buildChunkRequest(byte[] bytes, Integer length) {
+	GrpcUploadBinaryFileRequest buildChunkRequest(byte[] bytes, Integer length) {
 		return GrpcUploadBinaryFileRequest.newBuilder().setFileContent((ByteString.copyFrom(bytes, 0, length))).build();
 	}
 
-	private CallStreamObserver<GrpcUploadBinaryFileRequest> buildCallStreamObserver(
+	CallStreamObserver<GrpcUploadBinaryFileRequest> buildCallStreamObserver(
 			StreamObserver<GrpcUploadBinaryFileResponse> responseObserver) {
 		return (CallStreamObserver<GrpcUploadBinaryFileRequest>) binaryFileRemoteStub.withInterceptors(callContextInterceptor)
 				.uploadBinaryFileAsStream(responseObserver);
diff --git a/document-manager-server/src/test/java/de/ozgcloud/document/bescheid/binaryfile/BinaryFileRemoteServiceTest.java b/document-manager-server/src/test/java/de/ozgcloud/document/bescheid/binaryfile/BinaryFileRemoteServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..b1d5b0cf4bf9f9a92d8b451a9640baaec3131732
--- /dev/null
+++ b/document-manager-server/src/test/java/de/ozgcloud/document/bescheid/binaryfile/BinaryFileRemoteServiceTest.java
@@ -0,0 +1,370 @@
+/*
+ * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den
+ * Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei
+ * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+package de.ozgcloud.document.bescheid.binaryfile;
+
+import static org.assertj.core.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+import java.io.InputStream;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+import org.apache.commons.io.IOUtils;
+import org.junit.jupiter.api.AfterEach;
+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.ValueSource;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockedStatic;
+import org.mockito.Spy;
+
+import de.ozgcloud.common.binaryfile.FileId;
+import de.ozgcloud.common.binaryfile.GrpcFileUploadUtils;
+import de.ozgcloud.common.errorhandling.TechnicalException;
+import de.ozgcloud.document.bescheid.BescheidCallContextAttachingInterceptor;
+import de.ozgcloud.document.bescheid.BescheidResponse;
+import de.ozgcloud.document.bescheid.BescheidResponseTestFactory;
+import de.ozgcloud.vorgang.grpc.binaryFile.BinaryFileServiceGrpc.BinaryFileServiceStub;
+import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileRequest;
+import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileResponse;
+import io.grpc.stub.CallStreamObserver;
+import io.grpc.stub.StreamObserver;
+import lombok.SneakyThrows;
+
+class BinaryFileRemoteServiceTest {
+
+	@Spy
+	@InjectMocks
+	private BinaryFileRemoteService remoteService;
+
+	@Mock
+	private BinaryFileServiceStub binaryFileServiceStub;
+	@Mock
+	private BescheidCallContextAttachingInterceptor callContextInterceptor;
+	@Mock
+	private StreamObserver<GrpcUploadBinaryFileResponse> responseObserver;
+	@Mock
+	private GrpcUploadBinaryFileResponse grpcUploadResponse;
+	@Mock
+	private GrpcFileUploadUtils.FileSender<GrpcUploadBinaryFileRequest, GrpcUploadBinaryFileResponse> initialisedFileSender;
+	@Mock
+	private InputStream inputStream;
+
+	@Nested
+	class TestUploadBescheidFile {
+
+		private static final BescheidResponse BESCHEID_RESPONSE = BescheidResponseTestFactory.create();
+		private static final FileId FILE_ID = FileId.createNew();
+
+		@Mock
+		private GrpcFileUploadUtils.FileSender<GrpcUploadBinaryFileRequest, GrpcUploadBinaryFileResponse> createdFileSender;
+		@Mock
+		private GrpcFileUploadUtils.FileSender<GrpcUploadBinaryFileRequest, GrpcUploadBinaryFileResponse> fileSenderWithMetadata;
+		@Mock
+		private CallStreamObserver<GrpcUploadBinaryFileRequest> requestObserver;
+		@Mock
+		private GrpcUploadBinaryFileRequest grpcUploadRequest;
+
+		@Captor
+		private ArgumentCaptor<BiFunction<byte[], Integer, GrpcUploadBinaryFileRequest>> buildChunkRequestCaptor;
+		@Captor
+		private ArgumentCaptor<Function<StreamObserver<GrpcUploadBinaryFileResponse>, CallStreamObserver<GrpcUploadBinaryFileRequest>>> buildCallStreamObserverCaptor;
+
+		private MockedStatic<GrpcFileUploadUtils> uploadUtilsMock;
+
+		@BeforeEach
+		void init() {
+			doReturn(inputStream).when(remoteService).openFile(any());
+			doReturn(grpcUploadResponse).when(remoteService).waitUntilFutureToComplete(any(), any());
+			when(grpcUploadResponse.getFileId()).thenReturn(FILE_ID.toString());
+
+			uploadUtilsMock = mockStatic(GrpcFileUploadUtils.class);
+			when(createdFileSender.withMetaData(any())).thenReturn(fileSenderWithMetadata);
+			when(fileSenderWithMetadata.send()).thenReturn(initialisedFileSender);
+			uploadUtilsMock.when(() -> GrpcFileUploadUtils.createSender(any(), any(), any())).thenReturn(createdFileSender);
+		}
+
+		@AfterEach
+		void cleanup() {
+			uploadUtilsMock.close();
+		}
+
+		@Test
+		void shouldCallOpenFile() {
+			uploadBescheidFile();
+
+			verify(remoteService).openFile(BescheidResponseTestFactory.BESCHEID_FILE);
+		}
+
+		@Test
+		void shouldCallCreateSender() {
+			uploadBescheidFile();
+
+			uploadUtilsMock.verify(() -> GrpcFileUploadUtils.createSender(buildChunkRequestCaptor.capture(), eq(inputStream),
+					buildCallStreamObserverCaptor.capture()));
+			verifyCallBuildChunkRequest();
+			verifyCallBuildCallStreamObserver();
+		}
+
+		@Test
+		void shouldCallBuildMetaDataRequest() {
+			uploadBescheidFile();
+
+			verify(remoteService).buildMetaDataRequest(BESCHEID_RESPONSE);
+		}
+
+		@Test
+		void shouldCallWithMetaData() {
+			doReturn(grpcUploadRequest).when(remoteService).buildMetaDataRequest(any());
+
+			uploadBescheidFile();
+
+			verify(createdFileSender).withMetaData(grpcUploadRequest);
+		}
+
+		@Test
+		void shouldCallSend() {
+			uploadBescheidFile();
+
+			verify(fileSenderWithMetadata).send();
+		}
+
+		@Test
+		void shouldCallWaitUntilFutureToComplete() {
+			uploadBescheidFile();
+
+			verify(remoteService).waitUntilFutureToComplete(initialisedFileSender, inputStream);
+		}
+
+		@Test
+		void shouldReturnFileId() {
+			var result = uploadBescheidFile();
+
+			assertThat(result).isEqualTo(FILE_ID);
+		}
+
+		private FileId uploadBescheidFile() {
+			return remoteService.uploadBescheidFile(BESCHEID_RESPONSE);
+		}
+
+		private void verifyCallBuildChunkRequest() {
+			doReturn(grpcUploadRequest).when(remoteService).buildChunkRequest(any(), any());
+			var bytes = new byte[1];
+			var length = 1;
+
+			buildChunkRequestCaptor.getValue().apply(bytes, length);
+			verify(remoteService).buildChunkRequest(bytes, length);
+		}
+
+		private void verifyCallBuildCallStreamObserver() {
+			doReturn(requestObserver).when(remoteService).buildCallStreamObserver(any());
+
+			buildCallStreamObserverCaptor.getValue().apply(responseObserver);
+			verify(remoteService).buildCallStreamObserver(responseObserver);
+		}
+	}
+
+	@Nested
+	class TestOpenFile {
+
+		@Test
+		void shouldReturnInputStream() {
+			var result = remoteService.openFile(BescheidResponseTestFactory.BESCHEID_FILE);
+
+			assertThat(result).hasBinaryContent(BescheidResponseTestFactory.BESCHEID_FILE_NAME.getBytes());
+		}
+	}
+
+	@Nested
+	class TestBuildMetaDataRequest {
+
+		@Test
+		void shouldReturnGrpcUploadBinaryFileRequest() {
+			var requestMetadata = GrpcUploadBinaryFileMetaDataTestFactory.createBuilder().setField(BinaryFileRemoteService.VORGANG_ATTACHMENT_FIELD)
+					.build();
+
+			var result = remoteService.buildMetaDataRequest(BescheidResponseTestFactory.create());
+
+			assertThat(result.getMetadata()).usingRecursiveComparison().isEqualTo(requestMetadata);
+			assertThat(result.getFileContent()).isEmpty();
+		}
+	}
+
+	@Nested
+	class TestBuildChunkRequest {
+
+		@Test
+		void shouldSetFileContent() {
+			var bytes = BescheidResponseTestFactory.BESCHEID_FILE_NAME.getBytes();
+			var length = BescheidResponseTestFactory.BESCHEID_FILE_NAME.length();
+
+			var result = remoteService.buildChunkRequest(bytes, length);
+
+			assertThat(result.getFileContent().toStringUtf8()).isEqualTo(BescheidResponseTestFactory.BESCHEID_FILE_NAME);
+		}
+	}
+
+	@Nested
+	class TestBuildCallStreamObserver {
+
+		@Mock
+		private BinaryFileServiceStub binaryFileServiceStubWithInterceptor;
+
+		@BeforeEach
+		void init() {
+			when(binaryFileServiceStub.withInterceptors(callContextInterceptor)).thenReturn(binaryFileServiceStubWithInterceptor);
+		}
+
+		@Test
+		void shouldSetInterceptor() {
+			buildCallStreamObserver();
+
+			verify(binaryFileServiceStub).withInterceptors(callContextInterceptor);
+		}
+
+		@Test
+		void shouldCallUploadBinaryFileAsStream() {
+			buildCallStreamObserver();
+
+			verify(binaryFileServiceStubWithInterceptor).uploadBinaryFileAsStream(responseObserver);
+		}
+
+		private CallStreamObserver<GrpcUploadBinaryFileRequest> buildCallStreamObserver() {
+			return remoteService.buildCallStreamObserver(responseObserver);
+		}
+	}
+
+	@Nested
+	class TestWaitUntilFutureToComplete {
+
+		@Mock
+		private GrpcUploadBinaryFileResponse grpcUploadResponse;
+		@Mock
+		private CompletableFuture<GrpcUploadBinaryFileResponse> responseFuture;
+
+		@BeforeEach
+		void init() {
+			when(initialisedFileSender.getResultFuture()).thenReturn(responseFuture);
+		}
+
+		@Nested
+		class TestOnSuccess {
+
+			@SneakyThrows
+			@BeforeEach
+			void init() {
+				when(responseFuture.get(anyLong(), any())).thenReturn(grpcUploadResponse);
+			}
+
+			@Test
+			void shouldReturnResponse() {
+				var result = waitUntilFutureToComplete();
+
+				assertThat(result).isSameAs(grpcUploadResponse);
+			}
+
+			@Test
+			void shouldCloseStream() {
+				try (var ioUtilsMock = mockStatic(IOUtils.class)) {
+					waitUntilFutureToComplete();
+
+					ioUtilsMock.verify(() -> IOUtils.closeQuietly(inputStream));
+				}
+			}
+		}
+
+		@Nested
+		class TestOnInterruptedException {
+
+			@Mock
+			private InterruptedException exception;
+
+			@BeforeEach
+			void init() throws ExecutionException, InterruptedException, TimeoutException {
+				when(responseFuture.get(anyLong(), any())).thenThrow(exception);
+			}
+
+			@Test
+			void shouldCallCancelOnError() {
+				assertThrows(TechnicalException.class, TestWaitUntilFutureToComplete.this::waitUntilFutureToComplete);
+
+				verify(initialisedFileSender).cancelOnError(exception);
+			}
+
+			@Test
+			void shouldCloseStream() {
+				try (var ioUtilsMock = mockStatic(IOUtils.class)) {
+					assertThrows(TechnicalException.class, TestWaitUntilFutureToComplete.this::waitUntilFutureToComplete);
+
+					ioUtilsMock.verify(() -> IOUtils.closeQuietly(inputStream));
+				}
+			}
+		}
+
+		@Nested
+		class TestOnException {
+
+			@SneakyThrows
+			@DisplayName("should cancel on timeout")
+			@ParameterizedTest(name = "when {0} is thrown")
+			@ValueSource(classes = { ExecutionException.class, TimeoutException.class })
+			void shouldCancelOnTimeoutOnTimeoutException(Class<Exception> exceptionClass) {
+				when(responseFuture.get(anyLong(), any())).thenThrow(exceptionClass);
+
+				assertThrows(TechnicalException.class, TestWaitUntilFutureToComplete.this::waitUntilFutureToComplete);
+
+				verify(initialisedFileSender).cancelOnTimeout();
+			}
+
+			@SneakyThrows
+			@DisplayName("should close stream")
+			@ParameterizedTest(name = "when {0} is thrown")
+			@ValueSource(classes = { ExecutionException.class, TimeoutException.class })
+			void shouldCloseStream(Class<Exception> exceptionClass) {
+				try (var ioUtilsMock = mockStatic(IOUtils.class)) {
+					when(responseFuture.get(anyLong(), any())).thenThrow(exceptionClass);
+
+					assertThrows(TechnicalException.class, TestWaitUntilFutureToComplete.this::waitUntilFutureToComplete);
+
+					ioUtilsMock.verify(() -> IOUtils.closeQuietly(inputStream));
+				}
+			}
+		}
+
+		private GrpcUploadBinaryFileResponse waitUntilFutureToComplete() {
+			return remoteService.waitUntilFutureToComplete(initialisedFileSender, inputStream);
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/document-manager-server/src/test/java/de/ozgcloud/document/bescheid/binaryfile/GrpcUploadBinaryFileMetaDataTestFactory.java b/document-manager-server/src/test/java/de/ozgcloud/document/bescheid/binaryfile/GrpcUploadBinaryFileMetaDataTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..9680d544810c33865349dad68392fe665d2bd7ed
--- /dev/null
+++ b/document-manager-server/src/test/java/de/ozgcloud/document/bescheid/binaryfile/GrpcUploadBinaryFileMetaDataTestFactory.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den
+ * Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei
+ * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+package de.ozgcloud.document.bescheid.binaryfile;
+
+import com.thedeanda.lorem.LoremIpsum;
+
+import de.ozgcloud.document.bescheid.BescheidResponseTestFactory;
+import de.ozgcloud.document.bescheid.vorgang.VorgangTestFactory;
+import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileMetaData;
+
+public class GrpcUploadBinaryFileMetaDataTestFactory {
+
+	public static final String VORGANG_ID = VorgangTestFactory.ID_STR;
+	public static final String FIELD = LoremIpsum.getInstance().getWords(1);
+	public static final String CONTENT_TYPE = BescheidResponseTestFactory.CONTENT_TYPE;
+	public static final int SIZE = BescheidResponseTestFactory.BESCHEID_FILE_SIZE;
+	public static final String FILE_NAME = BescheidResponseTestFactory.BESCHEID_FILE_NAME;
+
+	public static GrpcUploadBinaryFileMetaData create() {
+		return createBuilder().build();
+	}
+
+	public static GrpcUploadBinaryFileMetaData.Builder createBuilder() {
+		return GrpcUploadBinaryFileMetaData.newBuilder()
+						.setVorgangId(VORGANG_ID)
+						.setField(FIELD)
+						.setContentType(CONTENT_TYPE)
+						.setSize(SIZE)
+						.setFileName(FILE_NAME);
+	}
+}