Skip to content
Snippets Groups Projects
Commit 58a8df02 authored by OZGCloud's avatar OZGCloud
Browse files

Merge branch 'master' into OZG-7143-download-timeout

# Conflicts:
#	ozgcloud-common-lib/src/main/java/de/ozgcloud/common/binaryfile/GrpcBinaryFileServerDownloader.java
parents ea049edf 65647fb4
No related branches found
No related tags found
No related merge requests found
......@@ -6,6 +6,7 @@
### 4.6.0
* Update [OZGCloud License Generator](ozgcloud-common-license/readme.md)
* `GrpcUtil` erweitern: mehr Schlüssel hinzufügen und Methoden, um diese Schlüssel aus gRPC-Metadaten zu extrahieren.
### 4.5.0
* common-lib erweitern: gRPC Server Downloader für binäre Dateien hinzufügen
......
......@@ -25,7 +25,6 @@ package de.ozgcloud.common.binaryfile;
import com.google.protobuf.ByteString;
import de.ozgcloud.common.errorhandling.TechnicalException;
import io.grpc.Context;
import io.grpc.stub.CallStreamObserver;
import lombok.Builder;
import lombok.extern.log4j.Log4j2;
......@@ -80,7 +79,7 @@ public class GrpcBinaryFileServerDownloader<T> {
void doStart() {
LOG.debug("Starting download.");
handleSafety(this::setupStreams);
taskExecutor.execute(Context.current().wrap(this::startDownload));
taskExecutor.execute(this::startDownload);
callObserver.setOnReadyHandler(this::sendChunks);
}
......
......@@ -24,10 +24,10 @@
package de.ozgcloud.common.grpc;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import io.grpc.Metadata;
......@@ -39,8 +39,12 @@ import lombok.NoArgsConstructor;
public class GrpcUtil {
public static final Key<byte[]> HEADER_KEY_USER_ID = createKeyOf("USER_ID-bin");
public static final Key<byte[]> HEADER_KEY_USER_NAME = createKeyOf("USER_NAME-bin");
public static final Key<byte[]> HEADER_KEY_CLIENT_NAME = createKeyOf("CLIENT_NAME-bin");
public static final Key<byte[]> HEADER_KEY_REQUEST_ID = createKeyOf("REQUEST_ID-bin");
public static final String KEY_REQUEST_ID = "REQUEST_ID-bin";
public static final Key<byte[]> HEADER_KEY_REQUEST_ID = createKeyOf(KEY_REQUEST_ID);
public static final Key<byte[]> HEADER_KEY_ACCESS_LIMITED_ORGAID = createKeyOf("ACCESS_LIMITED_TO_ORGANISATORISCHEEINHEITENID-bin");
public static final Key<byte[]> HEADER_KEY_ACCESS_LIMITED = createKeyOf("ACCESS_LIMITED-bin");
public static Key<String> keyOfString(String key) {
return Key.of(key, Metadata.ASCII_STRING_MARSHALLER);
......@@ -50,6 +54,30 @@ public class GrpcUtil {
return Key.of(key, Metadata.BINARY_BYTE_MARSHALLER);
}
public static Optional<String> getRequestId(Metadata headers) {
return getFromHeaders(HEADER_KEY_REQUEST_ID, headers);
}
public static Optional<String> getClientName(Metadata headers) {
return getFromHeaders(HEADER_KEY_CLIENT_NAME, headers);
}
public static Optional<String> getUserId(Metadata headers) {
return getFromHeaders(HEADER_KEY_USER_ID, headers);
}
public static Optional<String> getUserName(Metadata headers) {
return getFromHeaders(HEADER_KEY_USER_NAME, headers);
}
public static List<String> getAccessLimitedOrgaIds(Metadata headers) {
return getList(HEADER_KEY_ACCESS_LIMITED_ORGAID, headers);
}
public static Optional<Boolean> getAccessLimited(Metadata headers) {
return getFromHeaders(HEADER_KEY_ACCESS_LIMITED, headers).map(Boolean::parseBoolean);
}
public static Optional<String> getFromHeaders(String key, Metadata headers) {
return getFromHeaders(createKeyOf(key), headers);
}
......@@ -58,14 +86,21 @@ public class GrpcUtil {
return Optional.ofNullable(headers.get(key)).map(GrpcUtil::byteToString);
}
public static Collection<String> getCollection(String key, Metadata headers) {
final List<String> result = new ArrayList<>();
var valuesOptional = Optional.ofNullable(headers.getAll(createKeyOf(key)));
valuesOptional.ifPresent(valuesBytes -> result.addAll(StreamSupport.stream(valuesBytes.spliterator(), false)
.map(GrpcUtil::byteToString)
.toList()));
/**
* @deprecated since 4.6.0, use {@link #getList(String, Metadata)} instead
*/
@Deprecated(since = "4.6.0", forRemoval = true)
public static List<String> getCollection(String key, Metadata headers) {
return getList(key, headers);
}
public static List<String> getList(String key, Metadata headers) {
return getList(createKeyOf(key), headers);
}
return result;
public static List<String> getList(Key<byte[]> key, Metadata headers) {
return Optional.ofNullable(headers.getAll(key)).map(valuesBytes -> StreamSupport.stream(valuesBytes.spliterator(), false))
.orElseGet(Stream::empty).map(GrpcUtil::byteToString).toList();
}
private static String byteToString(byte[] bytes) {
......
......@@ -121,13 +121,6 @@ class GrpcBinaryFileServerDownloaderTest {
@Nested
class TestDoStart {
@Mock
private Context callContext;
@Mock
private Runnable wrappedRunnable;
@Captor
private ArgumentCaptor<Runnable> wrappedRunnableCaptor;
@Captor
private ArgumentCaptor<Runnable> runnableCaptor;
@Captor
......@@ -145,32 +138,16 @@ class GrpcBinaryFileServerDownloaderTest {
verify(downloader).setupStreams();
}
@Test
void shouldCallTaskExecutor() {
try (var contextMock = mockStatic(Context.class)) {
contextMock.when(Context::current).thenReturn(callContext);
when(callContext.wrap(any(Runnable.class))).thenReturn(wrappedRunnable);
downloader.doStart();
verify(taskExecutor).execute(wrappedRunnable);
}
}
@Test
void shouldCallStartDownload() {
try (var contextMock = mockStatic(Context.class)) {
contextMock.when(Context::current).thenReturn(callContext);
when(callContext.wrap(any(Runnable.class))).thenReturn(wrappedRunnable);
doNothing().when(downloader).startDownload();
downloader.doStart();
verify(callContext).wrap(wrappedRunnableCaptor.capture());
wrappedRunnableCaptor.getValue().run();
verify(taskExecutor).execute(runnableCaptor.capture());
runnableCaptor.getValue().run();
verify(downloader).startDownload();
}
}
@SneakyThrows
@Test
......
......@@ -2,6 +2,7 @@ package de.ozgcloud.common.grpc;
import static org.assertj.core.api.Assertions.*;
import com.thedeanda.lorem.LoremIpsum;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
......@@ -9,14 +10,15 @@ import org.junit.jupiter.api.Test;
import io.grpc.Metadata;
import java.util.UUID;
class GrpcUtilTest {
private static final String KEY_VALUE_BIN = "key_value-bin";
private static final String KEY_VALUE_STRING = "key_value";
private static final String UNKNOWN_KEY_BIN = "unknown_key-bin";
@DisplayName("Test Grpc Utility methods")
@Nested
class TestGrpcUtils {
private final Metadata header = new Metadata();
@DisplayName("Test creation of MetaData keys")
@Nested
......@@ -50,9 +52,7 @@ class GrpcUtilTest {
@DisplayName("Test reading values from the grpc header")
@Nested
class TestReadingFromHeader {
private static final String TEST_VALUE = "test-value";
private Metadata header = new Metadata();
private static final String TEST_VALUE = LoremIpsum.getInstance().getWords(1);
@BeforeEach
void initMetadata() {
......@@ -77,10 +77,8 @@ class GrpcUtilTest {
@DisplayName("Test reading multiple values of a key from the grpc header")
@Nested
class TestReadingCollection {
private static final String TEST_VALUE_1 = "test-value-1";
private static final String TEST_VALUE_2 = "test-value-2";
private Metadata header = new Metadata();
private static final String TEST_VALUE_1 = LoremIpsum.getInstance().getWords(1);
private static final String TEST_VALUE_2 = LoremIpsum.getInstance().getWords(2);
@BeforeEach
void initMetadata() {
......@@ -90,17 +88,106 @@ class GrpcUtilTest {
@Test
void shouldReadFromHeader() {
var values = GrpcUtil.getCollection(KEY_VALUE_BIN, header);
var values = GrpcUtil.getList(KEY_VALUE_BIN, header);
assertThat(values).hasSize(2).contains(TEST_VALUE_1, TEST_VALUE_2);
}
@Test
void shouldGetEmptyCollectionOnUnknownKey() {
var values = GrpcUtil.getCollection(UNKNOWN_KEY_BIN, header);
var values = GrpcUtil.getList(UNKNOWN_KEY_BIN, header);
assertThat(values).isEmpty();
}
}
@Nested
class TestGetRequestId {
private static final String REQUEST_ID = UUID.randomUUID().toString();
@Test
void shouldReturnRequestId() {
header.put(GrpcUtil.HEADER_KEY_REQUEST_ID, REQUEST_ID.getBytes());
var result = GrpcUtil.getRequestId(header);
assertThat(result).contains(REQUEST_ID);
}
}
@Nested
class TestGetClientName {
private static final String CLIENT_NAME = LoremIpsum.getInstance().getWords(1);
@Test
void shouldReturnClientName() {
header.put(GrpcUtil.HEADER_KEY_CLIENT_NAME, CLIENT_NAME.getBytes());
var result = GrpcUtil.getClientName(header);
assertThat(result).contains(CLIENT_NAME);
}
}
@Nested
class TestGetUserId {
private static final String USER_ID = LoremIpsum.getInstance().getWords(1);
@Test
void shouldReturnUserId() {
header.put(GrpcUtil.HEADER_KEY_USER_ID, USER_ID.getBytes());
var result = GrpcUtil.getUserId(header);
assertThat(result).contains(USER_ID);
}
}
@Nested
class TestGetUserName {
private static final String USER_NAME = LoremIpsum.getInstance().getWords(1);
@Test
void shouldReturnUserName() {
header.put(GrpcUtil.HEADER_KEY_USER_NAME, USER_NAME.getBytes());
var result = GrpcUtil.getUserName(header);
assertThat(result).contains(USER_NAME);
}
}
@Nested
class TestGetAccessLimitedOrgaId {
private static final String ACCESS_LIMITED_ORGAID = LoremIpsum.getInstance().getWords(1);
@Test
void shouldReturnAccessLimitedOrgaId() {
header.put(GrpcUtil.HEADER_KEY_ACCESS_LIMITED_ORGAID, ACCESS_LIMITED_ORGAID.getBytes());
var result = GrpcUtil.getAccessLimitedOrgaIds(header);
assertThat(result).containsExactly(ACCESS_LIMITED_ORGAID);
}
}
@Nested
class TestGetAccessLimited {
private static final boolean ACCESS_LIMITED = true;
@Test
void shouldReturnAccessLimited() {
header.put(GrpcUtil.HEADER_KEY_ACCESS_LIMITED, String.valueOf(ACCESS_LIMITED).getBytes());
var result = GrpcUtil.getAccessLimited(header);
assertThat(result).contains(ACCESS_LIMITED);
}
}
}
......@@ -393,7 +393,7 @@
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment