Skip to content

Commit ee0bec9

Browse files
kristoffSCKrzysztof Chmielewski
authored andcommitted
ESP-98ESP-98_SinkParameters - add unit tests
Signed-off-by: Krzysztof Chmielewski <krzysztof.chmielewski@getindata.com>
1 parent 727356f commit ee0bec9

File tree

4 files changed

+135
-4
lines changed

4 files changed

+135
-4
lines changed

src/main/java/com/getindata/connectors/http/internal/config/ConfigException.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ public class ConfigException extends RuntimeException {
55

66
private static final long serialVersionUID = 1L;
77

8+
public ConfigException(String message) {
9+
super(message);
10+
}
11+
812
public ConfigException(String message, Throwable t) {
913
super(message, t);
1014
}

src/main/java/com/getindata/connectors/http/internal/sink/httpclient/JavaNetSinkHttpClient.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public JavaNetSinkHttpClient(Properties properties) {
4949
.flatMap(entry -> {
5050
String originalKey = entry.getKey();
5151
// TODO EXP-98 extract this to utils and add tests. Wrap with try/catch in Utils
52-
String newKey = originalKey.substring(originalKey.lastIndexOf(".") + 1);
52+
String newKey = ConfigUtils.extractPropertyLastElement(originalKey);
5353

5454
return Stream.of(newKey, entry.getValue());
5555
}).toArray(String[]::new);

src/main/java/com/getindata/connectors/http/internal/utils/ConfigUtils.java

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,35 @@
66

77
import lombok.AccessLevel;
88
import lombok.NoArgsConstructor;
9+
import org.apache.flink.util.StringUtils;
910

1011
import com.getindata.connectors.http.internal.config.ConfigException;
1112

12-
// TODO EXP-98 add Javadoc and tests
1313
@NoArgsConstructor(access = AccessLevel.NONE)
1414
public final class ConfigUtils {
1515

16+
private static final String PROPERTY_NAME_DELIMITER = ".";
17+
18+
/**
19+
* Convert properties that name starts with given {@code keyPrefix} to Map.
20+
* Values for this property will be cast to {@code valueClazz} type.
21+
*
22+
* @param properties properties to extract keys from.
23+
* @param keyPrefix prefix used to match property name with.
24+
* @param valueClazz type to cast property values to.
25+
* @return Map of propertyName to propertyValue.
26+
*/
1627
public static <T> Map<String, T> propertiesToMap(
1728
Properties properties,
1829
String keyPrefix,
19-
Class<T> clazz) {
30+
Class<T> valueClazz) {
2031

2132
Map<String, T> map = new HashMap<>();
2233
for (Map.Entry<Object, Object> entry : properties.entrySet()) {
2334
if (entry.getKey() instanceof String) {
2435
String key = (String) entry.getKey();
2536
if (key.startsWith(keyPrefix)) {
26-
tryAddToConfigMap(properties, clazz, map, key);
37+
tryAddToConfigMap(properties, valueClazz, map, key);
2738
}
2839
} else {
2940
throw new ConfigException(
@@ -35,6 +46,38 @@ public static <T> Map<String, T> propertiesToMap(
3546
return map;
3647
}
3748

49+
/**
50+
* A utility method to extract last element from property name. This method assumes property to
51+
* be in format as <b>{@code this.is.my.property.name}</b>, using "dot" as a delimiter. For this
52+
* example the returned value would be <b>{@code name}</b>.
53+
*
54+
* @param propertyKay Property name to extract the last element from.
55+
* @return property last element or the property name if {@code propertyKey} parameter had no
56+
* dot delimiter.
57+
* @throws ConfigException when invalid property such as null, empty, blank, ended with dot was
58+
* used.
59+
*/
60+
public static String extractPropertyLastElement(String propertyKay) {
61+
if (StringUtils.isNullOrWhitespaceOnly(propertyKay)) {
62+
throw new ConfigException("Provided a property name that is null, empty or blank.");
63+
}
64+
65+
if (!propertyKay.contains(PROPERTY_NAME_DELIMITER)) {
66+
return propertyKay;
67+
}
68+
69+
int delimiterLastIndex = propertyKay.lastIndexOf(PROPERTY_NAME_DELIMITER);
70+
if (delimiterLastIndex == propertyKay.length() - 1) {
71+
throw new ConfigException(
72+
String.format(
73+
"Invalid property - %s. Property name should not end with property delimiter.",
74+
propertyKay)
75+
);
76+
}
77+
78+
return propertyKay.substring(delimiterLastIndex + 1);
79+
}
80+
3881
private static <T> void tryAddToConfigMap(
3982
Properties properties,
4083
Class<T> clazz, Map<String, T> map,
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package com.getindata.connectors.http.internal.utils;
2+
3+
import java.util.Map;
4+
import java.util.Properties;
5+
6+
import org.junit.jupiter.api.Test;
7+
import org.junit.jupiter.params.ParameterizedTest;
8+
import org.junit.jupiter.params.provider.ValueSource;
9+
import static org.assertj.core.api.Assertions.assertThat;
10+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
11+
12+
import com.getindata.connectors.http.internal.config.ConfigException;
13+
14+
class ConfigUtilsTest {
15+
16+
@Test
17+
public void shouldExtractPropertiesToMap() {
18+
Properties properties = new Properties();
19+
properties.setProperty("property", "val1");
20+
properties.setProperty("my.property", "val2");
21+
properties.setProperty("my.super.property", "val3");
22+
properties.setProperty("my.property.detail", "val4");
23+
properties.setProperty("my.property.extra", "val5");
24+
properties.setProperty("another.my.property.extra", "val6");
25+
26+
Map<String, String> mappedProperties =
27+
ConfigUtils.propertiesToMap(properties, "my.property", String.class);
28+
29+
assertThat(mappedProperties).hasSize(3);
30+
assertThat(mappedProperties)
31+
.containsExactlyEntriesOf(
32+
Map.of(
33+
"my.property", "val2",
34+
"my.property.detail", "val4",
35+
"my.property.extra", "val5"
36+
));
37+
}
38+
39+
@Test
40+
public void shouldConvertNoProperty() {
41+
Properties properties = new Properties();
42+
properties.setProperty("property", "val1");
43+
properties.setProperty("my.property", "val2");
44+
properties.setProperty("my.super.property", "val3");
45+
46+
Map<String, String> mappedProperties =
47+
ConfigUtils.propertiesToMap(properties, "my.custom", String.class);
48+
assertThat(mappedProperties).isEmpty();
49+
}
50+
51+
@Test
52+
public void shouldHandleInvalidPropertyType() {
53+
54+
Properties properties = new Properties();
55+
properties.put("a.property", 1);
56+
57+
// Should ignore "invalid" property since does not match the prefix
58+
Map<String, String> mappedProperties =
59+
ConfigUtils.propertiesToMap(properties, "my.custom", String.class);
60+
assertThat(mappedProperties).isEmpty();
61+
62+
// should throw on invalid value, when name matches the prefix.
63+
assertThatThrownBy(
64+
() -> ConfigUtils.propertiesToMap(properties, "a.property", String.class))
65+
.isInstanceOf(ConfigException.class);
66+
}
67+
68+
@ParameterizedTest(name = "Property full name - {0}")
69+
@ValueSource(strings = {"property", "my.property", "my.super.property", ".my.super.property"})
70+
public void shouldGetPropertyName(String fullPropertyName) {
71+
72+
String propertyLastElement = ConfigUtils.extractPropertyLastElement(fullPropertyName);
73+
assertThat(propertyLastElement).isEqualTo("property");
74+
}
75+
76+
@ParameterizedTest(name = "Property full name - {0}")
77+
@ValueSource(strings = {"", " ", "my.super.property.", ".", "..."})
78+
public void shouldThrowOnInvalidProperty(String invalidProperty) {
79+
80+
assertThatThrownBy(
81+
() -> ConfigUtils.extractPropertyLastElement(invalidProperty))
82+
.isInstanceOf(ConfigException.class);
83+
}
84+
}

0 commit comments

Comments
 (0)